From fca77b940f4204d2107ddba522a4e3952fcc80f2 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Thu, 19 Oct 2017 21:30:19 +0200 Subject: [PATCH] #1016 Deprecate MD5, SHA1, SHA512: no longer allowed for active use - Deprecate unsalted hashes: if such a hash is configured, move it to the legacy hashes setting to still support the existing hashes in the database but hash all passwords from now on with our default, SHA256. --- src/main/java/fr/xephi/authme/AuthMe.java | 8 -- .../authme/initialization/OnStartupTasks.java | 22 ----- .../xephi/authme/security/HashAlgorithm.java | 16 ++-- .../authme/security/crypts/DoubleMd5.java | 1 + .../fr/xephi/authme/security/crypts/Md5.java | 1 + .../fr/xephi/authme/security/crypts/Sha1.java | 1 + .../xephi/authme/security/crypts/Sha512.java | 1 + .../authme/security/crypts/Whirlpool.java | 1 + .../authme/settings/EnumSetProperty.java | 8 +- .../settings/SettingsMigrationService.java | 29 +++++++ .../settings/properties/SecuritySettings.java | 2 +- .../initialization/OnStartupTasksTest.java | 27 ------ .../SettingsMigrationServiceTest.java | 86 +++++++++++++++---- .../fr/xephi/authme/settings/config-old.yml | 5 +- 14 files changed, 121 insertions(+), 87 deletions(-) delete mode 100644 src/test/java/fr/xephi/authme/initialization/OnStartupTasksTest.java diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 6ce2d103e..728b469b8 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -23,7 +23,6 @@ import fr.xephi.authme.listener.PlayerListener18; import fr.xephi.authme.listener.PlayerListener19; import fr.xephi.authme.listener.PlayerListener19Spigot; import fr.xephi.authme.listener.ServerListener; -import fr.xephi.authme.security.HashAlgorithm; import fr.xephi.authme.security.crypts.Sha256; import fr.xephi.authme.service.BackupService; import fr.xephi.authme.service.BukkitService; @@ -268,13 +267,6 @@ public class AuthMe extends JavaPlugin { && settings.getProperty(EmailSettings.SMTP_PORT) != 25) { ConsoleLogger.warning("Note: You have set Email.useTls to false but this only affects mail over port 25"); } - - // Unsalted hashes will be deprecated in 5.4 (see Github issue #1016) - HashAlgorithm hash = settings.getProperty(SecuritySettings.PASSWORD_HASH); - if (OnStartupTasks.isHashDeprecatedIn54(hash)) { - ConsoleLogger.warning("You are using an unsalted hash (" + hash + "). Support for this will be removed " - + "in 5.4 -- do you still need it? Comment on https://github.com/AuthMe/AuthMeReloaded/issues/1016"); - } } /** diff --git a/src/main/java/fr/xephi/authme/initialization/OnStartupTasks.java b/src/main/java/fr/xephi/authme/initialization/OnStartupTasks.java index e9ae353b4..77d18264a 100644 --- a/src/main/java/fr/xephi/authme/initialization/OnStartupTasks.java +++ b/src/main/java/fr/xephi/authme/initialization/OnStartupTasks.java @@ -7,9 +7,6 @@ import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.Messages; import fr.xephi.authme.output.ConsoleFilter; import fr.xephi.authme.output.Log4JFilter; -import fr.xephi.authme.security.HashAlgorithm; -import fr.xephi.authme.security.crypts.description.Recommendation; -import fr.xephi.authme.security.crypts.description.Usage; import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.DatabaseSettings; @@ -103,23 +100,4 @@ public class OnStartupTasks { } }, 1, TICKS_PER_MINUTE * settings.getProperty(EmailSettings.DELAY_RECALL)); } - - /** - * Returns whether the hash algorithm is deprecated and won't be able - * to be actively used anymore in 5.4. - * - * @param hash the hash algorithm to check - * @return true if the hash will be deprecated, false otherwise - * @see #1016 - */ - public static boolean isHashDeprecatedIn54(HashAlgorithm hash) { - if (hash.getClazz() == null || hash == HashAlgorithm.PLAINTEXT) { - // Exclude PLAINTEXT from this check because it already has a mandatory migration, which takes care of - // sending all the necessary messages and warnings. - return false; - } - - Recommendation recommendation = hash.getClazz().getAnnotation(Recommendation.class); - return recommendation != null && recommendation.value() == Usage.DEPRECATED; - } } diff --git a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java index f12da678d..5ce3e92a5 100644 --- a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java +++ b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java @@ -10,34 +10,34 @@ public enum HashAlgorithm { BCRYPT(fr.xephi.authme.security.crypts.BCrypt.class), BCRYPT2Y(fr.xephi.authme.security.crypts.BCrypt2y.class), CRAZYCRYPT1(fr.xephi.authme.security.crypts.CrazyCrypt1.class), - DOUBLEMD5(fr.xephi.authme.security.crypts.DoubleMd5.class), IPB3(fr.xephi.authme.security.crypts.Ipb3.class), IPB4(fr.xephi.authme.security.crypts.Ipb4.class), JOOMLA(fr.xephi.authme.security.crypts.Joomla.class), - MD5(fr.xephi.authme.security.crypts.Md5.class), MD5VB(fr.xephi.authme.security.crypts.Md5vB.class), MYBB(fr.xephi.authme.security.crypts.MyBB.class), PBKDF2(fr.xephi.authme.security.crypts.Pbkdf2.class), PBKDF2DJANGO(fr.xephi.authme.security.crypts.Pbkdf2Django.class), PHPBB(fr.xephi.authme.security.crypts.PhpBB.class), PHPFUSION(fr.xephi.authme.security.crypts.PhpFusion.class), - @Deprecated - PLAINTEXT(fr.xephi.authme.security.crypts.PlainText.class), ROYALAUTH(fr.xephi.authme.security.crypts.RoyalAuth.class), SALTED2MD5(fr.xephi.authme.security.crypts.Salted2Md5.class), SALTEDSHA512(fr.xephi.authme.security.crypts.SaltedSha512.class), - SHA1(fr.xephi.authme.security.crypts.Sha1.class), SHA256(fr.xephi.authme.security.crypts.Sha256.class), - SHA512(fr.xephi.authme.security.crypts.Sha512.class), SMF(fr.xephi.authme.security.crypts.Smf.class), TWO_FACTOR(fr.xephi.authme.security.crypts.TwoFactor.class), WBB3(fr.xephi.authme.security.crypts.Wbb3.class), WBB4(fr.xephi.authme.security.crypts.Wbb4.class), - WHIRLPOOL(fr.xephi.authme.security.crypts.Whirlpool.class), WORDPRESS(fr.xephi.authme.security.crypts.Wordpress.class), XAUTH(fr.xephi.authme.security.crypts.XAuth.class), XFBCRYPT(fr.xephi.authme.security.crypts.XfBCrypt.class), - CUSTOM(null); + CUSTOM(null), + + @Deprecated DOUBLEMD5(fr.xephi.authme.security.crypts.DoubleMd5.class), + @Deprecated MD5(fr.xephi.authme.security.crypts.Md5.class), + @Deprecated PLAINTEXT(fr.xephi.authme.security.crypts.PlainText.class), + @Deprecated SHA1(fr.xephi.authme.security.crypts.Sha1.class), + @Deprecated SHA512(fr.xephi.authme.security.crypts.Sha512.class), + @Deprecated WHIRLPOOL(fr.xephi.authme.security.crypts.Whirlpool.class); private final Class clazz; diff --git a/src/main/java/fr/xephi/authme/security/crypts/DoubleMd5.java b/src/main/java/fr/xephi/authme/security/crypts/DoubleMd5.java index 54158419b..12e968082 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/DoubleMd5.java +++ b/src/main/java/fr/xephi/authme/security/crypts/DoubleMd5.java @@ -5,6 +5,7 @@ import fr.xephi.authme.security.crypts.description.Usage; import static fr.xephi.authme.security.HashUtils.md5; +@Deprecated @Recommendation(Usage.DEPRECATED) public class DoubleMd5 extends UnsaltedMethod { diff --git a/src/main/java/fr/xephi/authme/security/crypts/Md5.java b/src/main/java/fr/xephi/authme/security/crypts/Md5.java index a5f6d91d2..55e07a173 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/Md5.java +++ b/src/main/java/fr/xephi/authme/security/crypts/Md5.java @@ -4,6 +4,7 @@ import fr.xephi.authme.security.HashUtils; import fr.xephi.authme.security.crypts.description.Recommendation; import fr.xephi.authme.security.crypts.description.Usage; +@Deprecated @Recommendation(Usage.DEPRECATED) public class Md5 extends UnsaltedMethod { diff --git a/src/main/java/fr/xephi/authme/security/crypts/Sha1.java b/src/main/java/fr/xephi/authme/security/crypts/Sha1.java index 3430752b5..6d095b4a2 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/Sha1.java +++ b/src/main/java/fr/xephi/authme/security/crypts/Sha1.java @@ -4,6 +4,7 @@ import fr.xephi.authme.security.HashUtils; import fr.xephi.authme.security.crypts.description.Recommendation; import fr.xephi.authme.security.crypts.description.Usage; +@Deprecated @Recommendation(Usage.DEPRECATED) public class Sha1 extends UnsaltedMethod { diff --git a/src/main/java/fr/xephi/authme/security/crypts/Sha512.java b/src/main/java/fr/xephi/authme/security/crypts/Sha512.java index 4e9682ffe..36dc5a342 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/Sha512.java +++ b/src/main/java/fr/xephi/authme/security/crypts/Sha512.java @@ -4,6 +4,7 @@ import fr.xephi.authme.security.HashUtils; import fr.xephi.authme.security.crypts.description.Recommendation; import fr.xephi.authme.security.crypts.description.Usage; +@Deprecated @Recommendation(Usage.DEPRECATED) public class Sha512 extends UnsaltedMethod { diff --git a/src/main/java/fr/xephi/authme/security/crypts/Whirlpool.java b/src/main/java/fr/xephi/authme/security/crypts/Whirlpool.java index c1ea747a9..7c62b2619 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/Whirlpool.java +++ b/src/main/java/fr/xephi/authme/security/crypts/Whirlpool.java @@ -64,6 +64,7 @@ import fr.xephi.authme.security.crypts.description.Usage; import java.util.Arrays; +@Deprecated @Recommendation(Usage.DEPRECATED) public class Whirlpool extends UnsaltedMethod { diff --git a/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java b/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java index 901c9fc1e..b18944aac 100644 --- a/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java +++ b/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java @@ -3,8 +3,8 @@ package fr.xephi.authme.settings; import ch.jalu.configme.properties.Property; import ch.jalu.configme.resource.PropertyResource; +import java.util.Collection; import java.util.LinkedHashSet; -import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -27,9 +27,9 @@ public class EnumSetProperty> extends Property> { @Override protected Set getFromResource(PropertyResource resource) { - List elements = resource.getList(getPath()); - if (elements != null) { - return elements.stream() + Object entry = resource.getObject(getPath()); + if (entry instanceof Collection) { + return ((Collection) entry).stream() .map(val -> toEnum(String.valueOf(val))) .filter(e -> e != null) .collect(Collectors.toCollection(LinkedHashSet::new)); diff --git a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java index c2dd46558..8d25e4c3b 100644 --- a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java +++ b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java @@ -10,6 +10,8 @@ import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.output.LogLevel; import fr.xephi.authme.process.register.RegisterSecondaryArgument; import fr.xephi.authme.process.register.RegistrationType; +import fr.xephi.authme.security.HashAlgorithm; +import fr.xephi.authme.security.crypts.EncryptionMethod; import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.SecuritySettings; @@ -20,6 +22,7 @@ import java.io.FileWriter; import java.io.IOException; import java.util.Collections; import java.util.List; +import java.util.Set; import static ch.jalu.configme.properties.PropertyInitializer.newListProperty; import static ch.jalu.configme.properties.PropertyInitializer.newProperty; @@ -73,6 +76,7 @@ public class SettingsMigrationService extends PlainMigrationService { | hasSupportOldPasswordProperty(resource) | convertToRegistrationType(resource) | mergeAndMovePermissionGroupSettings(resource) + | moveDeprecatedHashAlgorithmIntoLegacySection(resource) || hasDeprecatedProperties(resource); } @@ -286,6 +290,31 @@ public class SettingsMigrationService extends PlainMigrationService { return performedChanges; } + /** + * If a deprecated hash is used, it is added to the legacy hashes option and the active hash + * is changed to SHA256. + * + * @param resource The property resource + * @return True if the configuration has changed, false otherwise + */ + private static boolean moveDeprecatedHashAlgorithmIntoLegacySection(PropertyResource resource) { + HashAlgorithm currentHash = SecuritySettings.PASSWORD_HASH.getValue(resource); + // Skip CUSTOM (has no class) and PLAINTEXT (is force-migrated later on in the startup process) + if (currentHash != HashAlgorithm.CUSTOM && currentHash != HashAlgorithm.PLAINTEXT) { + Class clazz = currentHash.getClazz(); + if (clazz.isAnnotationPresent(Deprecated.class)) { + resource.setValue(SecuritySettings.PASSWORD_HASH.getPath(), HashAlgorithm.SHA256); + Set legacyHashes = SecuritySettings.LEGACY_HASHES.getValue(resource); + legacyHashes.add(currentHash); + resource.setValue(SecuritySettings.LEGACY_HASHES.getPath(), legacyHashes); + ConsoleLogger.warning("The hash algorithm '" + currentHash + + "' is no longer supported for active use. New hashes will be in SHA256."); + return true; + } + } + return false; + } + /** * Checks for an old property path and moves it to a new path if it is present and the new path is not yet set. * diff --git a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java index 07d0eaf96..0a32c5584 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java @@ -53,7 +53,7 @@ public final class SecuritySettings implements SettingsHolder { newProperty("settings.security.passwordMaxLength", 30); @Comment({ - "Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512, WHIRLPOOL,", + "Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512,", "MYBB, IPB3, PHPBB, PHPFUSION, SMF, XENFORO, XAUTH, JOOMLA, WBB3, WBB4, MD5VB,", "PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM (for developers only). See full list at", "https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/hash_algorithms.md" diff --git a/src/test/java/fr/xephi/authme/initialization/OnStartupTasksTest.java b/src/test/java/fr/xephi/authme/initialization/OnStartupTasksTest.java deleted file mode 100644 index e3febf41f..000000000 --- a/src/test/java/fr/xephi/authme/initialization/OnStartupTasksTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package fr.xephi.authme.initialization; - -import fr.xephi.authme.security.HashAlgorithm; -import org.junit.Test; - -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; - -/** - * Test for {@link OnStartupTasks}. - */ -public class OnStartupTasksTest { - - @Test - public void shouldCheckIfHashIsDeprecatedIn54() { - // given / when / then - assertThat(OnStartupTasks.isHashDeprecatedIn54(HashAlgorithm.CUSTOM), equalTo(false)); - assertThat(OnStartupTasks.isHashDeprecatedIn54(HashAlgorithm.IPB3), equalTo(false)); - assertThat(OnStartupTasks.isHashDeprecatedIn54(HashAlgorithm.PLAINTEXT), equalTo(false)); - assertThat(OnStartupTasks.isHashDeprecatedIn54(HashAlgorithm.SHA256), equalTo(false)); - assertThat(OnStartupTasks.isHashDeprecatedIn54(HashAlgorithm.WORDPRESS), equalTo(false)); - - assertThat(OnStartupTasks.isHashDeprecatedIn54(HashAlgorithm.MD5), equalTo(true)); - assertThat(OnStartupTasks.isHashDeprecatedIn54(HashAlgorithm.SHA512), equalTo(true)); - assertThat(OnStartupTasks.isHashDeprecatedIn54(HashAlgorithm.WHIRLPOOL), equalTo(true)); - } -} diff --git a/src/test/java/fr/xephi/authme/settings/SettingsMigrationServiceTest.java b/src/test/java/fr/xephi/authme/settings/SettingsMigrationServiceTest.java index da7c270be..0a952bb0b 100644 --- a/src/test/java/fr/xephi/authme/settings/SettingsMigrationServiceTest.java +++ b/src/test/java/fr/xephi/authme/settings/SettingsMigrationServiceTest.java @@ -1,12 +1,16 @@ package fr.xephi.authme.settings; +import ch.jalu.configme.configurationdata.ConfigurationData; +import ch.jalu.configme.properties.Property; import ch.jalu.configme.resource.PropertyResource; import ch.jalu.configme.resource.YamlFileResource; import com.google.common.io.Files; import fr.xephi.authme.TestHelper; +import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.output.LogLevel; import fr.xephi.authme.process.register.RegisterSecondaryArgument; import fr.xephi.authme.process.register.RegistrationType; +import fr.xephi.authme.security.HashAlgorithm; import fr.xephi.authme.settings.properties.AuthMeSettingsRetriever; import org.junit.BeforeClass; import org.junit.Rule; @@ -16,6 +20,8 @@ import org.junit.rules.TemporaryFolder; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; import static fr.xephi.authme.TestHelper.getJarFile; import static fr.xephi.authme.settings.properties.PluginSettings.ENABLE_PERMISSION_CHECK; @@ -28,6 +34,8 @@ import static fr.xephi.authme.settings.properties.RegistrationSettings.REGISTRAT import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS; import static fr.xephi.authme.settings.properties.RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN; import static fr.xephi.authme.settings.properties.RestrictionSettings.FORCE_SPAWN_ON_WORLDS; +import static fr.xephi.authme.settings.properties.SecuritySettings.LEGACY_HASHES; +import static fr.xephi.authme.settings.properties.SecuritySettings.PASSWORD_HASH; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; @@ -47,8 +55,9 @@ public class SettingsMigrationServiceTest { TestHelper.setupLogger(); } + /* When settings are loaded, test that migrations are applied and immediately available in memory. */ @Test - public void shouldPerformMigrations() throws IOException { + public void shouldPerformMigrationsInMemory() throws IOException { // given File dataFolder = temporaryFolder.newFolder(); File configFile = new File(dataFolder, "config.yml"); @@ -61,22 +70,31 @@ public class SettingsMigrationServiceTest { dataFolder, resource, migrationService, AuthMeSettingsRetriever.buildConfigurationData()); // then - assertThat(settings.getProperty(ALLOWED_NICKNAME_CHARACTERS), equalTo(ALLOWED_NICKNAME_CHARACTERS.getDefaultValue())); - assertThat(settings.getProperty(DELAY_JOIN_MESSAGE), equalTo(true)); - assertThat(settings.getProperty(FORCE_SPAWN_LOCATION_AFTER_LOGIN), equalTo(true)); - assertThat(settings.getProperty(FORCE_SPAWN_ON_WORLDS), contains("survival", "survival_nether", "creative")); - assertThat(settings.getProperty(LOG_LEVEL), equalTo(LogLevel.INFO)); - assertThat(settings.getProperty(REGISTRATION_TYPE), equalTo(RegistrationType.EMAIL)); - assertThat(settings.getProperty(REGISTER_SECOND_ARGUMENT), equalTo(RegisterSecondaryArgument.CONFIRMATION)); - assertThat(settings.getProperty(ENABLE_PERMISSION_CHECK), equalTo(true)); - assertThat(settings.getProperty(REGISTERED_GROUP), equalTo("unLoggedinGroup")); - assertThat(settings.getProperty(UNREGISTERED_GROUP), equalTo("")); + verifyHasUpToDateSettings(settings, dataFolder); + } - // Check migration of old setting to email.html - assertThat(Files.readLines(new File(dataFolder, "email.html"), StandardCharsets.UTF_8), - contains("Dear ,

