#850 Fix export of legacy hashes property

- Ugly workaround due to #1014: need to have EnumSetProperty extend from StringListProperty type so that it is exported in a proper manner (as a string list). To get an enum Set we need to call a dedicated method on EnumSetProperty for the time being.
This commit is contained in:
ljacqu 2016-11-22 22:02:34 +01:00
parent 7d65d2a7c4
commit d2a28bdaed
4 changed files with 31 additions and 24 deletions

View File

@ -6,6 +6,7 @@ import fr.xephi.authme.events.PasswordEncryptionEvent;
import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.security.crypts.EncryptionMethod; import fr.xephi.authme.security.crypts.EncryptionMethod;
import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.EnumSetProperty;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
@ -41,7 +42,8 @@ public class PasswordSecurity implements Reloadable {
@Override @Override
public void reload() { public void reload() {
this.algorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH); this.algorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH);
this.legacyAlgorithms = settings.getProperty(SecuritySettings.LEGACY_HASHES); // TODO #1014: Need to cast to specific type because ConfigMe ignores fields of child Property types
this.legacyAlgorithms = ((EnumSetProperty<HashAlgorithm>) SecuritySettings.LEGACY_HASHES).asEnumSet(settings);
} }
/** /**

View File

@ -1,35 +1,38 @@
package fr.xephi.authme.settings; package fr.xephi.authme.settings;
import com.github.authme.configme.properties.Property; import com.github.authme.configme.SettingsManager;
import com.github.authme.configme.resource.PropertyResource; import com.github.authme.configme.properties.StringListProperty;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* Property whose value is a set of entries of a given enum. * Property whose value is a set of entries of a given enum.
*/ */
// TODO https://github.com/AuthMe/ConfigMe/issues/27: Should be a Property of Set<E> type // TODO #1014: This property type currently extends StringListProperty with a dedicated method to convert the values
public class EnumSetProperty<E extends Enum<E>> extends Property<List<E>> { // into a Set of the selected enum due to multiple issues on ConfigMe's side.
public class EnumSetProperty<E extends Enum<E>> extends StringListProperty {
private final Class<E> enumClass; private final Class<E> enumClass;
public EnumSetProperty(Class<E> enumClass, String path, List<E> defaultValue) { public EnumSetProperty(Class<E> enumClass, String path, String... values) {
super(path, defaultValue); super(path, values);
this.enumClass = enumClass; this.enumClass = enumClass;
} }
@Override /**
protected List<E> getFromResource(PropertyResource resource) { * Returns the value as a set of enum entries.
List<?> elements = resource.getList(getPath()); *
if (elements != null) { * @param settings the settings manager to look up the raw value with
return elements.stream() * @return the property's value as mapped enum entries
.map(val -> toEnum(String.valueOf(val))) */
.filter(e -> e != null) public Set<E> asEnumSet(SettingsManager settings) {
.distinct() List<String> entries = settings.getProperty(this);
.collect(Collectors.toList()); return entries.stream()
} .map(str -> toEnum(str))
return null; .filter(e -> e != null)
.collect(Collectors.toSet());
} }
private E toEnum(String str) { private E toEnum(String str) {

View File

@ -6,7 +6,6 @@ import com.github.authme.configme.properties.Property;
import fr.xephi.authme.security.HashAlgorithm; import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.settings.EnumSetProperty; import fr.xephi.authme.settings.EnumSetProperty;
import java.util.Collections;
import java.util.List; import java.util.List;
import static com.github.authme.configme.properties.PropertyInitializer.newLowercaseListProperty; import static com.github.authme.configme.properties.PropertyInitializer.newLowercaseListProperty;
@ -83,8 +82,8 @@ public class SecuritySettings implements SettingsHolder {
"legacyHashes:", "legacyHashes:",
"- 'SHA1'" "- 'SHA1'"
}) })
public static final Property<List<HashAlgorithm>> LEGACY_HASHES = public static final Property<List<String>> LEGACY_HASHES =
new EnumSetProperty<>(HashAlgorithm.class, "settings.security.legacyHashes", Collections.emptyList()); new EnumSetProperty<>(HashAlgorithm.class, "settings.security.legacyHashes");
@Comment({"Prevent unsafe passwords from being used; put them in lowercase!", @Comment({"Prevent unsafe passwords from being used; put them in lowercase!",
"You should always set 'help' as unsafePassword due to possible conflicts.", "You should always set 'help' as unsafePassword due to possible conflicts.",

View File

@ -26,8 +26,10 @@ import org.mockito.stubbing.Answer;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newHashSet;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.equalToIgnoringCase; import static org.hamcrest.Matchers.equalToIgnoringCase;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
@ -173,7 +175,7 @@ public class PasswordSecurityTest {
given(method.comparePassword(clearTextPass, password, playerLowerCase)).willReturn(false); given(method.comparePassword(clearTextPass, password, playerLowerCase)).willReturn(false);
given(method.computeHash(clearTextPass, playerLowerCase)).willReturn(newPassword); given(method.computeHash(clearTextPass, playerLowerCase)).willReturn(newPassword);
initSettings(HashAlgorithm.MD5); initSettings(HashAlgorithm.MD5);
given(settings.getProperty(SecuritySettings.LEGACY_HASHES)).willReturn(newArrayList(HashAlgorithm.BCRYPT)); given(settings.getProperty(SecuritySettings.LEGACY_HASHES)).willReturn(newArrayList(HashAlgorithm.BCRYPT.name()));
PasswordSecurity security = newPasswordSecurity(); PasswordSecurity security = newPasswordSecurity();
// when // when
@ -258,7 +260,7 @@ public class PasswordSecurityTest {
initSettings(HashAlgorithm.BCRYPT); initSettings(HashAlgorithm.BCRYPT);
PasswordSecurity passwordSecurity = newPasswordSecurity(); PasswordSecurity passwordSecurity = newPasswordSecurity();
given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.MD5); given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.MD5);
List<HashAlgorithm> legacyHashes = newArrayList(HashAlgorithm.CUSTOM, HashAlgorithm.BCRYPT); List<String> legacyHashes = newArrayList(HashAlgorithm.CUSTOM.name(), HashAlgorithm.BCRYPT.name());
given(settings.getProperty(SecuritySettings.LEGACY_HASHES)).willReturn(legacyHashes); given(settings.getProperty(SecuritySettings.LEGACY_HASHES)).willReturn(legacyHashes);
// when // when
@ -267,8 +269,9 @@ public class PasswordSecurityTest {
// then // then
assertThat(ReflectionTestUtils.getFieldValue(PasswordSecurity.class, passwordSecurity, "algorithm"), assertThat(ReflectionTestUtils.getFieldValue(PasswordSecurity.class, passwordSecurity, "algorithm"),
equalTo(HashAlgorithm.MD5)); equalTo(HashAlgorithm.MD5));
Set<HashAlgorithm> legacyHashesSet = newHashSet(HashAlgorithm.CUSTOM, HashAlgorithm.BCRYPT);
assertThat(ReflectionTestUtils.getFieldValue(PasswordSecurity.class, passwordSecurity, "legacyAlgorithms"), assertThat(ReflectionTestUtils.getFieldValue(PasswordSecurity.class, passwordSecurity, "legacyAlgorithms"),
equalTo(legacyHashes)); equalTo(legacyHashesSet));
} }
private PasswordSecurity newPasswordSecurity() { private PasswordSecurity newPasswordSecurity() {