You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2021/03/11 05:05:22 UTC

[james-project] 05/15: JAMES-3512 Strong typing for algorithm

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 319d143d06efce462150bcc1030393e163454034
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Mar 5 10:59:42 2021 +0700

    JAMES-3512 Strong typing for algorithm
---
 .../james/user/cassandra/CassandraUsersDAO.java    | 10 ++--
 .../org/apache/james/user/lib/model/Algorithm.java | 57 ++++++++++++++++++++++
 .../apache/james/user/lib/model/DefaultUser.java   |  8 +--
 .../org/apache/james/user/lib/util/DigestUtil.java |  7 +--
 .../james/user/lib/UsersRepositoryContract.java    |  5 +-
 .../apache/james/user/lib/model/AlgorithmTest.java | 31 ++++++++++++
 .../apache/james/user/memory/MemoryUsersDAO.java   |  7 +--
 7 files changed, 109 insertions(+), 16 deletions(-)

diff --git a/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersDAO.java b/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersDAO.java
index 25689c2..ae459ba 100644
--- a/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersDAO.java
+++ b/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersDAO.java
@@ -43,6 +43,7 @@ import org.apache.james.user.api.AlreadyExistInUsersRepositoryException;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.user.api.model.User;
 import org.apache.james.user.lib.UsersDAO;
+import org.apache.james.user.lib.model.Algorithm;
 import org.apache.james.user.lib.model.DefaultUser;
 
 import com.datastax.driver.core.PreparedStatement;