This is your new AuthMe password for the server " - + "

:



Do not forget to " - + "change password after login!
/changepassword newPassword")); + /* + * When settings are loaded, test that migrations are applied and persisted to disk, + * i.e. when the settings are loaded again from the file, no migrations should be necessary. + */ + @Test + public void shouldPerformMigrationsAndPersistToDisk() throws IOException { + // given + File dataFolder = temporaryFolder.newFolder(); + File configFile = new File(dataFolder, "config.yml"); + Files.copy(getJarFile(OLD_CONFIG_FILE), configFile); + PropertyResource resource = new YamlFileResource(configFile); + TestMigrationServiceExtension migrationService = new TestMigrationServiceExtension(dataFolder); + ConfigurationData configurationData = AuthMeSettingsRetriever.buildConfigurationData(); + + // when + new Settings(dataFolder, resource, migrationService, configurationData); + resource = new YamlFileResource(configFile); + Settings settings = new Settings(dataFolder, resource, migrationService, configurationData); + + // then + verifyHasUpToDateSettings(settings, dataFolder); + assertThat(migrationService.returnedValues, contains(true, false)); } @Test @@ -97,4 +115,40 @@ public class SettingsMigrationServiceTest { assertThat(migrationService.getOnRegisterCommands(), contains("me registers", "msg CONSOLE hi")); assertThat(migrationService.getOnRegisterConsoleCommands(), contains("sethome %p:regloc")); } + + private void verifyHasUpToDateSettings(Settings settings, File dataFolder) throws IOException { + assertThat(settings.getProperty(ALLOWED_NICKNAME_CHARACTERS), equalTo(ALLOWED_NICKNAME_CHARACTERS.getDefaultValue())); + assertThat(settings.getProperty(DELAY_JOIN_MESSAGE), equalTo(true)); + assertThat(settings.getProperty(FORCE_SPAWN_LOCATION_AFTER_LOGIN), equalTo(true)); + assertThat(settings.getProperty(FORCE_SPAWN_ON_WORLDS), contains("survival", "survival_nether", "creative")); + assertThat(settings.getProperty(LOG_LEVEL), equalTo(LogLevel.INFO)); + assertThat(settings.getProperty(REGISTRATION_TYPE), equalTo(RegistrationType.EMAIL)); + assertThat(settings.getProperty(REGISTER_SECOND_ARGUMENT), equalTo(RegisterSecondaryArgument.CONFIRMATION)); + assertThat(settings.getProperty(ENABLE_PERMISSION_CHECK), equalTo(true)); + assertThat(settings.getProperty(REGISTERED_GROUP), equalTo("unLoggedinGroup")); + assertThat(settings.getProperty(UNREGISTERED_GROUP), equalTo("")); + assertThat(settings.getProperty(PASSWORD_HASH), equalTo(HashAlgorithm.SHA256)); + assertThat(settings.getProperty(LEGACY_HASHES), contains(HashAlgorithm.PBKDF2, HashAlgorithm.WORDPRESS, HashAlgorithm.SHA512)); + + // Check migration of old setting to email.html + assertThat(Files.readLines(new File(dataFolder, "email.html"), StandardCharsets.UTF_8), + contains("Dear ,

