#449 Remove use of legacy settings in encryption methods
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
package fr.xephi.authme.security;
|
||||
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -12,19 +13,25 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.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 NewSetting settings;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpWrapper() {
|
||||
WrapperMock.createInstance();
|
||||
Settings.bCryptLog2Rounds = 8;
|
||||
Settings.saltLength = 16;
|
||||
settings = mock(NewSetting.class);
|
||||
given(settings.getProperty(HooksSettings.BCRYPT_LOG2_ROUND)).willReturn(8);
|
||||
given(settings.getProperty(SecuritySettings.DOUBLE_MD5_SALT_LENGTH)).willReturn(16);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -47,8 +54,10 @@ public class HashAlgorithmIntegrationTest {
|
||||
public void shouldBeAbleToInstantiateEncryptionAlgorithms() throws InstantiationException, IllegalAccessException {
|
||||
// given / when / then
|
||||
for (HashAlgorithm algorithm : HashAlgorithm.values()) {
|
||||
if (!HashAlgorithm.CUSTOM.equals(algorithm)) {
|
||||
EncryptionMethod method = algorithm.getClazz().newInstance();
|
||||
if (!HashAlgorithm.CUSTOM.equals(algorithm) && !HashAlgorithm.PLAINTEXT.equals(algorithm)) {
|
||||
EncryptionMethod method = PasswordSecurity.initializeEncryptionMethod(algorithm, settings);
|
||||
assertThat("Encryption method for algorithm '" + algorithm + "' is not null",
|
||||
method, not(nullValue()));
|
||||
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()));
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
package fr.xephi.authme.security;
|
||||
|
||||
import fr.xephi.authme.ReflectionTestUtils;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.events.PasswordEncryptionEvent;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.security.crypts.JOOMLA;
|
||||
import fr.xephi.authme.security.crypts.PHPBB;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
@@ -35,19 +38,24 @@ import static org.mockito.Mockito.verify;
|
||||
/**
|
||||
* Test for {@link PasswordSecurity}.
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class PasswordSecurityTest {
|
||||
|
||||
@Mock
|
||||
private PluginManager pluginManager;
|
||||
@Mock
|
||||
private DataSource dataSource;
|
||||
@Mock
|
||||
private EncryptionMethod method;
|
||||
private Class<?> caughtClassInEvent;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpTest() {
|
||||
TestHelper.setupLogger();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUpMocks() {
|
||||
WrapperMock.createInstance();
|
||||
pluginManager = mock(PluginManager.class);
|
||||
dataSource = mock(DataSource.class);
|
||||
method = mock(EncryptionMethod.class);
|
||||
caughtClassInEvent = null;
|
||||
|
||||
// When the password encryption event is emitted, replace the encryption method with our mock.
|
||||
@@ -97,7 +105,6 @@ public class PasswordSecurityTest {
|
||||
String playerLowerCase = playerName.toLowerCase();
|
||||
String clearTextPass = "passw0Rd1";
|
||||
|
||||
PlayerAuth auth = mock(PlayerAuth.class);
|
||||
given(dataSource.getPassword(playerName)).willReturn(password);
|
||||
given(method.comparePassword(clearTextPass, password, playerLowerCase)).willReturn(false);
|
||||
PasswordSecurity security =
|
||||
@@ -165,6 +172,25 @@ public class PasswordSecurityTest {
|
||||
verify(dataSource).updatePassword(playerLowerCase, newPassword);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldTryAllMethodsAndFail() {
|
||||
// given
|
||||
HashedPassword password = new HashedPassword("hashNotMatchingAnyMethod", "someBogusSalt");
|
||||
String playerName = "asfd";
|
||||
String clearTextPass = "someInvalidPassword";
|
||||
given(dataSource.getPassword(playerName)).willReturn(password);
|
||||
given(method.comparePassword(clearTextPass, password, playerName)).willReturn(false);
|
||||
PasswordSecurity security =
|
||||
new PasswordSecurity(dataSource, mockSettings(HashAlgorithm.MD5, true), pluginManager);
|
||||
|
||||
// when
|
||||
boolean result = security.comparePassword(clearTextPass, playerName);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(false));
|
||||
verify(dataSource, never()).updatePassword(anyString(), any(HashedPassword.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHashPassword() {
|
||||
// given
|
||||
@@ -188,28 +214,6 @@ public class PasswordSecurityTest {
|
||||
assertThat(event.getPlayerName(), equalTo(usernameLowerCase));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHashPasswordWithGivenAlgorithm() {
|
||||
// given
|
||||
String password = "TopSecretPass#112525";
|
||||
String username = "someone12";
|
||||
HashedPassword hashedPassword = new HashedPassword("~T!est#Hash", "__someSalt__");
|
||||
given(method.computeHash(password, username)).willReturn(hashedPassword);
|
||||
PasswordSecurity security =
|
||||
new PasswordSecurity(dataSource, mockSettings(HashAlgorithm.JOOMLA, true), pluginManager);
|
||||
|
||||
// when
|
||||
HashedPassword result = security.computeHash(HashAlgorithm.PHPBB, password, username);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(hashedPassword));
|
||||
ArgumentCaptor<PasswordEncryptionEvent> captor = ArgumentCaptor.forClass(PasswordEncryptionEvent.class);
|
||||
verify(pluginManager).callEvent(captor.capture());
|
||||
PasswordEncryptionEvent event = captor.getValue();
|
||||
assertThat(PHPBB.class.equals(caughtClassInEvent), equalTo(true));
|
||||
assertThat(event.getPlayerName(), equalTo(username));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSkipCheckIfMandatorySaltIsUnavailable() {
|
||||
// given
|
||||
@@ -234,12 +238,13 @@ public class PasswordSecurityTest {
|
||||
@Test
|
||||
public void shouldReloadSettings() {
|
||||
// given
|
||||
PasswordSecurity passwordSecurity =
|
||||
new PasswordSecurity(dataSource, mockSettings(HashAlgorithm.BCRYPT, false), pluginManager);
|
||||
NewSetting updatedSettings = mockSettings(HashAlgorithm.MD5, true);
|
||||
NewSetting settings = mockSettings(HashAlgorithm.BCRYPT, false);
|
||||
PasswordSecurity passwordSecurity = new PasswordSecurity(dataSource, settings, pluginManager);
|
||||
given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.MD5);
|
||||
given(settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH)).willReturn(true);
|
||||
|
||||
// when
|
||||
passwordSecurity.reload(updatedSettings);
|
||||
passwordSecurity.reload();
|
||||
|
||||
// then
|
||||
assertThat(ReflectionTestUtils.getFieldValue(PasswordSecurity.class, passwordSecurity, "algorithm"),
|
||||
@@ -252,6 +257,8 @@ public class PasswordSecurityTest {
|
||||
NewSetting settings = mock(NewSetting.class);
|
||||
given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(algorithm);
|
||||
given(settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH)).willReturn(supportOldPassword);
|
||||
given(settings.getProperty(HooksSettings.BCRYPT_LOG2_ROUND)).willReturn(8);
|
||||
given(settings.getProperty(SecuritySettings.DOUBLE_MD5_SALT_LENGTH)).willReturn(16);
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Test for {@link BCRYPT}.
|
||||
*/
|
||||
public class BcryptTest extends AbstractEncryptionMethodTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpSettings() {
|
||||
WrapperMock.createInstance();
|
||||
Settings.bCryptLog2Rounds = 8;
|
||||
public static void initializeLogger() {
|
||||
TestHelper.setupLogger();
|
||||
}
|
||||
|
||||
public BcryptTest() {
|
||||
super(new BCRYPT(),
|
||||
super(new BCRYPT(mockSettings()),
|
||||
"$2a$10$6iATmYgwJVc3YONhVcZFve3Cfb5GnwvKhJ20r.hMjmcNkIT9.Uh9K", // password
|
||||
"$2a$10$LOhUxhEcS0vgDPv/jkXvCurNb7LjP9xUlEolJGk.Uhgikqc6FtIOi", // PassWord1
|
||||
"$2a$10$j9da7SGiaakWhzIms9BtwemLUeIhSEphGUQ3XSlvYgpYsGnGCKRBa", // &^%te$t?Pw@_
|
||||
@@ -26,4 +27,10 @@ public class BcryptTest extends AbstractEncryptionMethodTest {
|
||||
);
|
||||
}
|
||||
|
||||
private static NewSetting mockSettings() {
|
||||
NewSetting settings = mock(NewSetting.class);
|
||||
given(settings.getProperty(HooksSettings.BCRYPT_LOG2_ROUND)).willReturn(8);
|
||||
return settings;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
/**
|
||||
@@ -11,7 +10,6 @@ public class IPB4Test extends AbstractEncryptionMethodTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpSettings() {
|
||||
WrapperMock.createInstance();
|
||||
TestHelper.setupLogger();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.junit.Before;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Test for {@link SALTED2MD5}.
|
||||
*/
|
||||
public class SALTED2MD5Test extends AbstractEncryptionMethodTest {
|
||||
|
||||
@Before
|
||||
public void setUpAlgorithm() {
|
||||
WrapperMock.createInstance();
|
||||
Settings.saltLength = 8;
|
||||
}
|
||||
|
||||
public SALTED2MD5Test() {
|
||||
super(new SALTED2MD5(),
|
||||
super(new SALTED2MD5(mockSettings()),
|
||||
new HashedPassword("9f3d13dc01a6fe61fd669954174399f3", "9b5f5749"), // password
|
||||
new HashedPassword("b28c32f624a4eb161d6adc9acb5bfc5b", "f750ba32"), // PassWord1
|
||||
new HashedPassword("38dcb83cc68424afe3cda012700c2bb1", "eb2c3394"), // &^%te$t?Pw@_
|
||||
new HashedPassword("ad25606eae5b760c8a2469d65578ac39", "04eee598")); // âË_3(íù*)
|
||||
}
|
||||
|
||||
private static NewSetting mockSettings() {
|
||||
NewSetting settings = mock(NewSetting.class);
|
||||
given(settings.getProperty(SecuritySettings.DOUBLE_MD5_SALT_LENGTH)).willReturn(8);
|
||||
return settings;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
/**
|
||||
@@ -11,7 +10,6 @@ public class XFBCRYPTTest extends AbstractEncryptionMethodTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() {
|
||||
WrapperMock.createInstance();
|
||||
TestHelper.setupLogger();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user