package com.constellio.model.services.users; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; import java.security.Key; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.joda.time.LocalDateTime; import org.junit.Before; import org.junit.Test; import com.constellio.data.dao.services.idGenerator.UUIDV1Generator; import com.constellio.model.conf.ModelLayerConfiguration; import com.constellio.model.conf.PropertiesModelLayerConfiguration.InMemoryModelLayerConfiguration; import com.constellio.model.entities.security.global.UserCredential; import com.constellio.model.entities.security.global.UserCredentialStatus; import com.constellio.model.services.collections.CollectionsListManager; import com.constellio.model.services.encrypt.EncryptionKeyFactory; import com.constellio.model.services.factories.ModelLayerFactoryUtils; import com.constellio.sdk.tests.ConstellioTest; import com.constellio.sdk.tests.ModelLayerConfigurationAlteration; public class UserCredentialsManagerAcceptanceTest extends ConstellioTest { LocalDateTime shishOClock = new LocalDateTime(); String edouardServiceKey = "myKey"; UserCredentialsManager manager; UserCredential chuckUserCredential, edouardUserCredential, bobUserCredential; CollectionsListManager collectionsListManager; LocalDateTime endDate = new LocalDateTime().plusMinutes(30); List<String> msExchDelegateListBL = new ArrayList<>(); @Before public void setUp() throws Exception { givenCollection("collection1"); givenCollection("zeCollection"); givenDisabledAfterTestValidations(); withSpiedServices(ModelLayerConfiguration.class, CollectionsListManager.class); configure(new ModelLayerConfigurationAlteration() { @Override public void alter(InMemoryModelLayerConfiguration configuration) { configuration.setTokenDuration(org.joda.time.Duration.standardSeconds(42)); } }); collectionsListManager = getModelLayerFactory().getCollectionsListManager(); msExchDelegateListBL = new ArrayList<>(); msExchDelegateListBL.add("msExchDelegateListBL1"); msExchDelegateListBL.add("msExchDelegateListBL2"); Key key = EncryptionKeyFactory.newApplicationKey("zePassword", "zeUltimateSalt"); ModelLayerFactoryUtils.setApplicationEncryptionKey(getModelLayerFactory(), key); manager = getModelLayerFactory().getUserCredentialsManager(); createUserCredentials(); } @Test public void whenAddingAndSearchingCredentialsThenUsernamesAreNormalized() { manager.addUpdate(edouardUserCredential); assertThat(manager.getUserCredential("Edouard")).isNotNull(); assertThat(manager.getUserCredential("EDOUARD")).isNotNull(); assertThat(manager.getUserCredential("Édouard")).isNotNull(); } @Test public void whenAddUsersCredentialsThenTheyAreAddedInListOnce() throws Exception { manager.addUpdate(chuckUserCredential); manager.addUpdate(edouardUserCredential); manager.addUpdate(chuckUserCredential); UserCredential admin = manager.getUserCredential("admin"); assertThat(manager.getActiveUserCredentials()).extracting("firstName", "lastName").containsOnly( tuple(admin.getFirstName(), admin.getLastName()), tuple(chuckUserCredential.getFirstName(), chuckUserCredential.getLastName()), tuple(edouardUserCredential.getFirstName(), edouardUserCredential.getLastName())); } @Test public void givenHasInvalidCollectionWhenReadThenHAsOnlyValidCollections() { manager.addUpdate(edouardUserCredential); assertThat(manager.getUserCredential("edouard").getCollections()).containsOnly(zeCollection, "collection1"); } @Test public void givenUserCredentialInListWhenUpdateUserCredentialThenHeIsUpdated() throws Exception { manager.addUpdate(chuckUserCredential); manager.addUpdate(edouardUserCredential); chuckUserCredential = manager.create("chuck", "Chuck1", "Norris1", "chuck.norris1@gmail.com", asList("group11"), asList(zeCollection, "collection1"), UserCredentialStatus.ACTIVE, "domain", msExchDelegateListBL, null); manager.addUpdate(chuckUserCredential); assertThat(manager.getActiveUserCredentials()).hasSize(3); assertThat(manager.getActiveUserCredentials().get(1)).isEqualToComparingFieldByField(chuckUserCredential); assertThat(manager.getActiveUserCredentials().get(2)).isEqualToComparingFieldByField(edouardUserCredential); assertThat(manager.getUserCredential("chuck")).isEqualToComparingFieldByField(chuckUserCredential); assertThat(manager.getUserCredential("edouard")).isEqualToComparingFieldByField(edouardUserCredential); assertThat(manager.getUserCredential("edouard").getAccessTokens().get("token1")).isEqualTo(endDate); } @Test public void whenAddCollectionToExistingUserCredentialThenItIsUpdated() throws Exception { manager.addUpdate(chuckUserCredential); chuckUserCredential = manager.create("chuck", "Chuck", "Norris", "chuck.norris@gmail.com", asList("group1"), asList(zeCollection, "collection1"), UserCredentialStatus.ACTIVE, "domain", msExchDelegateListBL, null); manager.addUpdate(chuckUserCredential); assertThat(manager.getActiveUserCredentials()).hasSize(2); assertThat(manager.getUserCredential("chuck")).isEqualToComparingFieldByField(chuckUserCredential); } @Test public void givenUserCredentialInGlobalGroupWhenGetUserCredentialInGlobalGroupThenItIsReturned() throws Exception { manager.addUpdate(chuckUserCredential); manager.addUpdate(edouardUserCredential); assertThat(manager.getUserCredentialsInGlobalGroup("group1")).hasSize(1); assertThat(manager.getUserCredentialsInGlobalGroup("group1").get(0)).isEqualToComparingFieldByField(chuckUserCredential); assertThat(manager.getUserCredentialsInGlobalGroup("group2")).hasSize(1); assertThat(manager.getUserCredentialsInGlobalGroup("group2").get(0)) .isEqualToComparingFieldByField(edouardUserCredential); assertThat(manager.getUserCredentialsInGlobalGroup("group3")).isEmpty(); } @Test public void givenUserCredentialWhenRemoveCollectionThenRemoveItFromAllUsers() throws Exception { manager.addUpdate(chuckUserCredential); manager.addUpdate(edouardUserCredential); manager.removeCollection(zeCollection); Set<String> collections = getAllCollectionsInUserCredentialFile(); assertThat(collections).doesNotContain(zeCollection); } @Test public void givenUserCredentialWhenRemoveTokenThenItIsRemoved() throws Exception { manager.addUpdate(chuckUserCredential); manager.addUpdate(edouardUserCredential); manager.removeToken("token1"); assertThat(manager.getServiceKeyByToken("token1")).isNull(); assertThat(manager.getServiceKeyByToken("token2")).isNotNull(); } @Test public void whenRemoveUserCredentialThenItIsRemoved() throws Exception { manager.addUpdate(chuckUserCredential); manager.addUpdate(edouardUserCredential); manager.removeUserCredentialFromCollection(chuckUserCredential, zeCollection); assertThat(manager.getActiveUserCredentials()).hasSize(3); assertThat(manager.getActiveUserCredentials().get(0).getUsername()).isEqualTo("admin"); assertThat(manager.getActiveUserCredentials().get(0).getCollections()).hasSize(0); assertThat(manager.getActiveUserCredentials().get(1).getUsername()).isEqualTo(chuckUserCredential.getUsername()); assertThat(manager.getActiveUserCredentials().get(1).getCollections()).isEmpty(); assertThat(manager.getActiveUserCredentials().get(2).getUsername()).isEqualTo(edouardUserCredential.getUsername()); assertThat(manager.getActiveUserCredentials().get(2).getCollections()).hasSize(2); } @Test public void whenChangeStatusUserThenOk() throws Exception { manager.addUpdate(chuckUserCredential); manager.addUpdate(edouardUserCredential); chuckUserCredential = chuckUserCredential.withStatus(UserCredentialStatus.DELETED); manager.addUpdate(chuckUserCredential); assertThat(manager.getActiveUserCredentials()).hasSize(2); assertThat(manager.getDeletedUserCredentials()).hasSize(1); assertThat(manager.getDeletedUserCredentials().get(0).getUsername()).isEqualTo(chuckUserCredential.getUsername()); chuckUserCredential = chuckUserCredential.withStatus(UserCredentialStatus.SUSPENDED); manager.addUpdate(chuckUserCredential); assertThat(manager.getActiveUserCredentials()).hasSize(2); assertThat(manager.getDeletedUserCredentials()).isEmpty(); assertThat(manager.getSuspendedUserCredentials().get(0).getUsername()).isEqualTo(chuckUserCredential.getUsername()); chuckUserCredential = chuckUserCredential.withStatus(UserCredentialStatus.PENDING); manager.addUpdate(chuckUserCredential); assertThat(manager.getActiveUserCredentials()).hasSize(2); assertThat(manager.getSuspendedUserCredentials()).isEmpty(); assertThat(manager.getPendingApprovalUserCredentials().get(0).getUsername()).isEqualTo(chuckUserCredential.getUsername()); chuckUserCredential = chuckUserCredential.withStatus(UserCredentialStatus.ACTIVE); manager.addUpdate(chuckUserCredential); assertThat(manager.getActiveUserCredentials()).hasSize(3); assertThat(manager.getPendingApprovalUserCredentials()).isEmpty(); } @Test public void whenRemoveGroupThenItIsRemoved() throws Exception { manager.addUpdate(chuckUserCredential); manager.addUpdate(edouardUserCredential); manager.removeGroup("group1"); assertThat(manager.getUserCredential("chuck").getGlobalGroups()).isEmpty(); assertThat(manager.getUserCredential("edouard").getGlobalGroups()).hasSize(1); assertThat(manager.getUserCredential("edouard").getGlobalGroups().get(0)).isEqualTo("group2"); } @Test public void givenTwoTokensWhenGetServiceKeyByTokenThenReturnIt() throws Exception { manager.addUpdate(edouardUserCredential); String serviceKey = manager.getServiceKeyByToken("token1"); String serviceKey2 = manager.getServiceKeyByToken("token2"); String serviceKey3 = manager.getServiceKeyByToken("token3"); assertThat(serviceKey).isEqualTo(serviceKey2).isEqualTo(edouardServiceKey); assertThat(serviceKey3).isNull(); } @Test public void givenUserHasTokensThenAreAutomaticallyDeletedAfterTheGivenTime() throws Exception { String tokenA = UUIDV1Generator.newRandomId(); String tokenB = UUIDV1Generator.newRandomId(); String tokenC = UUIDV1Generator.newRandomId(); givenTimeIs(shishOClock.minusYears(1)); manager.addUpdate(chuckUserCredential); manager.addUpdate(bobUserCredential); manager.addUpdate(chuckUserCredential .withAccessToken(tokenA, shishOClock).withAccessToken(tokenB, shishOClock.plusHours(1))); manager.addUpdate(bobUserCredential.withAccessToken(tokenC, shishOClock.plusMinutes(1))); givenTimeIs(shishOClock.minusSeconds(1)); manager.removeTimedOutTokens(); assertThat(manager.getUserCredential(chuckUserCredential.getUsername()).getTokenKeys()).containsOnly(tokenA, tokenB); assertThat(manager.getUserCredential(bobUserCredential.getUsername()).getTokenKeys()).containsOnly(tokenC); givenTimeIs(shishOClock); manager.removeTimedOutTokens(); assertThat(manager.getUserCredential(chuckUserCredential.getUsername()).getTokenKeys()).containsOnly(tokenB); assertThat(manager.getUserCredential(bobUserCredential.getUsername()).getTokenKeys()).containsOnly(tokenC); givenTimeIs(shishOClock.plusMinutes(1)); manager.removeTimedOutTokens(); assertThat(manager.getUserCredential(chuckUserCredential.getUsername()).getTokenKeys()).containsOnly(tokenB); assertThat(manager.getUserCredential(bobUserCredential.getUsername()).getTokenKeys()).isEmpty(); givenTimeIs(shishOClock.plusMinutes(59)); manager.removeTimedOutTokens(); assertThat(manager.getUserCredential(chuckUserCredential.getUsername()).getTokenKeys()).containsOnly(tokenB); assertThat(manager.getUserCredential(bobUserCredential.getUsername()).getTokenKeys()).isEmpty(); givenTimeIs(shishOClock.plusMinutes(60)); manager.removeTimedOutTokens(); assertThat(manager.getUserCredential(chuckUserCredential.getUsername()).getTokenKeys()).isEmpty(); assertThat(manager.getUserCredential(bobUserCredential.getUsername()).getTokenKeys()).isEmpty(); } private void createUserCredentials() { chuckUserCredential = manager.create("chuck", "Chuck", "Norris", "chuck.norris@gmail.com", null, true, asList("group1"), asList(zeCollection), new HashMap<String, LocalDateTime>(), UserCredentialStatus.ACTIVE, "domain", msExchDelegateListBL, null); bobUserCredential = manager.create("bob", "Bob", "Gratton", "bob.gratton@gmail.com", null, true, asList("group1"), asList(zeCollection), new HashMap<String, LocalDateTime>(), UserCredentialStatus.ACTIVE, "domain", msExchDelegateListBL, null); Map<String, LocalDateTime> tokens = new HashMap<String, LocalDateTime>(); tokens.put("token1", endDate); tokens.put("token2", endDate.plusMinutes(30)); edouardUserCredential = manager.create("edouard", "Edouard", "Lechat", "edouard.lechat@gmail.com", edouardServiceKey, false, asList("group2"), asList(zeCollection, "collection1"), tokens, UserCredentialStatus.ACTIVE, "domain", msExchDelegateListBL, null); } private Set<String> getAllCollectionsInUserCredentialFile() { Set<String> collections = new HashSet<>(); List<UserCredential> userCredentials = manager.getActiveUserCredentials(); for (UserCredential userCredential : userCredentials) { collections.addAll(userCredential.getCollections()); } return collections; } }