This is your new AuthMe password for the server " + + "

:



Do not forget to " + + "change password after login!
/changepassword newPassword")); + } + + private static class TestMigrationServiceExtension extends SettingsMigrationService { + private List returnedValues = new ArrayList<>(); + + TestMigrationServiceExtension(@DataFolder File pluginFolder) { + super(pluginFolder); + } + + @Override + protected boolean performMigrations(PropertyResource resource, List> properties) { + boolean result = super.performMigrations(resource, properties); + returnedValues.add(result); + return result; + } + } } diff --git a/src/test/resources/fr/xephi/authme/settings/config-old.yml b/src/test/resources/fr/xephi/authme/settings/config-old.yml index 65e2614ce..0d2e425c5 100644 --- a/src/test/resources/fr/xephi/authme/settings/config-old.yml +++ b/src/test/resources/fr/xephi/authme/settings/config-old.yml @@ -191,7 +191,10 @@ settings: # PLAINTEXT ( unhashed password), # MYBB, IPB3, PHPFUSION, SMF, XENFORO, SALTED2MD5, JOOMLA, BCRYPT, WBB3, SHA512, # DOUBLEMD5, PBKDF2, PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM(for developpers only) - passwordHash: SHA256 + passwordHash: SHA512 + legacyHashes: + - PBKDF2 + - WORDPRESS # salt length for the SALTED2MD5 MD5(MD5(password)+salt) doubleMD5SaltLength: 8 # If password checking return false , do we need to check with all