From d40109929c570f74bbfc9e6c8c9baf31086905e6 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 28 Oct 2017 13:40:06 +0200 Subject: [PATCH] Fix describeHashAlgos tool task - Handle case when Argon2 library is not loaded - Account for hash algorithms with `null` as associated impl. class --- docs/hash_algorithms.md | 4 +-- .../EncryptionMethodInfoGatherer.java | 35 +++++++++++++++---- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/docs/hash_algorithms.md b/docs/hash_algorithms.md index 00480c80a..a2eb41e05 100644 --- a/docs/hash_algorithms.md +++ b/docs/hash_algorithms.md @@ -1,5 +1,5 @@ - + ## Hash Algorithms AuthMe supports the following hash algorithms for storing your passwords safely. @@ -79,4 +79,4 @@ or bad. --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Thu Oct 19 21:41:21 CEST 2017 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sat Oct 28 13:29:59 CEST 2017 diff --git a/src/test/java/tools/docs/hashmethods/EncryptionMethodInfoGatherer.java b/src/test/java/tools/docs/hashmethods/EncryptionMethodInfoGatherer.java index 50b4f50d0..86f808386 100644 --- a/src/test/java/tools/docs/hashmethods/EncryptionMethodInfoGatherer.java +++ b/src/test/java/tools/docs/hashmethods/EncryptionMethodInfoGatherer.java @@ -3,8 +3,10 @@ package tools.docs.hashmethods; import ch.jalu.injector.Injector; import ch.jalu.injector.InjectorBuilder; import com.google.common.collect.ImmutableSet; +import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.TestHelper; import fr.xephi.authme.security.HashAlgorithm; +import fr.xephi.authme.security.crypts.Argon2; import fr.xephi.authme.security.crypts.EncryptionMethod; import fr.xephi.authme.security.crypts.HexSaltedMethod; import fr.xephi.authme.security.crypts.description.AsciiRestricted; @@ -13,10 +15,12 @@ import fr.xephi.authme.security.crypts.description.Recommendation; import fr.xephi.authme.settings.Settings; import java.lang.annotation.Annotation; +import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; +import java.util.logging.Logger; import static org.mockito.Mockito.mock; @@ -34,6 +38,7 @@ public class EncryptionMethodInfoGatherer { private Map descriptions; public EncryptionMethodInfoGatherer() { + ConsoleLogger.setLogger(Logger.getAnonymousLogger()); // set logger because of Argon2.isLibraryLoaded() descriptions = new LinkedHashMap<>(); constructDescriptions(); } @@ -44,7 +49,7 @@ public class EncryptionMethodInfoGatherer { private void constructDescriptions() { for (HashAlgorithm algorithm : HashAlgorithm.values()) { - if (!HashAlgorithm.CUSTOM.equals(algorithm) && !algorithm.getClazz().isAnnotationPresent(Deprecated.class)) { + if (algorithm.getClazz() != null && !algorithm.getClazz().isAnnotationPresent(Deprecated.class)) { MethodDescription description = createDescription(algorithm); descriptions.put(algorithm, description); } @@ -53,10 +58,7 @@ public class EncryptionMethodInfoGatherer { private static MethodDescription createDescription(HashAlgorithm algorithm) { Class clazz = algorithm.getClazz(); - EncryptionMethod method = injector.createIfHasDependencies(clazz); - if (method == null) { - throw new NullPointerException("Method for '" + algorithm + "' is null"); - } + EncryptionMethod method = createEncryptionMethod(clazz); MethodDescription description = new MethodDescription(clazz); description.setHashLength(method.computeHash("test", "user").getHash().length()); description.setHasSeparateSalt(method.hasSeparateSalt()); @@ -74,6 +76,19 @@ public class EncryptionMethodInfoGatherer { return description; } + private static EncryptionMethod createEncryptionMethod(Class clazz) { + if (clazz == Argon2.class && !Argon2.isLibraryLoaded()) { + // The library for Argon2 isn't installed, so override the hash implementation to avoid using the library + return new Argon2DummyExtension(); + } + + EncryptionMethod method = injector.createIfHasDependencies(clazz); + if (method == null) { + throw new NullPointerException("Failed to instantiate '" + clazz + "'. Is a dependency missing?"); + } + return method; + } + private static Map, Annotation> gatherAnnotations(Class methodClass) { // Note ljacqu 20151231: The map could be Map, Annotation> and it has the constraint // that for a key Class, the value is of type T. We write a simple "Class" for brevity. @@ -140,11 +155,17 @@ public class EncryptionMethodInfoGatherer { Settings settings = mock(Settings.class); TestHelper.returnDefaultsForAllProperties(settings); - // By passing some bogus "package" to the constructor, the injector will throw if it needs to - // instantiate any dependency other than what we provide. + // Limit instantiation to the crypts package only so any dependencies need to be passed explicitly Injector injector = new InjectorBuilder().addDefaultHandlers("fr.xephi.authme.security.crypts").create(); injector.register(Settings.class, settings); return injector; } + private static final class Argon2DummyExtension extends Argon2 { + @Override + public String computeHash(String password) { + // Argon2 produces hashes of 96 characters -> return dummy value with this length + return String.join("", Collections.nCopies(96, ".")); + } + } }