110 lines
4.8 KiB
Java
110 lines
4.8 KiB
Java
package fr.xephi.authme.security;
|
|
|
|
import ch.jalu.injector.Injector;
|
|
import ch.jalu.injector.InjectorBuilder;
|
|
import fr.xephi.authme.TestHelper;
|
|
import fr.xephi.authme.security.crypts.Argon2;
|
|
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
|
import fr.xephi.authme.security.crypts.HashedPassword;
|
|
import fr.xephi.authme.security.crypts.description.Recommendation;
|
|
import fr.xephi.authme.security.crypts.description.Usage;
|
|
import fr.xephi.authme.settings.Settings;
|
|
import fr.xephi.authme.settings.properties.HooksSettings;
|
|
import fr.xephi.authme.settings.properties.SecuritySettings;
|
|
import fr.xephi.authme.util.StringUtils;
|
|
import org.junit.BeforeClass;
|
|
import org.junit.Test;
|
|
|
|
import java.util.HashSet;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
|
|
import static org.hamcrest.Matchers.equalTo;
|
|
import static org.hamcrest.MatcherAssert.assertThat;
|
|
import static org.junit.Assert.fail;
|
|
import static org.mockito.BDDMockito.given;
|
|
import static org.mockito.Mockito.mock;
|
|
|
|
/**
|
|
* Integration test for {@link HashAlgorithm}.
|
|
*/
|
|
public class HashAlgorithmIntegrationTest {
|
|
|
|
private static Injector injector;
|
|
|
|
@BeforeClass
|
|
public static void setUpConfigAndInjector() {
|
|
Settings settings = mock(Settings.class);
|
|
given(settings.getProperty(HooksSettings.BCRYPT_LOG2_ROUND)).willReturn(8);
|
|
given(settings.getProperty(SecuritySettings.DOUBLE_MD5_SALT_LENGTH)).willReturn(16);
|
|
given(settings.getProperty(SecuritySettings.PBKDF2_NUMBER_OF_ROUNDS)).willReturn(10_000);
|
|
injector = new InjectorBuilder().addDefaultHandlers("fr.xephi.authme").create();
|
|
injector.register(Settings.class, settings);
|
|
TestHelper.setupLogger();
|
|
}
|
|
|
|
@Test
|
|
public void shouldHaveUniqueClassForEntries() {
|
|
// given
|
|
Set<Class<? extends EncryptionMethod>> classes = new HashSet<>();
|
|
|
|
// when / then
|
|
for (HashAlgorithm algorithm : HashAlgorithm.values()) {
|
|
if (!HashAlgorithm.CUSTOM.equals(algorithm)) {
|
|
if (!classes.add(algorithm.getClazz())) {
|
|
fail("Found class '" + algorithm.getClazz() + "' twice!");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void shouldBeAbleToInstantiateEncryptionAlgorithms() {
|
|
// given / when / then
|
|
for (HashAlgorithm algorithm : HashAlgorithm.values()) {
|
|
if (!HashAlgorithm.CUSTOM.equals(algorithm) && !HashAlgorithm.PLAINTEXT.equals(algorithm)) {
|
|
if (HashAlgorithm.ARGON2.equals(algorithm) && !Argon2.isLibraryLoaded()) {
|
|
System.out.println("[WARNING] Cannot find argon2 library, skipping integration test");
|
|
continue;
|
|
}
|
|
EncryptionMethod method = injector.createIfHasDependencies(algorithm.getClazz());
|
|
if (method == null) {
|
|
fail("Could not create '" + algorithm.getClazz() + "' - forgot to provide some class?");
|
|
}
|
|
HashedPassword hashedPassword = method.computeHash("pwd", "name");
|
|
assertThat("Salt should not be null if method.hasSeparateSalt(), and vice versa. Method: '"
|
|
+ method + "'", StringUtils.isEmpty(hashedPassword.getSalt()), equalTo(!method.hasSeparateSalt()));
|
|
assertThat("Hash should not be empty for method '" + method + "'",
|
|
StringUtils.isEmpty(hashedPassword.getHash()), equalTo(false));
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void shouldBeDeprecatedIfEncryptionClassIsDeprecated() throws NoSuchFieldException {
|
|
// given
|
|
List<String> failedEntries = new LinkedList<>();
|
|
|
|
// when
|
|
for (HashAlgorithm hashAlgorithm : HashAlgorithm.values()) {
|
|
if (hashAlgorithm != HashAlgorithm.CUSTOM && hashAlgorithm != HashAlgorithm.PLAINTEXT) {
|
|
boolean isEnumDeprecated = HashAlgorithm.class.getDeclaredField(hashAlgorithm.name())
|
|
.isAnnotationPresent(Deprecated.class);
|
|
boolean isDeprecatedClass = hashAlgorithm.getClazz().isAnnotationPresent(Deprecated.class);
|
|
Recommendation recommendation = hashAlgorithm.getClazz().getAnnotation(Recommendation.class);
|
|
boolean hasDeprecatedUsage = recommendation != null && recommendation.value() == Usage.DEPRECATED;
|
|
if (isEnumDeprecated != isDeprecatedClass || isEnumDeprecated != hasDeprecatedUsage) {
|
|
failedEntries.add(hashAlgorithm + ": enum @Deprecated = " + isEnumDeprecated
|
|
+ ", @Deprecated class = " + isDeprecatedClass + ", usage Deprecated = " + hasDeprecatedUsage);
|
|
}
|
|
}
|
|
}
|
|
|
|
// then
|
|
if (!failedEntries.isEmpty()) {
|
|
fail("Found inconsistencies:\n" + String.join("\n", failedEntries));
|
|
}
|
|
}
|
|
}
|