@@ -51,7 +52,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.primitives.Ints;
 
 public class CassandraUsersDAO implements UsersDAO {
-    private static final String DEFAULT_ALGO_VALUE = "SHA-512";
+    private static final Algorithm DEFAULT_ALGO_VALUE = Algorithm.of("SHA-512");
 
     private final CassandraAsyncExecutor executor;
     private final PreparedStatement getUserStatement;
@@ -113,7 +114,8 @@ public class CassandraUsersDAO implements UsersDAO {
         return executor.executeSingleRow(
                 getUserStatement.bind()
                     .setString(NAME, name.asString()))
-            .map(row -> new DefaultUser(Username.of(row.getString(NAME)), row.getString(PASSWORD), row.getString(ALGORITHM)))
+            .map(row -> new DefaultUser(Username.of(row.getString(NAME)), row.getString(PASSWORD),
+                Algorithm.of(row.getString(ALGORITHM))))
             .blockOptional();
     }
 
@@ -125,7 +127,7 @@ public class CassandraUsersDAO implements UsersDAO {
                 updateUserStatement.bind()
                     .setString(REALNAME, defaultUser.getUserName().asString())
                     .setString(PASSWORD, defaultUser.getHashedPassword())
-                    .setString(ALGORITHM, defaultUser.getHashAlgorithm())
+                    .setString(ALGORITHM, defaultUser.getHashAlgorithm().rawValue())
                     .setString(NAME, defaultUser.getUserName().asString()))
             .block();
 
@@ -176,7 +178,7 @@ public class CassandraUsersDAO implements UsersDAO {
                 .setString(NAME, user.getUserName().asString())
                 .setString(REALNAME, user.getUserName().asString())
                 .setString(PASSWORD, user.getHashedPassword())
-                .setString(ALGORITHM, user.getHashAlgorithm()))
+                .setString(ALGORITHM, user.getHashAlgorithm().rawValue()))
             .block();
 
         if (!executed) {
diff --git a/server/data/data-library/src/main/java/org/apache/james/user/lib/model/Algorithm.java b/server/data/data-library/src/main/java/org/apache/james/user/lib/model/Algorithm.java
new file mode 100644
index 0000000..ca8ff46
--- /dev/null
+++ b/server/data/data-library/src/main/java/org/apache/james/user/lib/model/Algorithm.java
@@ -0,0 +1,57 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.user.lib.model;
+
+import java.util.Objects;
+
+public class Algorithm {
+    public static Algorithm of(String rawValue) {
+        return new Algorithm(rawValue);
+    }
+
+    private final String rawValue;
+
+    public Algorithm(String rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    public String algorithmName() {
+        return rawValue;
+    }
+
+    public String rawValue() {
+        return rawValue;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof Algorithm) {
+            Algorithm that = (Algorithm) o;
+
+            return Objects.equals(this.rawValue, that.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(rawValue);
+    }
+}
diff --git a/server/data/data-library/src/main/java/org/apache/james/user/lib/model/DefaultUser.java b/server/data/data-library/src/main/java/org/apache/james/user/lib/model/DefaultUser.java
index fd22baa..187cb1a 100644
--- a/server/data/data-library/src/main/java/org/apache/james/user/lib/model/DefaultUser.java
+++ b/server/data/data-library/src/main/java/org/apache/james/user/lib/model/DefaultUser.java
@@ -36,7 +36,7 @@ public class DefaultUser implements User, Serializable {
 
     private final Username userName;
     private String hashedPassword;
-    private final String algorithm;
+    private final Algorithm algorithm;
 
     /**
      * Standard constructor.
@@ -46,7 +46,7 @@ public class DefaultUser implements User, Serializable {
      * @param hashAlg
      *            the algorithm used to generate the hash of the password
      */
-    public DefaultUser(Username name, String hashAlg) {
+    public DefaultUser(Username name, Algorithm hashAlg) {
         userName = name;
         algorithm = hashAlg;
     }
@@ -62,7 +62,7 @@ public class DefaultUser implements User, Serializable {
      * @param hashAlg
      *            the String algorithm used to generate the hash of the password
      */
-    public DefaultUser(Username name, String passwordHash, String hashAlg) {
+    public DefaultUser(Username name, String passwordHash, Algorithm hashAlg) {
         userName = name;
         hashedPassword = passwordHash;
         algorithm = hashAlg;
@@ -107,7 +107,7 @@ public class DefaultUser implements User, Serializable {
      * 
      * @return the name of the hashing algorithm used for this user's password
      */
-    public String getHashAlgorithm() {
+    public Algorithm getHashAlgorithm() {
         return algorithm;
     }
 }
diff --git a/server/data/data-library/src/main/java/org/apache/james/user/lib/util/DigestUtil.java b/server/data/data-library/src/main/java/org/apache/james/user/lib/util/DigestUtil.java
index d4e5c72..f0be987 100644
--- a/server/data/data-library/src/main/java/org/apache/james/user/lib/util/DigestUtil.java
+++ b/server/data/data-library/src/main/java/org/apache/james/user/lib/util/DigestUtil.java
@@ -31,6 +31,7 @@ import java.util.Locale;
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeUtility;
 
+import org.apache.james.user.lib.model.Algorithm;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -74,7 +75,7 @@ public class DigestUtil {
             digestFile(args[args.length - 1], alg);
         } else {
             try {
-                String hash = digestString(args[args.length - 1], alg);
+                String hash = digestString(args[args.length - 1], Algorithm.of(alg));
                 System.out.println("Hash is: " + hash);
             } catch (NoSuchAlgorithmException nsae) {
                 System.out.println("No such algorithm available");
@@ -132,13 +133,13 @@ public class DigestUtil {
      * @throws NoSuchAlgorithmException
      *             if the algorithm passed in cannot be found
      */
-    public static String digestString(String pass, String algorithm) throws NoSuchAlgorithmException {
+    public static String digestString(String pass, Algorithm algorithm) throws NoSuchAlgorithmException {
 
         MessageDigest md;
         ByteArrayOutputStream bos;
 
         try {
-            md = MessageDigest.getInstance(algorithm);
+            md = MessageDigest.getInstance(algorithm.algorithmName());
             byte[] digest = md.digest(pass.getBytes("iso-8859-1"));
             bos = new ByteArrayOutputStream();
             OutputStream encodedStream = MimeUtility.encode(bos, "base64");
diff --git a/server/data/data-library/src/test/java/org/apache/james/user/lib/UsersRepositoryContract.java b/server/data/data-library/src/test/java/org/apache/james/user/lib/UsersRepositoryContract.java
index 1059431..3ce0342 100644
--- a/server/data/data-library/src/test/java/org/apache/james/user/lib/UsersRepositoryContract.java
+++ b/server/data/data-library/src/test/java/org/apache/james/user/lib/UsersRepositoryContract.java
@@ -36,6 +36,7 @@ import org.apache.james.user.api.AlreadyExistInUsersRepositoryException;
 import org.apache.james.user.api.InvalidUsernameException;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.user.api.model.User;
+import org.apache.james.user.lib.model.Algorithm;
 import org.apache.james.user.lib.model.DefaultUser;
 import org.junit.jupiter.api.Assumptions;
 import org.junit.jupiter.api.Test;
@@ -565,14 +566,14 @@ public interface UsersRepositoryContract {
 
         @Test
         default void updateUserShouldThrowWhenUserDoesNotBelongToDomainList(TestSystem testSystem) {
-            assertThatThrownBy(() -> testee().updateUser(new DefaultUser(testSystem.userWithUnknowDomain, "hasAlg")))
+            assertThatThrownBy(() -> testee().updateUser(new DefaultUser(testSystem.userWithUnknowDomain, Algorithm.of("hasAlg"))))
                 .isInstanceOf(InvalidUsernameException.class)
                 .hasMessage("Domain does not exist in DomainList");
         }
 
         @Test
         default void updateUserShouldNotThrowInvalidUsernameExceptionWhenInvalidUser(TestSystem testSystem) {
-            assertThatThrownBy(() -> testee().updateUser(new DefaultUser(testSystem.invalidUsername, "hasAlg")))
+            assertThatThrownBy(() -> testee().updateUser(new DefaultUser(testSystem.invalidUsername, Algorithm.of("hasAlg"))))
                 .isNotInstanceOf(InvalidUsernameException.class);
         }
 
diff --git a/server/data/data-library/src/test/java/org/apache/james/user/lib/model/AlgorithmTest.java b/server/data/data-library/src/test/java/org/apache/james/user/lib/model/AlgorithmTest.java
new file mode 100644
index 0000000..d2ab539
--- /dev/null
+++ b/server/data/data-library/src/test/java/org/apache/james/user/lib/model/AlgorithmTest.java
@@ -0,0 +1,31 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.user.lib.model;
+
+import org.junit.jupiter.api.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class AlgorithmTest {
+    @Test
+    void shouldMatchBeanContract() {
+        EqualsVerifier.forClass(Algorithm.class).verify();
+    }
+}
\ No newline at end of file
diff --git a/server/data/data-memory/src/main/java/org/apache/james/user/memory/MemoryUsersDAO.java b/server/data/data-memory/src/main/java/org/apache/james/user/memory/MemoryUsersDAO.java
index 33e07d2..e07c8b4 100644
--- a/server/data/data-memory/src/main/java/org/apache/james/user/memory/MemoryUsersDAO.java
+++ b/server/data/data-memory/src/main/java/org/apache/james/user/memory/MemoryUsersDAO.java
@@ -31,20 +31,21 @@ import org.apache.james.lifecycle.api.Configurable;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.user.api.model.User;
 import org.apache.james.user.lib.UsersDAO;
+import org.apache.james.user.lib.model.Algorithm;
 import org.apache.james.user.lib.model.DefaultUser;
 
 public class MemoryUsersDAO implements UsersDAO, Configurable {
     private final Map<String, User> userByName;
-    private String algo;
+    private Algorithm algo;
 
     MemoryUsersDAO() {
         this.userByName = new HashMap<>();
-        this.algo = "SHA-512";
+        this.algo = Algorithm.of("SHA-512");
     }
 
     @Override
     public void configure(HierarchicalConfiguration<ImmutableNode> config) {
-        algo = config.getString("algorithm", "SHA-512");
+        algo = Algorithm.of(config.getString("algorithm", "SHA-512"));
     }
 
     public void clear() {


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org