package com.constellio.model.services.security.authentification;
import static com.constellio.data.conf.HashingEncoding.BASE64;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.spy;
import org.junit.Before;
import org.junit.Test;
import com.constellio.data.dao.managers.config.ConfigManager;
import com.constellio.data.dao.managers.config.values.PropertiesConfiguration;
import com.constellio.data.utils.hashing.HashingService;
import com.constellio.data.utils.hashing.HashingServiceException;
import com.constellio.sdk.tests.ConstellioTest;
public class PasswordFileAuthentificationServiceAcceptanceTest extends ConstellioTest {
private static final String NEW_PASSWORD = "newPassword";
private static final String PASSWORD = "password";
String authentificationPropertiesPath = "/authentification.properties";
String usernameChuck = "chuck";
String usernameDakota = "dakota";
PasswordFileAuthenticationService passwordFileAuthenticationService;
ConfigManager configManager;
HashingService hashingService;
@Before
public void setup()
throws Exception {
configManager = getDataLayerFactory().getConfigManager();
hashingService = spy(getIOLayerFactory().newHashingService(BASE64));
passwordFileAuthenticationService = getModelLayerFactory()
.getPasswordFileAuthenticationService();
}
@Test
public void givenMultipleUsernamesWithSimilarNamesThenDetectGoodPassword()
throws Exception {
passwordFileAuthenticationService.changePassword("adminconstellio", "password1");
passwordFileAuthenticationService.changePassword("adminCONSTELLIO", "password2");
assertThat(passwordFileAuthenticationService.authenticate("adminconstellio", "password1")).isFalse();
assertThat(passwordFileAuthenticationService.authenticate("adminconstellio", "password2")).isTrue();
assertThat(passwordFileAuthenticationService.authenticate("adminCONSTELLIO", "password1")).isFalse();
assertThat(passwordFileAuthenticationService.authenticate("adminCONSTELLIO", "password2")).isTrue();
assertThat(passwordFileAuthenticationService.authenticate("adminconstellio", "password4")).isFalse();
}
@Test
public void givenPasswordHashPropertyWhenChangeOldPasswordThenItIsChanged()
throws Exception {
givenChuckPasswordProperty();
String newPassword = NEW_PASSWORD;
String newPasswordHash = hashingService.getHashFromBytes(newPassword.getBytes());
passwordFileAuthenticationService.changePassword(usernameChuck, PASSWORD, NEW_PASSWORD);
PropertiesConfiguration propertiesConfiguration = configManager.getProperties(authentificationPropertiesPath);
assertThat(propertiesConfiguration.getProperties().get(usernameChuck)).isEqualTo(newPasswordHash);
}
@Test(expected = PasswordFileAuthenticationServiceRuntimeException.InvalidPasswordException.class)
public void givenInvalidNewPasswordWhenChangeOldPasswordThenException()
throws Exception {
givenChuckPasswordProperty();
String newPassword = null;
passwordFileAuthenticationService.changePassword(usernameChuck, PASSWORD, newPassword);
}
@Test(expected = PasswordFileAuthenticationServiceRuntimeException.IncorrectPassword.class)
public void givenDifferentCurrentPasswordWhenChangeOldPasswordThenException()
throws Exception {
givenChuckPasswordProperty();
passwordFileAuthenticationService.changePassword(usernameChuck, "differentPassword", NEW_PASSWORD);
}
@Test(expected = PasswordFileAuthenticationServiceRuntimeException.IncorrectPassword.class)
public void givenInexistentUsernameWhenChangeOldPasswordThenException()
throws Exception {
givenChuckPasswordProperty();
passwordFileAuthenticationService.changePassword("inexistentUsername", PASSWORD, NEW_PASSWORD);
}
@Test(expected = PasswordFileAuthenticationServiceRuntimeException.CannotCalculateHash.class)
public void givenHashingServiceExceptionWhenChangeOldPasswordThenException()
throws Exception {
passwordFileAuthenticationService = new PasswordFileAuthenticationService(configManager, hashingService);
givenChuckPasswordProperty();
doThrow(HashingServiceException.class).when(hashingService).getHashFromBytes(PASSWORD.getBytes());
passwordFileAuthenticationService.changePassword(usernameChuck, PASSWORD, NEW_PASSWORD);
}
@Test
public void wWhenChangePasswordThenItIsChanged()
throws Exception {
givenChuckPasswordProperty();
String newPassword = NEW_PASSWORD;
String newPasswordHash = hashingService.getHashFromBytes(newPassword.getBytes());
passwordFileAuthenticationService.changePassword(usernameChuck, NEW_PASSWORD);
PropertiesConfiguration propertiesConfiguration = configManager.getProperties(authentificationPropertiesPath);
assertThat(propertiesConfiguration.getProperties().get(usernameChuck)).isEqualTo(newPasswordHash);
}
@Test(expected = PasswordFileAuthenticationServiceRuntimeException.InvalidPasswordException.class)
public void givenInvalidNewPasswordWhenChangePasswordThenException()
throws Exception {
String newPassword = null;
passwordFileAuthenticationService.changePassword(usernameChuck, newPassword);
}
@Test(expected = PasswordFileAuthenticationServiceRuntimeException.CannotCalculateHash.class)
public void givenHashingServiceExceptionWhenChangePasswordThenException()
throws Exception {
passwordFileAuthenticationService = new PasswordFileAuthenticationService(configManager, hashingService);
doThrow(HashingServiceException.class).when(hashingService).getHashFromBytes(NEW_PASSWORD.getBytes());
String newPassword = NEW_PASSWORD;
passwordFileAuthenticationService.changePassword(usernameChuck, newPassword);
}
@Test
public void givenUsernameAndPasswordWhenAuthenticateThenReturnTrue()
throws Exception {
givenChuckPasswordProperty();
boolean authenticated = passwordFileAuthenticationService.authenticate(usernameChuck, PASSWORD);
assertThat(authenticated).isTrue();
}
@Test
public void givenWrongUsernameWhenAuthenticateThenReturnFalse()
throws Exception {
givenChuckPasswordProperty();
boolean authenticated = passwordFileAuthenticationService.authenticate("inexistentUsername", PASSWORD);
assertThat(authenticated).isFalse();
}
@Test
public void givenWrongPasswordWhenAuthenticateThenReturnFalse()
throws Exception {
givenChuckPasswordProperty();
boolean authenticated = passwordFileAuthenticationService.authenticate(usernameChuck, "inexistentPassword");
assertThat(authenticated).isFalse();
}
private void givenChuckPasswordProperty()
throws HashingServiceException {
passwordFileAuthenticationService.changePassword(usernameChuck, PASSWORD);
}
}