diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagementMaintenanceTask.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagementMaintenanceTask.java index c0d98921e66941e8b2c2ad916890f19d89f81599..839c81a21829ed3f78a856c71bc1371ca580de18 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagementMaintenanceTask.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagementMaintenanceTask.java @@ -27,7 +27,6 @@ import org.apache.log4j.Logger; import com.fasterxml.jackson.databind.ObjectMapper; -import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi; import ch.systemsx.cisd.authentication.Principal; import ch.systemsx.cisd.authentication.ldap.LDAPAuthenticationService; import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; @@ -36,7 +35,6 @@ import ch.systemsx.cisd.common.logging.Log4jSimpleLogger; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; import ch.systemsx.cisd.common.maintenance.IMaintenanceTask; -import ch.systemsx.cisd.common.utilities.ITimeAndWaitingProvider; import ch.systemsx.cisd.common.utilities.SystemTimeProvider; import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider; @@ -131,7 +129,7 @@ public class UserManagementMaintenanceTask implements IMaintenanceTask return null; } } - + private boolean addGroup(UserManager userManager, UserGroup group) { String key = group.getKey(); @@ -191,7 +189,11 @@ public class UserManagementMaintenanceTask implements IMaintenanceTask protected UserManager createUserManager(UserManagerConfig config, Log4jSimpleLogger logger) { - return new UserManager(ldapService, CommonServiceProvider.getApplicationServerApi(), - config.getCommonSpaces(), logger, SystemTimeProvider.SYSTEM_TIME_PROVIDER); + UserManager userManager = new UserManager(ldapService, CommonServiceProvider.getApplicationServerApi(), + logger, SystemTimeProvider.SYSTEM_TIME_PROVIDER); + userManager.setGlobalSpaces(config.getGlobalSpaces()); + userManager.setCommonSpacesByRole(config.getCommonSpaces()); + userManager.setSamplesByType(config.getCommonSamples()); + return userManager; } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManager.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManager.java index 21f1e8828fd6388aa3ab7f913b6cd4a8fa1caf58..e8d6bcf648f1054474a2ab563e306228fe2003ae 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManager.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManager.java @@ -20,6 +20,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -27,13 +29,17 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; +import org.apache.commons.collections4.map.LinkedMap; + import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.AuthorizationGroup; import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.create.AuthorizationGroupCreation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.create.CreateAuthorizationGroupsOperation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.fetchoptions.AuthorizationGroupFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.id.AuthorizationGroupPermId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.search.AuthorizationGroupSearchCriteria; import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.update.AuthorizationGroupUpdate; import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.update.UpdateAuthorizationGroupsOperation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.operation.IOperation; @@ -48,14 +54,20 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.search.PersonSearchCriter import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.update.PersonUpdate; import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.update.UpdatePersonsOperation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.Role; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.RoleAssignment; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.RoleLevel; import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.create.CreateRoleAssignmentsOperation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.create.RoleAssignmentCreation; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.delete.DeleteRoleAssignmentsOperation; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.delete.RoleAssignmentDeletionOptions; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.id.IRoleAssignmentId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.Space; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.create.CreateSpacesOperation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.create.SpaceCreation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.fetchoptions.SpaceFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.ISpaceId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.search.SpaceSearchCriteria; import ch.ethz.sis.openbis.generic.server.asapi.v3.IApplicationServerInternalApi; import ch.systemsx.cisd.authentication.IAuthenticationService; import ch.systemsx.cisd.authentication.Principal; @@ -68,6 +80,10 @@ import ch.systemsx.cisd.common.utilities.ITimeProvider; */ public class UserManager { + private static final String GLOBAL_AUTHORIZATION_GROUP_CODE = "ALL_GROUPS"; + + private static final AuthorizationGroupPermId GLOBAL_AUTHORIZATION_GROUP_ID = new AuthorizationGroupPermId(GLOBAL_AUTHORIZATION_GROUP_CODE); + private final IAuthenticationService authenticationService; private final IApplicationServerInternalApi service; @@ -76,24 +92,42 @@ public class UserManager private final ITimeProvider timeProvider; - private final Map<Role, List<String>> commonSpacesByRole; - private final Map<String, UserInfo> userInfosByUserId = new TreeMap<>(); - private final Map<String, Map<String, Principal>> usersByGroupCode = new TreeMap<>(); + private final Map<String, Map<String, Principal>> usersByGroupCode = new LinkedHashMap<>(); private final List<String> groupCodes = new ArrayList<>(); + private List<String> globalSpaces = new ArrayList<>(); + + private Map<Role, List<String>> commonSpacesByRole = new HashMap<>(); + + private Map<String, String> samplesByType = new HashMap<>(); + public UserManager(IAuthenticationService authenticationService, IApplicationServerInternalApi service, - Map<Role, List<String>> commonSpacesByRole, ISimpleLogger logger, ITimeProvider timeProvider) + ISimpleLogger logger, ITimeProvider timeProvider) { this.authenticationService = authenticationService; this.service = service; - this.commonSpacesByRole = commonSpacesByRole; this.logger = logger; this.timeProvider = timeProvider; } + public void setGlobalSpaces(List<String> globalSpaces) + { + this.globalSpaces = globalSpaces; + } + + public void setCommonSpacesByRole(Map<Role, List<String>> commonSpacesByRole) + { + this.commonSpacesByRole = commonSpacesByRole; + } + + public void setSamplesByType(Map<String, String> samplesByType) + { + this.samplesByType = samplesByType; + } + public void addGroup(UserGroup group, Map<String, Principal> principalsByUserId) { String groupCode = group.getKey().toUpperCase(); @@ -121,8 +155,14 @@ public class UserManager { String sessionToken = service.loginAsSystem(); - manageGroups(sessionToken, report); - manageUsers(sessionToken, report); + manageGlobalSpaces(sessionToken, report); + revokeUsersUnkownByAuthenticationService(sessionToken, report); + CurrentState currentState = loadCurrentState(sessionToken, service); + for (Entry<String, Map<String, Principal>> entry : usersByGroupCode.entrySet()) + { + String groupCode = entry.getKey(); + manageGroup(sessionToken, groupCode, entry.getValue(), currentState, report); + } service.logout(sessionToken); } catch (Throwable e) @@ -133,90 +173,92 @@ public class UserManager return report; } - private void manageGroups(String sessionToken, UserManagerReport report) + private void manageGlobalSpaces(String sessionToken, UserManagerReport report) { - Map<String, Set<String>> usersByGroupCodes = getUsersByGroupCodes(sessionToken); - for (String groupCode : groupCodes) + if (globalSpaces != null && globalSpaces.isEmpty() == false) { - try - { - Context context = new Context(sessionToken); - if (usersByGroupCodes.containsKey(groupCode)) - { - manageKnownGroup(context, groupCode, report); - } else - { - manageNewGroup(context, groupCode, report); - } - context.executeOperations(); - } catch (Exception e) - { - String message = String.format("Couldn't manage group '%s' because of the following error: %s", - groupCode, e); - report.addErrorMessage(message); - logger.log(LogLevel.ERROR, message, e); - } + createGlobalSpaces(sessionToken, report); + Set<String> knownGlobalSpaces = createGlobalGroupAndGetKnownSpaces(sessionToken, GLOBAL_AUTHORIZATION_GROUP_ID, report); + createGlobalRoleAssignments(sessionToken, GLOBAL_AUTHORIZATION_GROUP_ID, knownGlobalSpaces, report); } } - private void manageUsers(String sessionToken, UserManagerReport report) + private void createGlobalSpaces(String sessionToken, UserManagerReport report) { - revokeUsersUnkownByAuthenticationService(sessionToken, report); - Map<IPersonId, Person> users = getUsersWithRoleAssigments(sessionToken); - Map<String, Set<String>> currentUsersByGroupCodes = getUsersByGroupCodes(sessionToken); - Map<String, Set<String>> currentAdminUsersByGroupCodes = getAdminUsersByGroupCodes(sessionToken); - for (UserInfo userInfo : userInfosByUserId.values()) + List<SpacePermId> spaceIds = globalSpaces.stream().map(SpacePermId::new).collect(Collectors.toList()); + Set<ISpaceId> knownSpaces = service.getSpaces(sessionToken, spaceIds, new SpaceFetchOptions()).keySet(); + List<SpaceCreation> spaceCreations = new ArrayList<>(); + for (SpacePermId spaceId : spaceIds) { - try + if (knownSpaces.contains(spaceId) == false) { - manageUser(sessionToken, userInfo, users, currentUsersByGroupCodes, currentAdminUsersByGroupCodes, report); - } catch (Exception e) - { - String message = String.format("Couldn't manage user '%s' because of the following error: %s", - userInfo.getPrincipal().getUserId(), e); - report.addErrorMessage(message); - logger.log(LogLevel.ERROR, message, e); + SpaceCreation spaceCreation = new SpaceCreation(); + spaceCreation.setCode(spaceId.getPermId()); + spaceCreations.add(spaceCreation); } } + if (spaceCreations.isEmpty() == false) + { + service.createSpaces(sessionToken, spaceCreations); + report.addSpaces(spaceCreations); + } + } - for (String groupCode : currentUsersByGroupCodes.keySet()) + private Set<String> createGlobalGroupAndGetKnownSpaces(String sessionToken, AuthorizationGroupPermId groupId, UserManagerReport report) + { + AuthorizationGroupFetchOptions fetchOptions = new AuthorizationGroupFetchOptions(); + fetchOptions.withRoleAssignments().withSpace(); + AuthorizationGroup group = service.getAuthorizationGroups(sessionToken, Arrays.asList(groupId), fetchOptions).get(groupId); + Set<String> knownGlobalSpaces = new TreeSet<>(); + if (group == null) { - try - { - manageUsersRemovedFromGroup(sessionToken, groupCode, currentUsersByGroupCodes, - currentAdminUsersByGroupCodes, report); - } catch (Exception e) + AuthorizationGroupCreation groupCreation = new AuthorizationGroupCreation(); + groupCreation.setCode(GLOBAL_AUTHORIZATION_GROUP_CODE); + groupCreation.setDescription("Authorization group for all users of all groups"); + service.createAuthorizationGroups(sessionToken, Arrays.asList(groupCreation)); + report.addGroup(GLOBAL_AUTHORIZATION_GROUP_CODE); + } else + { + for (RoleAssignment roleAssignment : group.getRoleAssignments()) { - String message = String.format("Couldn't manage users removed from group %s because of the following error: %s", - groupCode, e); - report.addErrorMessage(message); - logger.log(LogLevel.ERROR, message, e); + if (RoleLevel.SPACE.equals(roleAssignment.getRoleLevel()) && Role.OBSERVER.equals(roleAssignment.getRole())) + { + knownGlobalSpaces.add(roleAssignment.getSpace().getCode()); + } } } + return knownGlobalSpaces; } - private void manageUsersRemovedFromGroup(String sessionToken, String groupCode, Map<String, Set<String>> currentUsersByGroupCodes, - Map<String, Set<String>> currentAdminUsersByGroupCodes, UserManagerReport report) + private void createGlobalRoleAssignments(String sessionToken, AuthorizationGroupPermId groupId, Set<String> knownGlobalSpaces, + UserManagerReport report) { - Set<String> currentUsers = currentUsersByGroupCodes.get(groupCode); - Set<String> newUsers = usersByGroupCode.get(groupCode).keySet(); - Context context = new Context(sessionToken); - for (String currentUser : currentUsers) + List<RoleAssignmentCreation> assignmentCreations = new ArrayList<>(); + for (String spaceCode : globalSpaces) { - if (newUsers.contains(currentUser) == false) + if (knownGlobalSpaces.contains(spaceCode) == false) { - removePersonFromAuthorizationGroup(context, currentUsersByGroupCodes, groupCode, currentUser, report); - String adminGroupCode = createAdminGroupCode(groupCode); - removePersonFromAuthorizationGroup(context, currentAdminUsersByGroupCodes, adminGroupCode, currentUser, report); + RoleAssignmentCreation assignmentCreation = new RoleAssignmentCreation(); + assignmentCreation.setAuthorizationGroupId(groupId); + assignmentCreation.setRole(Role.OBSERVER); + SpacePermId spaceId = new SpacePermId(spaceCode); + assignmentCreation.setSpaceId(spaceId); + assignmentCreations.add(assignmentCreation); + report.assignRoleTo(groupId, assignmentCreation.getRole(), spaceId); } } - context.executeOperations(); + if (assignmentCreations.isEmpty() == false) + { + service.createRoleAssignments(sessionToken, assignmentCreations); + } } private void revokeUsersUnkownByAuthenticationService(String sessionToken, UserManagerReport report) { List<PersonUpdate> updates = new ArrayList<>(); - List<Person> persons = service.searchPersons(sessionToken, new PersonSearchCriteria(), new PersonFetchOptions()).getObjects(); + PersonSearchCriteria searchCriteria = new PersonSearchCriteria(); + PersonFetchOptions fetchOptions = new PersonFetchOptions(); + List<Person> persons = service.searchPersons(sessionToken, searchCriteria, fetchOptions).getObjects(); for (Person person : persons) { if (person.isActive()) @@ -240,19 +282,79 @@ public class UserManager } } - private void manageKnownGroup(Context context, String groupCode, UserManagerReport report) + private CurrentState loadCurrentState(String sessionToken, IApplicationServerInternalApi service) + { + List<AuthorizationGroup> authorizationGroups = getAllAuthorizationGroups(sessionToken, service); + List<Person> users = getAllUsers(sessionToken, service); + List<Space> spaces = getAllSpaces(sessionToken, service); + List<AuthorizationGroupPermId> ids = Arrays.asList(GLOBAL_AUTHORIZATION_GROUP_ID); + AuthorizationGroupFetchOptions fetchOptions = new AuthorizationGroupFetchOptions(); + fetchOptions.withRoleAssignments().withSpace(); + fetchOptions.withUsers(); + AuthorizationGroup group = service.getAuthorizationGroups(sessionToken, ids, fetchOptions).get(GLOBAL_AUTHORIZATION_GROUP_ID); + return new CurrentState(authorizationGroups, group, spaces, users); + } + + private List<AuthorizationGroup> getAllAuthorizationGroups(String sessionToken, IApplicationServerInternalApi service) + { + AuthorizationGroupSearchCriteria searchCriteria = new AuthorizationGroupSearchCriteria(); + AuthorizationGroupFetchOptions fetchOptions = new AuthorizationGroupFetchOptions(); + fetchOptions.withUsers().withSpace(); + fetchOptions.withRoleAssignments().withSpace(); + return service.searchAuthorizationGroups(sessionToken, searchCriteria, fetchOptions).getObjects(); + } + + private List<Person> getAllUsers(String sessionToken, IApplicationServerInternalApi service) + { + PersonSearchCriteria searchCriteria = new PersonSearchCriteria(); + PersonFetchOptions fetchOptions = new PersonFetchOptions(); + fetchOptions.withRoleAssignments().withSpace(); + fetchOptions.withSpace(); + return service.searchPersons(sessionToken, searchCriteria, fetchOptions).getObjects(); + } + + private List<Space> getAllSpaces(String sessionToken, IApplicationServerInternalApi service) + { + SpaceSearchCriteria searchCriteria = new SpaceSearchCriteria(); + SpaceFetchOptions fetchOptions = new SpaceFetchOptions(); + return service.searchSpaces(sessionToken, searchCriteria, fetchOptions).getObjects(); + } + + private void manageGroup(String sessionToken, String groupCode, Map<String, Principal> groupUsers, + CurrentState currentState, UserManagerReport report) + { + try + { + Context context = new Context(sessionToken, service, currentState, report); + if (currentState.groupExists(groupCode)) + { + manageKnownGroup(context, groupCode, groupUsers); + } else + { + manageNewGroup(context, groupCode, groupUsers); + } + context.executeOperations(); + } catch (Exception e) + { + String message = String.format("Couldn't manage group '%s' because of the following error: %s", + groupCode, e); + report.addErrorMessage(message); + logger.log(LogLevel.ERROR, message, e); + } + } + + private void manageKnownGroup(Context context, String groupCode, Map<String, Principal> groupUsers) { - // TODO Auto-generated method stub + manageUsers(context, groupCode, groupUsers); } - private void manageNewGroup(Context context, String groupCode, UserManagerReport report) + private void manageNewGroup(Context context, String groupCode, Map<String, Principal> groupUsers) { String adminGroupCode = createAdminGroupCode(groupCode); - assertAuthorizationGroupDoesNotExist(context, adminGroupCode); assertNoCommonSpaceExists(context, groupCode); - createAuthorizationGroup(context, groupCode, report); - createAuthorizationGroup(context, adminGroupCode, report); + AuthorizationGroupPermId groupId = createAuthorizationGroup(context, groupCode); + AuthorizationGroupPermId adminGroupId = createAuthorizationGroup(context, adminGroupCode); for (Entry<Role, List<String>> entry : commonSpacesByRole.entrySet()) { @@ -260,22 +362,163 @@ public class UserManager for (String space : entry.getValue()) { ISpaceId spaceId = createSpace(context, createCommonSpaceCode(groupCode, space)); - report.addSpace(spaceId); - createRoleAssignment(context, new AuthorizationGroupPermId(groupCode), role, spaceId, report); - createRoleAssignment(context, new AuthorizationGroupPermId(adminGroupCode), Role.ADMIN, spaceId, report); + createRoleAssignment(context, groupId, role, spaceId); + createRoleAssignment(context, adminGroupId, Role.ADMIN, spaceId); } } + + manageUsers(context, groupCode, groupUsers); } - private void assertAuthorizationGroupDoesNotExist(Context context, String adminGroup) + private void manageUsers(Context context, String groupCode, Map<String, Principal> groupUsers) { - if (service.getAuthorizationGroups(context.getSessionToken(), Arrays.asList(new AuthorizationGroupPermId(adminGroup)), - new AuthorizationGroupFetchOptions()).isEmpty() == false) + Map<String, Person> currentUsersOfGroup = context.currentState.getCurrentUsersOfGroup(groupCode); + Set<String> usersToBeRemoved = new TreeSet<>(currentUsersOfGroup.keySet()); + AuthorizationGroup globalGroup = context.currentState.getGlobalGroup(); + String adminGroupCode = createAdminGroupCode(groupCode); + AuthorizationGroupPermId adminGroupId = new AuthorizationGroupPermId(adminGroupCode); + for (Principal user : groupUsers.values()) { - throw new IllegalStateException("Authorization group " + adminGroup + " already exists."); + String userId = user.getUserId(); + usersToBeRemoved.remove(userId); + PersonPermId personId = new PersonPermId(userId); + if (currentUsersOfGroup.containsKey(userId) == false) + { + ISpaceId userSpaceId = createUserSpace(context, groupCode, userId); + Person knownUser = context.getCurrentState().getUser(userId); + if (context.getCurrentState().userExists(userId) == false) + { + PersonCreation personCreation = new PersonCreation(); + personCreation.setUserId(userId); + context.add(personCreation); + context.getCurrentState().addNewUser(userId); + context.getReport().addUser(userId); + assignHomeSpace(context, personId, userSpaceId); + } else if (knownUser != null) + { + if (knownUser.isActive() == false) + { + context.getReport().reuseUser(userId); + } + if (knownUser.getSpace() == null || knownUser.isActive() == false) + { + assignHomeSpace(context, personId, userSpaceId); + } + } + RoleAssignmentCreation roleCreation = new RoleAssignmentCreation(); + roleCreation.setUserId(personId); + roleCreation.setRole(Role.ADMIN); + roleCreation.setSpaceId(userSpaceId); + context.add(roleCreation); + createRoleAssignment(context, adminGroupId, Role.ADMIN, userSpaceId); + } + addPersonToAuthorizationGroup(context, groupCode, userId); + if (globalGroup != null) + { + addPersonToAuthorizationGroup(context, globalGroup.getCode(), userId); + } + if (isAdmin(userId, groupCode)) + { + addPersonToAuthorizationGroup(context, adminGroupCode, userId); + } else + { + removePersonFromAuthorizationGroup(context, adminGroupCode, userId); + } + } + removeUsersFromGroup(context, groupCode, usersToBeRemoved); + } + + private void removeUsersFromGroup(Context context, String groupCode, Set<String> usersToBeRemoved) + { + String adminGroupCode = createAdminGroupCode(groupCode); + Map<String, RoleAssignment> spaceRoles = context.currentState.getCurrentSpaceRolesOfGroup(adminGroupCode); + for (String user : usersToBeRemoved) + { + removePersonFromAuthorizationGroup(context, groupCode, user); + removePersonFromAuthorizationGroup(context, adminGroupCode, user); + for (RoleAssignment role : spaceRoles.values()) + { + if (role.getSpace().getCode().startsWith(groupCode + "_" + user)) + { + context.delete(role.getId()); + } + } } } + private ISpaceId createUserSpace(Context context, String groupCode, String userId) + { + String userSpaceCode = createCommonSpaceCode(groupCode, userId.toUpperCase()); + int n = context.getCurrentState().getNumberOfSpacesStartingWith(userSpaceCode); + if (n > 0) + { + userSpaceCode += "_" + (n + 1); + } + return createSpace(context, userSpaceCode); + } + + private void assignHomeSpace(Context context, PersonPermId personId, ISpaceId homeSpaceId) + { + PersonUpdate personUpdate = new PersonUpdate(); + personUpdate.setUserId(personId); + personUpdate.setSpaceId(homeSpaceId); + context.add(personUpdate); + } + + private boolean isAdmin(String userId, String groupCode) + { + UserInfo userInfo = userInfosByUserId.get(userId); + if (userInfo == null) + { + return false; + } + GroupInfo groupInfo = userInfo.getGroupInfosByGroupKey().get(groupCode); + return groupInfo != null && groupInfo.isAdmin(); + } + + private void addPersonToAuthorizationGroup(Context context, String groupCode, String userId) + { + if (context.currentState.getCurrentUsersOfGroup(groupCode).keySet().contains(userId) == false) + { + AuthorizationGroupUpdate groupUpdate = new AuthorizationGroupUpdate(); + groupUpdate.setAuthorizationGroupId(new AuthorizationGroupPermId(groupCode)); + groupUpdate.getUserIds().add(new PersonPermId(userId)); + context.add(groupUpdate); + context.getReport().addUserToGroup(groupCode, userId); + } + } + + private void removePersonFromAuthorizationGroup(Context context, String groupCode, String userId) + { + if (context.currentState.getCurrentUsersOfGroup(groupCode).keySet().contains(userId)) + { + AuthorizationGroupUpdate groupUpdate = new AuthorizationGroupUpdate(); + groupUpdate.setAuthorizationGroupId(new AuthorizationGroupPermId(groupCode)); + groupUpdate.getUserIds().remove(new PersonPermId(userId)); + context.add(groupUpdate); + context.getReport().removeUserFromGroup(groupCode, userId); + } + } + + private AuthorizationGroupPermId createAuthorizationGroup(Context context, String groupCode) + { + AuthorizationGroupCreation creation = new AuthorizationGroupCreation(); + creation.setCode(groupCode); + context.add(creation); + context.getReport().addGroup(groupCode); + return new AuthorizationGroupPermId(groupCode); + } + + private void createRoleAssignment(Context context, AuthorizationGroupPermId groupId, Role role, ISpaceId spaceId) + { + RoleAssignmentCreation roleCreation = new RoleAssignmentCreation(); + roleCreation.setAuthorizationGroupId(groupId); + roleCreation.setRole(role); + roleCreation.setSpaceId(spaceId); + context.add(roleCreation); + context.getReport().assignRoleTo(groupId, role, spaceId); + } + private void assertNoCommonSpaceExists(Context context, String groupCode) { Set<String> commonSpaces = new TreeSet<>(); @@ -293,82 +536,270 @@ public class UserManager throw new IllegalStateException("The group '" + groupCode + "' has already the following spaces: " + existingSpaces); } + private static final class CurrentState + { + private Map<String, AuthorizationGroup> groupsByCode = new TreeMap<>(); + + private Map<String, Space> spacesByCode = new TreeMap<>(); + + private Map<String, Person> usersById = new TreeMap<>(); + + private Set<String> newUsers = new TreeSet<>(); + + private AuthorizationGroup globalGroup; + + CurrentState(List<AuthorizationGroup> authorizationGroups, AuthorizationGroup globalGroup, List<Space> spaces, List<Person> users) + { + this.globalGroup = globalGroup; + authorizationGroups.forEach(group -> groupsByCode.put(group.getCode(), group)); + groupsByCode.put(GLOBAL_AUTHORIZATION_GROUP_CODE, globalGroup); + spaces.forEach(space -> spacesByCode.put(space.getCode(), space)); + users.forEach(user -> usersById.put(user.getUserId(), user)); + } + + public Map<String, RoleAssignment> getCurrentSpaceRolesOfGroup(String groupCode) + { + Map<String, RoleAssignment> result = new TreeMap<>(); + AuthorizationGroup group = groupsByCode.get(groupCode); + if (group != null) + { + List<RoleAssignment> roleAssignments = group.getRoleAssignments(); + for (RoleAssignment roleAssignment : roleAssignments) + { + if (RoleLevel.SPACE.equals(roleAssignment.getRoleLevel()) && Role.OBSERVER.equals(roleAssignment.getRole())) + { + Space space = roleAssignment.getSpace(); + result.put(space.getCode(), roleAssignment); + } + } + } + return result; + } + + public Map<String, Person> getCurrentUsersOfGroup(String groupCode) + { + Map<String, Person> result = new TreeMap<>(); + AuthorizationGroup group = groupsByCode.get(groupCode); + if (group != null) + { + group.getUsers().forEach(user -> result.put(user.getUserId(), user)); + } + return result; + } + + public AuthorizationGroup getGlobalGroup() + { + return globalGroup; + } + + public boolean userExists(String userId) + { + return newUsers.contains(userId) || usersById.containsKey(userId); + } + + public int getNumberOfSpacesStartingWith(String userSpaceCode) + { + Predicate<String> predicate = code -> code.startsWith(userSpaceCode); + return spacesByCode.keySet().stream().filter(predicate).collect(Collectors.counting()).intValue(); + } + + public Person getUser(String userId) + { + return usersById.get(userId); + } + + public boolean groupExists(String groupCode) + { + boolean groupExists = groupsByCode.containsKey(groupCode); + String adminGroupCode = createAdminGroupCode(groupCode); + boolean adminGroupExists = groupsByCode.containsKey(adminGroupCode); + if (groupExists) + { + if (adminGroupExists == false) + { + throw new IllegalArgumentException("Group " + groupCode + " exists but not " + adminGroupCode); + } + return true; + } + if (adminGroupExists) + { + throw new IllegalArgumentException("Group " + groupCode + " does not exist but " + adminGroupCode); + } + return false; + } + + public void addNewUser(String userId) + { + newUsers.add(userId); + } + } + + private void manageUsers(String sessionToken, Map<IPersonId, Person> currentUsers, UserManagerReport report) + { + Map<String, UsersAndRoleAssignments> currentUsersAndSpacesByGroupCodes = getUsersAndSpacesByGroupCodes(sessionToken); + Map<String, UsersAndRoleAssignments> currentUsersAndSpacesByAdminGroupCodes = getUsersAndSpacesByAdminGroupCodes(sessionToken); + for (UserInfo userInfo : userInfosByUserId.values()) + { + try + { + manageUser(sessionToken, userInfo, currentUsers, currentUsersAndSpacesByGroupCodes, currentUsersAndSpacesByAdminGroupCodes, report); + } catch (Exception e) + { + String message = String.format("Couldn't manage user '%s' because of the following error: %s", + userInfo.getPrincipal().getUserId(), e); + report.addErrorMessage(message); + logger.log(LogLevel.ERROR, message, e); + } + } + + for (String groupCode : currentUsersAndSpacesByGroupCodes.keySet()) + { + try + { + manageUsersRemovedFromGroup(sessionToken, groupCode, currentUsersAndSpacesByGroupCodes, + currentUsersAndSpacesByAdminGroupCodes, report); + } catch (Exception e) + { + String message = String.format("Couldn't manage users removed from group %s because of the following error: %s", + groupCode, e); + report.addErrorMessage(message); + logger.log(LogLevel.ERROR, message, e); + } + } + } + + private void manageUsersRemovedFromGroup(String sessionToken, String groupCode, + Map<String, UsersAndRoleAssignments> currentUsersAndSpacesByGroupCodes, + Map<String, UsersAndRoleAssignments> currentUsersAndSpacesByAdminGroupCodes, + UserManagerReport report) + { + Set<String> currentUsers = currentUsersAndSpacesByGroupCodes.get(groupCode).users; + Set<String> newUsers = usersByGroupCode.get(groupCode).keySet(); + Context context = new Context(sessionToken, service, null, report); + for (String currentUser : currentUsers) + { + if (newUsers.contains(currentUser) == false) + { + removePersonFromAuthorizationGroup(context, currentUsersAndSpacesByGroupCodes, groupCode, currentUser, report); + String adminGroupCode = createAdminGroupCode(groupCode); + removePersonFromAuthorizationGroup(context, currentUsersAndSpacesByAdminGroupCodes, adminGroupCode, currentUser, report); + } + } + context.executeOperations(); + } + + private void manageKnownGroup(Context context, String groupCode, Map<IPersonId, Person> currentUsers, UserManagerReport report) + { + String adminGroupCode = createAdminGroupCode(groupCode); + Map<String, UsersAndRoleAssignments> usersAndSpacesByAdminGroupCodes = getUsersAndSpacesByAdminGroupCodes(context.getSessionToken()); + UsersAndRoleAssignments usersAndSpaces = usersAndSpacesByAdminGroupCodes.get(adminGroupCode); + Collection<Principal> users = usersByGroupCode.get(groupCode).values(); + if (usersAndSpaces != null && users != null) + { + for (Principal user : users) + { + String userId = user.getUserId(); + Person knownUser = currentUsers.get(new PersonPermId(userId)); + if (knownUser != null) + { + Space homeSpace = knownUser.getSpace(); + if (homeSpace != null) + { + RoleAssignment roleAssignment = usersAndSpaces.getRoleAssignment(homeSpace.getCode()); + if (roleAssignment != null) + { + context.delete(roleAssignment.getId()); + report.unassignRoleFrom(new AuthorizationGroupPermId(adminGroupCode), Role.ADMIN, homeSpace.getPermId()); + } + } + } + } + } + } + + private void assertAuthorizationGroupDoesNotExist(Context context, String adminGroup) + { + if (service.getAuthorizationGroups(context.getSessionToken(), Arrays.asList(new AuthorizationGroupPermId(adminGroup)), + new AuthorizationGroupFetchOptions()).isEmpty() == false) + { + throw new IllegalStateException("Authorization group " + adminGroup + " already exists."); + } + } + private void manageUser(String sessionToken, UserInfo userInfo, Map<IPersonId, Person> knownUsers, - Map<String, Set<String>> currentUsersByGroupCodes, Map<String, Set<String>> currentAdminUsersByGroupCodes, + Map<String, UsersAndRoleAssignments> currentUsersAndSpacesByGroupCodes, + Map<String, UsersAndRoleAssignments> currentUsersAndSpacesByAdminGroupCodes, UserManagerReport report) { - Context context = new Context(sessionToken); + Context context = new Context(sessionToken, service, null, report); Person knownUser = knownUsers.get(new PersonPermId(userInfo.getPrincipal().getUserId())); if (knownUser != null) { - manageKnownUser(context, userInfo, knownUser, currentUsersByGroupCodes, currentAdminUsersByGroupCodes, report); + manageKnownUser(context, userInfo, knownUser, currentUsersAndSpacesByGroupCodes, + currentUsersAndSpacesByAdminGroupCodes, report); } else { manageNewUser(context, userInfo, userInfo.getPrincipal().getUserId().toUpperCase(), - currentUsersByGroupCodes, currentAdminUsersByGroupCodes, report); + currentUsersAndSpacesByGroupCodes, currentUsersAndSpacesByAdminGroupCodes, report); } context.executeOperations(); } private void manageKnownUser(Context context, UserInfo userInfo, Person knownUser, - Map<String, Set<String>> currentUsersByGroupCodes, Map<String, Set<String>> currentAdminUsersByGroupCodes, + Map<String, UsersAndRoleAssignments> currentUsersAndSpacesByGroupCodes, + Map<String, UsersAndRoleAssignments> currentUsersAndSpacesByAdminGroupCodes, UserManagerReport report) { + int numberOfHomeSpaces = getNumberOfHomeSpaces(context, knownUser); if (knownUser.isActive() == false) { - int maxSequenceNumber = getMaxSequenceNumber(context, knownUser); - String homeSpaceCode = knownUser.getUserId() + "_" + (maxSequenceNumber + 1); - manageNewUser(context, userInfo, homeSpaceCode, currentUsersByGroupCodes, currentAdminUsersByGroupCodes, report); + String homeSpaceCode = knownUser.getUserId().toUpperCase() + "_" + (numberOfHomeSpaces + 1); + manageNewUser(context, userInfo, homeSpaceCode, currentUsersAndSpacesByGroupCodes, + currentUsersAndSpacesByAdminGroupCodes, report); } else { String userId = userInfo.principal.getUserId(); for (GroupInfo groupInfo : userInfo.getGroupInfosByGroupKey().values()) { String groupCode = groupInfo.getKey(); - addPersonToAuthorizationGroup(context, currentUsersByGroupCodes, groupCode, userId, report); + addPersonToAuthorizationGroup(context, currentUsersAndSpacesByGroupCodes, groupCode, userId, report); String adminGroupCode = createAdminGroupCode(groupCode); + String homeSpaceCode = knownUser.getUserId().toUpperCase() + (numberOfHomeSpaces > 1 ? "_" + numberOfHomeSpaces : ""); + UsersAndRoleAssignments usersAndSpaces = currentUsersAndSpacesByAdminGroupCodes.get(adminGroupCode); + if (usersAndSpaces != null && usersAndSpaces.getRoleAssignment(homeSpaceCode) == null) + { + AuthorizationGroupPermId adminGroupId = new AuthorizationGroupPermId(adminGroupCode); + SpacePermId homeSpaceId = new SpacePermId(homeSpaceCode); + createRoleAssignment(context, adminGroupId, Role.ADMIN, homeSpaceId); + } if (groupInfo.isAdmin()) { - addPersonToAuthorizationGroup(context, currentAdminUsersByGroupCodes, adminGroupCode, userId, report); - } else if (isCurrentAdminUser(currentAdminUsersByGroupCodes, adminGroupCode, userId)) + addPersonToAuthorizationGroup(context, currentUsersAndSpacesByAdminGroupCodes, adminGroupCode, userId, report); + } else if (isCurrentAdminUser(currentUsersAndSpacesByAdminGroupCodes, adminGroupCode, userId)) { - removePersonFromAuthorizationGroup(context, currentAdminUsersByGroupCodes, adminGroupCode, userId, report); + removePersonFromAuthorizationGroup(context, currentUsersAndSpacesByAdminGroupCodes, adminGroupCode, userId, report); } } } } - private int getMaxSequenceNumber(Context context, Person knownUser) + private int getNumberOfHomeSpaces(Context context, Person knownUser) { - PersonSearchCriteria searchCriteria = new PersonSearchCriteria(); - searchCriteria.withUserId().thatStartsWith(knownUser.getUserId()); - PersonFetchOptions fetchOptions = new PersonFetchOptions(); - int maxSequenceNumber = 0; - for (Person person : service.searchPersons(context.getSessionToken(), searchCriteria, fetchOptions).getObjects()) - { - String[] splittedUserId = person.getUserId().split("_"); - if (splittedUserId.length == 2) - { - try - { - maxSequenceNumber = Math.max(maxSequenceNumber, Integer.parseInt(splittedUserId[1])); - } catch (NumberFormatException e) - { - // silently ignored - } - } - } - return maxSequenceNumber; + SpaceSearchCriteria searchCriteria = new SpaceSearchCriteria(); + searchCriteria.withCode().thatStartsWith(knownUser.getUserId().toUpperCase()); + return service.searchSpaces(context.getSessionToken(), searchCriteria, new SpaceFetchOptions()).getTotalCount(); } - private boolean isCurrentAdminUser(Map<String, Set<String>> currentAdminUsersByGroupCodes, String groupCode, String userId) + private boolean isCurrentAdminUser(Map<String, UsersAndRoleAssignments> currentUsersAndSpacesByAdminGroupCodes, + String groupCode, String userId) { - Set<String> users = currentAdminUsersByGroupCodes.get(groupCode); + Set<String> users = currentUsersAndSpacesByAdminGroupCodes.get(groupCode).users; return users == null ? false : users.contains(userId); } private void manageNewUser(Context context, UserInfo userInfo, String homeSpaceCode, - Map<String, Set<String>> currentUsersByGroupCodes, Map<String, Set<String>> currentAdminUsersByGroupCodes, + Map<String, UsersAndRoleAssignments> currentUsersAndSpacesByGroupCodes, + Map<String, UsersAndRoleAssignments> currentUsersAndSpacesByAdminGroupCodes, UserManagerReport report) { String userId = userInfo.getPrincipal().getUserId(); @@ -383,12 +814,12 @@ public class UserManager for (GroupInfo groupInfo : userInfo.getGroupInfosByGroupKey().values()) { String groupCode = groupInfo.getKey(); - addPersonToAuthorizationGroup(context, currentUsersByGroupCodes, groupCode, userId, report); + addPersonToAuthorizationGroup(context, currentUsersAndSpacesByGroupCodes, groupCode, userId, report); String adminGroupCode = createAdminGroupCode(groupCode); - createRoleAssignment(context, new AuthorizationGroupPermId(adminGroupCode), Role.ADMIN, homeSpaceId, report); + createRoleAssignment(context, new AuthorizationGroupPermId(adminGroupCode), Role.ADMIN, homeSpaceId); if (groupInfo.isAdmin()) { - addPersonToAuthorizationGroup(context, currentAdminUsersByGroupCodes, adminGroupCode, userId, report); + addPersonToAuthorizationGroup(context, currentUsersAndSpacesByAdminGroupCodes, adminGroupCode, userId, report); } } } @@ -402,15 +833,12 @@ public class UserManager PersonCreation personCreation = new PersonCreation(); personCreation.setUserId(userId); context.add(personCreation); - report.addUser(userId, homeSpaceId); + report.addUser(userId); } else { - report.reuseUser(userId, homeSpaceId); + report.reuseUser(userId); } - PersonUpdate personUpdate = new PersonUpdate(); - personUpdate.setUserId(personPermId); - personUpdate.setSpaceId(homeSpaceId); - context.add(personUpdate); + assignHomeSpace(context, personPermId, homeSpaceId); RoleAssignmentCreation roleCreation = new RoleAssignmentCreation(); roleCreation.setUserId(personPermId); roleCreation.setRole(Role.ADMIN); @@ -418,10 +846,11 @@ public class UserManager context.add(roleCreation); } - private void addPersonToAuthorizationGroup(Context context, Map<String, Set<String>> currentUsersByGroupCodes, + private void addPersonToAuthorizationGroup(Context context, + Map<String, UsersAndRoleAssignments> currentUsersAndSpacesByGroupCodes, String groupCode, String userId, UserManagerReport report) { - Set<String> users = currentUsersByGroupCodes.get(groupCode); + Set<String> users = currentUsersAndSpacesByGroupCodes.get(groupCode).users; if (users == null || users.contains(userId) == false) { AuthorizationGroupUpdate groupUpdate = new AuthorizationGroupUpdate(); @@ -432,10 +861,11 @@ public class UserManager } } - private void removePersonFromAuthorizationGroup(Context context, Map<String, Set<String>> currentUsersByGroupCodes, + private void removePersonFromAuthorizationGroup(Context context, + Map<String, UsersAndRoleAssignments> currentUsersAndSpacesByGroupCodes, String groupCode, String userId, UserManagerReport report) { - Set<String> users = currentUsersByGroupCodes.get(groupCode); + Set<String> users = currentUsersAndSpacesByGroupCodes.get(groupCode).users; if (users == null || users.contains(userId)) { AuthorizationGroupUpdate groupUpdate = new AuthorizationGroupUpdate(); @@ -446,31 +876,21 @@ public class UserManager } } - private ISpaceId createSpace(Context context, String spaceCode) + private void removeSpaceAdminRoleFromAuthorizationGroup(Context context, String groupCode, String userId, UserManagerReport report) { - SpaceCreation spaceCreation = new SpaceCreation(); - spaceCreation.setCode(spaceCode); - context.add(spaceCreation); - return new SpacePermId(spaceCode); - } - private void createAuthorizationGroup(Context context, String groupCode, UserManagerReport report) - { - AuthorizationGroupCreation creation = new AuthorizationGroupCreation(); - creation.setCode(groupCode); - context.add(creation); - report.addGroup(groupCode); + AuthorizationGroupUpdate groupUpdate = new AuthorizationGroupUpdate(); + groupUpdate.setAuthorizationGroupId(new AuthorizationGroupPermId(groupCode)); } - private void createRoleAssignment(Context context, AuthorizationGroupPermId groupId, Role role, ISpaceId spaceId, - UserManagerReport report) + private ISpaceId createSpace(Context context, String spaceCode) { - RoleAssignmentCreation roleCreation = new RoleAssignmentCreation(); - roleCreation.setAuthorizationGroupId(groupId); - roleCreation.setRole(role); - roleCreation.setSpaceId(spaceId); - context.add(roleCreation); - report.assignRoleTo(groupId, role, spaceId); + SpaceCreation spaceCreation = new SpaceCreation(); + spaceCreation.setCode(spaceCode); + context.add(spaceCreation); + SpacePermId spaceId = new SpacePermId(spaceCode); + context.getReport().addSpace(spaceId); + return spaceId; } private String createCommonSpaceCode(String groupCode, String spaceCode) @@ -499,31 +919,35 @@ public class UserManager Function<String, PersonPermId> mapper = userId -> new PersonPermId(userId); List<PersonPermId> userIds = userInfosByUserId.keySet().stream().map(mapper).collect(Collectors.toList()); PersonFetchOptions fetchOptions = new PersonFetchOptions(); + fetchOptions.withSpace(); fetchOptions.withRoleAssignments().withSpace(); Map<IPersonId, Person> users = service.getPersons(sessionToken, userIds, fetchOptions); return users; } - private Map<String, Set<String>> getUsersByGroupCodes(String sessionToken) + private Map<String, UsersAndRoleAssignments> getUsersAndSpacesByGroupCodes(String sessionToken) { - return getUsersByGroupCodes(sessionToken, groupCode -> new AuthorizationGroupPermId(groupCode)); + return getUsersAndSpacesByGroupCodes(sessionToken, groupCode -> new AuthorizationGroupPermId(groupCode)); } - private Map<String, Set<String>> getAdminUsersByGroupCodes(String sessionToken) + private Map<String, UsersAndRoleAssignments> getUsersAndSpacesByAdminGroupCodes(String sessionToken) { - return getUsersByGroupCodes(sessionToken, groupCode -> createAdminGroupId(groupCode)); + return getUsersAndSpacesByGroupCodes(sessionToken, groupCode -> createAdminGroupId(groupCode)); } - private Map<String, Set<String>> getUsersByGroupCodes(String sessionToken, Function<String, AuthorizationGroupPermId> mapper) + private Map<String, UsersAndRoleAssignments> getUsersAndSpacesByGroupCodes(String sessionToken, Function<String, AuthorizationGroupPermId> mapper) { List<AuthorizationGroupPermId> groupPermIds = groupCodes.stream().map(mapper).collect(Collectors.toList()); AuthorizationGroupFetchOptions fetchOptions = new AuthorizationGroupFetchOptions(); fetchOptions.withUsers(); - Map<String, Set<String>> usersByGroupCodes = new TreeMap<>(); + fetchOptions.withRoleAssignments().withSpace(); + Map<String, UsersAndRoleAssignments> usersByGroupCodes = new TreeMap<>(); for (AuthorizationGroup group : service.getAuthorizationGroups(sessionToken, groupPermIds, fetchOptions).values()) { Set<String> users = group.getUsers().stream().map(Person::getUserId).collect(Collectors.toSet()); - usersByGroupCodes.put(group.getCode(), users); + List<RoleAssignment> roleAssignments = group.getRoleAssignments().stream() + .filter(ra -> ra.getSpace() != null).collect(Collectors.toList()); + usersByGroupCodes.put(group.getCode(), new UsersAndRoleAssignments(users, roleAssignments)); } return usersByGroupCodes; } @@ -593,14 +1017,40 @@ public class UserManager { return key + (admin ? "*" : ""); } + } + + private static final class UsersAndRoleAssignments + { + private Set<String> users; + + private Map<String, RoleAssignment> roleAssignmentsBySpace = new TreeMap<>(); + + UsersAndRoleAssignments(Set<String> users, List<RoleAssignment> roleAssignments) + { + this.users = users; + for (RoleAssignment roleAssignment : roleAssignments) + { + roleAssignmentsBySpace.put(roleAssignment.getSpace().getCode(), roleAssignment); + } + } + + RoleAssignment getRoleAssignment(String spaceCode) + { + return roleAssignmentsBySpace.get(spaceCode); + } + @Override + public String toString() + { + return "users: " + users + ", spaces: " + roleAssignmentsBySpace.keySet(); + } } - private final class Context + private static final class Context { private String sessionToken; - private List<PersonCreation> personCreations = new ArrayList<>(); + private Map<String, PersonCreation> personCreations = new LinkedMap<>(); private List<PersonUpdate> personUpdates = new ArrayList<>(); @@ -612,9 +1062,20 @@ public class UserManager private List<RoleAssignmentCreation> roleCreations = new ArrayList<>(); - Context(String sessionToken) + private List<IRoleAssignmentId> roleDeletions = new ArrayList<>(); + + private IApplicationServerInternalApi service; + + private CurrentState currentState; + + private UserManagerReport report; + + Context(String sessionToken, IApplicationServerInternalApi service, CurrentState currentState, UserManagerReport report) { this.sessionToken = sessionToken; + this.service = service; + this.currentState = currentState; + this.report = report; } public String getSessionToken() @@ -622,9 +1083,19 @@ public class UserManager return sessionToken; } + public CurrentState getCurrentState() + { + return currentState; + } + + public UserManagerReport getReport() + { + return report; + } + public void add(PersonCreation personCreation) { - personCreations.add(personCreation); + personCreations.put(personCreation.getUserId(), personCreation); } public void add(PersonUpdate personUpdate) @@ -652,12 +1123,17 @@ public class UserManager groupUpdates.add(groupUpdate); } + public void delete(IRoleAssignmentId roleAssignmentId) + { + roleDeletions.add(roleAssignmentId); + } + public void executeOperations() { List<IOperation> operations = new ArrayList<>(); if (personCreations.isEmpty() == false) { - operations.add(new CreatePersonsOperation(personCreations)); + operations.add(new CreatePersonsOperation(new ArrayList<>(personCreations.values()))); } if (personUpdates.isEmpty() == false) { @@ -679,6 +1155,12 @@ public class UserManager { operations.add(new CreateRoleAssignmentsOperation(roleCreations)); } + if (roleDeletions.isEmpty() == false) + { + RoleAssignmentDeletionOptions options = new RoleAssignmentDeletionOptions(); + options.setReason("Users removed from a group"); + operations.add(new DeleteRoleAssignmentsOperation(roleDeletions, options)); + } if (operations.isEmpty()) { return; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagerConfig.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagerConfig.java index 328c31e334d92c9ee547d42fa6c6ca55fca634fb..b5ca92f5e3f7c7c7f3312398c613773bdedfc3ad 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagerConfig.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagerConfig.java @@ -16,6 +16,7 @@ package ch.systemsx.cisd.openbis.generic.server.task; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -24,10 +25,24 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.Role; class UserManagerConfig { + private List<String> globalSpaces = new ArrayList<>(); + private Map<Role, List<String>> commonSpaces = new HashMap<>(); + private Map<String, String> commonSamples = new HashMap<>(); + private List<UserGroup> groups; + public List<String> getGlobalSpaces() + { + return globalSpaces; + } + + public void setGlobalSpaces(List<String> globalSpaces) + { + this.globalSpaces = globalSpaces; + } + public Map<Role, List<String>> getCommonSpaces() { return commonSpaces; @@ -38,6 +53,16 @@ class UserManagerConfig this.commonSpaces = commonSpaces; } + public Map<String, String> getCommonSamples() + { + return commonSamples; + } + + public void setCommonSamples(Map<String, String> commonSamples) + { + this.commonSamples = commonSamples; + } + public List<UserGroup> getGroups() { return groups; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagerReport.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagerReport.java index 9bf531d0b3b9f0c385d81a4254f484e4b705b99f..781e43affcccb36b26aa6ab1b4ae1a44ce4354b2 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagerReport.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagerReport.java @@ -18,9 +18,12 @@ package ch.systemsx.cisd.openbis.generic.server.task; import java.text.MessageFormat; import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.id.AuthorizationGroupPermId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.Role; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.create.SpaceCreation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.ISpaceId; import ch.systemsx.cisd.common.utilities.ITimeProvider; @@ -66,25 +69,35 @@ public class UserManagerReport log("DEACTIVATE-USER", userId); } - void addUser(String userId, ISpaceId homeSpaceId) + void addUser(String userId) { - log("ADD-USER", userId + " (home space: " + homeSpaceId + ")"); + log("ADD-USER", userId); } - public void reuseUser(String userId, ISpaceId homeSpaceId) + public void reuseUser(String userId) { - log("REUSE-USER", userId + " (home space: " + homeSpaceId + ")"); + log("REUSE-USER", userId); } void addSpace(ISpaceId spaceId) { log("ADD-SPACE", spaceId); } + + void addSpaces(List<SpaceCreation> spaceCreations) + { + log("ADD-SPACES", spaceCreations.stream().map(SpaceCreation::getCode).collect(Collectors.toList()).toString()); + } void assignRoleTo(AuthorizationGroupPermId groupId, Role role, ISpaceId spaceId) { log("ASSIGN-ROLE-TO-AUTHORIZATION-GROUP", "group: " + groupId + ", role: SPACE_" + role + " for " + spaceId); } + + public void unassignRoleFrom(AuthorizationGroupPermId groupId, Role role, ISpaceId spaceId) + { + log("UNASSIGN-ROLE-FORM-AUTHORIZATION-GROUP", "group: " + groupId + ", role: SPACE_" + role + " for " + spaceId); + } void addUserToGroup(String groupCode, String userId) { diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagementMaintenanceTaskTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagementMaintenanceTaskTest.java index 041db12c663789d9501aaa3f619947c00de95806..09585f13d9fa3ba808b1c10e46da462210b6c5fe 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagementMaintenanceTaskTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/task/UserManagementMaintenanceTaskTest.java @@ -32,7 +32,6 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.Role; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId; import ch.systemsx.cisd.authentication.Principal; import ch.systemsx.cisd.authentication.ldap.LDAPAuthenticationService; import ch.systemsx.cisd.authentication.ldap.LDAPDirectoryConfiguration; @@ -188,7 +187,9 @@ public class UserManagementMaintenanceTaskTest extends AbstractFileSystemTestCas + "INFO OPERATION.UserManagementMaintenanceTask - Plugin '' initialized. Configuration file: " + configFile.getAbsolutePath() + "\n" + "INFO OPERATION.UserManagementMaintenanceTask - manage 1 groups\n" + + "INFO OPERATION.UserManagementMaintenanceTask - Global spaces: []\n" + "INFO OPERATION.UserManagementMaintenanceTask - Common spaces: {}\n" + + "INFO OPERATION.UserManagementMaintenanceTask - Samples by type: {}\n" + "ERROR OPERATION.UserManagementMaintenanceTask - No ldapGroupKeys specified for group 'ABC'. Task aborted.", logRecorder.getLogContent()); } @@ -210,7 +211,9 @@ public class UserManagementMaintenanceTaskTest extends AbstractFileSystemTestCas + "INFO OPERATION.UserManagementMaintenanceTask - Plugin '' initialized. Configuration file: " + configFile.getAbsolutePath() + "\n" + "INFO OPERATION.UserManagementMaintenanceTask - manage 1 groups\n" + + "INFO OPERATION.UserManagementMaintenanceTask - Global spaces: []\n" + "INFO OPERATION.UserManagementMaintenanceTask - Common spaces: {}\n" + + "INFO OPERATION.UserManagementMaintenanceTask - Samples by type: {}\n" + "ERROR OPERATION.UserManagementMaintenanceTask - Empty ldapGroupKey for group 'ABC'. Task aborted.", logRecorder.getLogContent()); } @@ -232,7 +235,9 @@ public class UserManagementMaintenanceTaskTest extends AbstractFileSystemTestCas + "INFO OPERATION.UserManagementMaintenanceTask - Plugin '' initialized. Configuration file: " + configFile.getAbsolutePath() + "\n" + "INFO OPERATION.UserManagementMaintenanceTask - manage 1 groups\n" + + "INFO OPERATION.UserManagementMaintenanceTask - Global spaces: []\n" + "INFO OPERATION.UserManagementMaintenanceTask - Common spaces: {}\n" + + "INFO OPERATION.UserManagementMaintenanceTask - Samples by type: {}\n" + "ERROR OPERATION.UserManagementMaintenanceTask - No users found for ldapGroupKey 'a1' for group 'ABC'. Task aborted.", logRecorder.getLogContent()); } @@ -244,12 +249,13 @@ public class UserManagementMaintenanceTaskTest extends AbstractFileSystemTestCas UserManagerReport report = new UserManagerReport(new MockTimeProvider(0, 1000)); report.addErrorMessage("This is a test error message"); report.addGroup("blabla"); - report.addUser("a", new SpacePermId("A")); + report.addUser("a"); UserManagementMaintenanceTaskWithMocks task = new UserManagementMaintenanceTaskWithMocks().withGroup("s", U1) .withUserManagerReport(report); FileUtilities.writeToFile(configFile, ""); task.setUp("", properties); - FileUtilities.writeToFile(configFile, "{\"commonSpaces\":{\"USER\": [\"ALPHA\"]}," + FileUtilities.writeToFile(configFile, "{\"globalSpaces\":[\"ES\"],\"commonSpaces\":{\"USER\": [\"ALPHA\"]}," + + "\"commonSamples\":{\"A\":\"B\"}," + "\"groups\": [{\"name\":\"sis\",\"key\":\"SIS\",\"ldapGroupKeys\": [\"s\"],\"admins\": [\"u2\"]}]}"); // When @@ -260,7 +266,9 @@ public class UserManagementMaintenanceTaskTest extends AbstractFileSystemTestCas + "INFO OPERATION.UserManagementMaintenanceTask - Plugin '' initialized. Configuration file: " + configFile.getAbsolutePath() + "\n" + "INFO OPERATION.UserManagementMaintenanceTask - manage 1 groups\n" + + "INFO OPERATION.UserManagementMaintenanceTask - Global spaces: [ES]\n" + "INFO OPERATION.UserManagementMaintenanceTask - Common spaces: {USER=[ALPHA]}\n" + + "INFO OPERATION.UserManagementMaintenanceTask - Samples by type: {A=B}\n" + "INFO OPERATION.UserManagementMaintenanceTask - Add group SIS[name:sis, ldapGroupKeys:[s], admins:[u2]] with users [u1=u1]\n" + "INFO OPERATION.UserManagementMaintenanceTask - 1 users for group SIS\n" + "ERROR NOTIFY.UserManagementMaintenanceTask - User management failed for the following reason(s):\n\n" @@ -268,7 +276,7 @@ public class UserManagementMaintenanceTaskTest extends AbstractFileSystemTestCas + "INFO OPERATION.UserManagementMaintenanceTask - finished", logRecorder.getLogContent()); assertEquals("1970-01-01 01:00:00 [ADD-AUTHORIZATION-GROUP] blabla\n" - + "1970-01-01 01:00:01 [ADD-USER] a (home space: A)\n\n", + + "1970-01-01 01:00:01 [ADD-USER] a\n\n", FileUtilities.loadToString(auditLogFile)); } @@ -316,7 +324,11 @@ public class UserManagementMaintenanceTaskTest extends AbstractFileSystemTestCas @Override protected UserManager createUserManager(UserManagerConfig config, Log4jSimpleLogger logger) { - return new MockUserManager(config.getCommonSpaces(), logger); + MockUserManager userManager = new MockUserManager(logger); + userManager.setGlobalSpaces(config.getGlobalSpaces()); + userManager.setCommonSpacesByRole(config.getCommonSpaces()); + userManager.setSamplesByType(config.getCommonSamples()); + return userManager; } private UserManagementMaintenanceTaskWithMocks withGroup(String groupCode, Principal... users) @@ -341,11 +353,31 @@ public class UserManagementMaintenanceTaskTest extends AbstractFileSystemTestCas { private ISimpleLogger logger; - MockUserManager(Map<Role, List<String>> commonSpacesByRole, ISimpleLogger logger) + MockUserManager(ISimpleLogger logger) { - super(null, null, commonSpacesByRole, logger, null); + super(null, null, logger, null); this.logger = logger; + } + + @Override + public void setGlobalSpaces(List<String> globalSpaces) + { + logger.log(LogLevel.INFO, "Global spaces: " + globalSpaces); + super.setGlobalSpaces(globalSpaces); + } + + @Override + public void setCommonSpacesByRole(Map<Role, List<String>> commonSpacesByRole) + { logger.log(LogLevel.INFO, "Common spaces: " + commonSpacesByRole); + super.setCommonSpacesByRole(commonSpacesByRole); + } + + @Override + public void setSamplesByType(Map<String, String> samplesByType) + { + logger.log(LogLevel.INFO, "Samples by type: " + samplesByType); + super.setSamplesByType(samplesByType); } @Override diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/task/UserManagerExpectationsBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/task/UserManagerExpectationsBuilder.java index 2333895a262dcb31ea349204f23368e5c8596248..8aba98cbc9b7580dd1c4753c8dd8f77cfe445f43 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/task/UserManagerExpectationsBuilder.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/task/UserManagerExpectationsBuilder.java @@ -20,8 +20,10 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -30,6 +32,7 @@ import java.util.TreeMap; import java.util.TreeSet; import java.util.function.Consumer; import java.util.function.Function; +import java.util.stream.Collector; import java.util.stream.Collectors; import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.AuthorizationGroup; @@ -55,7 +58,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE; class UserManagerExpectationsBuilder { - static final String HOME_SPACE_KEY = "home-space"; + static final String USER_SPACE_POSTFIX_KEY = "user-space-postfix"; private static final String TEST_USER = "test"; @@ -69,7 +72,7 @@ class UserManagerExpectationsBuilder private final Map<Role, List<String>> commonSpaces; - private Map<String, String> homeSpacesByUserId = new TreeMap<>(); + private Map<String, Map<String, String>> userSpacesByGroupAndUserId = new TreeMap<>(); private Map<String, List<Principal>> usersByGroup = new TreeMap<>(); @@ -81,6 +84,14 @@ class UserManagerExpectationsBuilder private Map<String, List<Principal>> adminUsersByGroup = new TreeMap<>(); + private Map<String, Set<String>> groupsByAdminUsers = new TreeMap<>(); + + private Map<String, Set<String>> userSpacesByGroups = new TreeMap<>(); + + private Map<String, String> homeSpacesByUserId = new TreeMap<>(); + + private List<String> globalSpaces = new ArrayList<>();; + UserManagerExpectationsBuilder(IApplicationServerInternalApi v3api, UserManagerTestService testService, IOpenBisSessionManager sessionManager, Map<Role, List<String>> commonSpaces) { @@ -90,6 +101,11 @@ class UserManagerExpectationsBuilder this.commonSpaces = commonSpaces; } + public void setGlobalSpaces(List<String> globalSpaces) + { + this.globalSpaces = globalSpaces; + } + UserManagerExpectationsBuilder unknownUser(Principal user) { unknownUsers.add(user); @@ -108,18 +124,44 @@ class UserManagerExpectationsBuilder UserManagerExpectationsBuilder adminUser(Principal user, String... groups) { + Set<String> usersAdminGroups = groupsByAdminUsers.get(user.getUserId()); + if (usersAdminGroups == null) + { + usersAdminGroups = new TreeSet<>(); + groupsByAdminUsers.put(user.getUserId(), usersAdminGroups); + } + usersAdminGroups.addAll(Arrays.asList(groups)); return addUser(user, adminUsersByGroup, groups); } private UserManagerExpectationsBuilder addUser(Principal user, Map<String, List<Principal>> users, String... groups) { + String userId = user.getUserId(); + if (groups.length == 0) + { + fail("No groups specified for " + userId); + } + String userSpacePostfix = user.getProperty(USER_SPACE_POSTFIX_KEY); + if (userSpacePostfix == null) + { + userSpacePostfix = userId.toUpperCase(); + } for (String group : groups) { + if (homeSpacesByUserId.containsKey(userId) == false) + { + homeSpacesByUserId.put(userId, group + "_" + userSpacePostfix); + } + Map<String, String> userSpacesByUserId = userSpacesByGroupAndUserId.get(group); + if (userSpacesByUserId == null) + { + userSpacesByUserId = new TreeMap<>(); + userSpacesByGroupAndUserId.put(group, userSpacesByUserId); + } + userSpacesByUserId.put(userId, group + "_" + userSpacePostfix); addUserToGroup(user, group, users); addUserToGroup(user, group, usersByGroup); } - String homeSpace = user.getProperty(HOME_SPACE_KEY); - homeSpacesByUserId.put(user.getUserId(), homeSpace == null ? user.getUserId().toUpperCase() : homeSpace); return this; } @@ -146,35 +188,26 @@ class UserManagerExpectationsBuilder private void assertSpaces(String sessionToken) { - List<SpacePermId> allCommonSpaces = getAllCommonSpaces(); - assertSpacesExist(sessionToken, allCommonSpaces); - List<SpacePermId> allUserSpaces = applyMapperToAllUsers(user -> new SpacePermId(getHomeSpaceFor(user.getUserId()))); - assertSpacesExist(sessionToken, allUserSpaces); - } - - private List<SpacePermId> getAllCommonSpaces() - { - List<SpacePermId> allCommonSpaces = new ArrayList<>(); - Set<String> groups = usersByGroup.keySet(); - for (String group : groups) + List<SpacePermId> expectedSpaces = globalSpaces.stream().map(SpacePermId::new).collect(Collectors.toList()); + for (Entry<String, List<Principal>> entry : usersByGroup.entrySet()) { + String groupCode = entry.getKey(); for (List<String> list : commonSpaces.values()) { for (String commonSpace : list) { - allCommonSpaces.add(new SpacePermId(createCommonSpaceCode(group, commonSpace))); + expectedSpaces.add(new SpacePermId(createCommonSpaceCode(groupCode, commonSpace))); } } + for (Principal user : entry.getValue()) + { + expectedSpaces.add(new SpacePermId(userSpacesByGroupAndUserId.get(groupCode).get(user.getUserId()))); + } } - return allCommonSpaces; - } - - private void assertSpacesExist(String sessionToken, List<SpacePermId> spaces) - { - List<String> expectedSpaces = extractedSortedPermIds(spaces); + List<String> expectedSpaceCodes = extractedSortedPermIds(expectedSpaces); SpaceFetchOptions fetchOptions = new SpaceFetchOptions(); - List<String> actualSpaces = extractedSortedCodes(v3api.getSpaces(sessionToken, spaces, fetchOptions).values()); - assertEquals(actualSpaces.toString(), expectedSpaces.toString(), "Spaces"); + List<String> actualSpaces = extractedSortedCodes(v3api.getSpaces(sessionToken, expectedSpaces, fetchOptions).values()); + assertEquals(actualSpaces.toString(), expectedSpaceCodes.toString(), "Spaces"); } private void assertUnknownUsers(String sessionToken) @@ -233,89 +266,105 @@ class UserManagerExpectationsBuilder assertEquals(person.getUserId(), id.getPermId()); assertEquals(person.isActive(), Boolean.TRUE); assertEquals(person.getEmail(), "franz-josef.elmer@systemsx.ch", "Wrong email of " + person); - assertEquals(person.getSpace().getCode(), getHomeSpaceFor(person.getUserId()), "Wrong home space of " + person); + assertEquals(person.getSpace().getCode(), homeSpacesByUserId.get(person.getUserId()), "Wrong home space of " + person); } } private void assertAuthorization(String sessionToken) { - AuthorizationExpectations expectations = new AuthorizationExpectations(v3api, sessionManager, testService); - createExpectationsForDisabledUsers(expectations); - createExpectationsForNormalUsers(expectations); - createExpectationsForAdminUsers(expectations); - expectations.assertExpectations(); + assertAuthorizationOfGlobalSpaces(); + assertAuthorizationOfCommonSpaces(disabledUsersByGroup, Level.NON, Level.NON); + assertAuthorizationOfCommonSpaces(normalUsersByGroup, Level.SPACE_USER, Level.SPACE_OBSERVER); + assertAuthorizationOfCommonSpaces(adminUsersByGroup, Level.SPACE_ADMIN, Level.SPACE_ADMIN); + assertAuthorizationOfUserSpaces(); } - private void createExpectationsForDisabledUsers(AuthorizationExpectations expectations) + private void assertAuthorizationOfGlobalSpaces() { - for (Entry<String, List<Principal>> entry : disabledUsersByGroup.entrySet()) + if (globalSpaces.isEmpty() == false) { - String groupCode = entry.getKey(); - for (Principal user : entry.getValue()) + AuthorizationExpectations expectations = new AuthorizationExpectations(v3api, sessionManager, testService); + for (List<Principal> users : usersByGroup.values()) { - commonSpaces.get(Role.USER).forEach(expectForSpace(expectations, user, groupCode, Level.NON)); - commonSpaces.get(Role.OBSERVER).forEach(expectForSpace(expectations, user, groupCode, Level.NON)); - for (List<Principal> users2 : usersByGroup.values()) + for (Principal user : users) { - users2.forEach(user2 -> expectations.expect(user, getHomeSpace(user2), - equals(user, user2) ? Level.SPACE_ADMIN : Level.NON)); + globalSpaces.forEach(space -> expectations.expect(user, space, Level.SPACE_OBSERVER)); } } + expectations.assertExpectations(); } } - private void createExpectationsForNormalUsers(AuthorizationExpectations expectations) + private void assertAuthorizationOfCommonSpaces(Map<String, List<Principal>> users, Level userLevel, Level observerLevel) { - for (Entry<String, List<Principal>> entry : normalUsersByGroup.entrySet()) + AuthorizationExpectations expectations = new AuthorizationExpectations(v3api, sessionManager, testService); + for (Entry<String, List<Principal>> entry : users.entrySet()) { String groupCode = entry.getKey(); for (Principal user : entry.getValue()) { - commonSpaces.get(Role.USER).forEach(expectForSpace(expectations, user, groupCode, Level.SPACE_USER)); - commonSpaces.get(Role.OBSERVER).forEach(expectForSpace(expectations, user, groupCode, Level.SPACE_OBSERVER)); - for (List<Principal> users2 : usersByGroup.values()) - { - users2.forEach(user2 -> expectations.expect(user, getHomeSpace(user2), - equals(user, user2) ? Level.SPACE_ADMIN : Level.NON)); - } + commonSpaces.get(Role.USER).forEach(expectForSpace(expectations, user, groupCode, userLevel)); + commonSpaces.get(Role.OBSERVER).forEach(expectForSpace(expectations, user, groupCode, observerLevel)); } } + expectations.assertExpectations(); } - - private void createExpectationsForAdminUsers(AuthorizationExpectations expectations) + + private void assertAuthorizationOfUserSpaces() { - for (Entry<String, List<Principal>> entry : adminUsersByGroup.entrySet()) + Set<String> allUserSpaces = new TreeSet<>(); + for (Entry<String, List<Principal>> entry : usersByGroup.entrySet()) { String groupCode = entry.getKey(); for (Principal user : entry.getValue()) { - commonSpaces.get(Role.USER).forEach(expectForSpace(expectations, user, groupCode, Level.SPACE_ADMIN)); - commonSpaces.get(Role.OBSERVER).forEach(expectForSpace(expectations, user, groupCode, Level.SPACE_ADMIN)); - Set<Entry<String, List<Principal>>> entrySet = usersByGroup.entrySet(); - for (Entry<String, List<Principal>> entry2 : entrySet) + allUserSpaces.add(userSpacesByGroupAndUserId.get(groupCode).get(user.getUserId())); + } + } + AuthorizationExpectations expectations = new AuthorizationExpectations(v3api, sessionManager, testService); + for (List<Principal> users : usersByGroup.values()) + { + for (Principal user : users) + { + Set<String> accessibleUserSpaces = getAllAccessibleUserSpacesFor(user.getUserId()); + for (String space : allUserSpaces) { - String groupCode2 = entry2.getKey(); - List<Principal> users2 = entry2.getValue(); - if (groupCode.equals(groupCode2)) - { - users2.forEach(user2 -> expectations.expect(user, getHomeSpace(user2), Level.SPACE_ADMIN)); - } else - { - users2.forEach(user2 -> expectations.expect(user, getHomeSpace(user2), Level.NON)); - } + expectations.expect(user, space, accessibleUserSpaces.contains(space) ? Level.SPACE_ADMIN : Level.NON); } } } + expectations.assertExpectations(); } - private String getHomeSpace(Principal user) - { - return getHomeSpaceFor(user.getUserId()); - } - - private String getHomeSpaceFor(String userId) + private Set<String> getAllAccessibleUserSpacesFor(String userId) { - return homeSpacesByUserId.get(userId); + Set<String> spaces = new TreeSet<>(); + for (String group : usersByGroup.keySet()) + { + Map<String, String> userSpacesByUserId = userSpacesByGroupAndUserId.get(group); + if (userSpacesByUserId != null) + { + String space = userSpacesByUserId.get(userId); + if (space != null) + { + spaces.add(space); + } + } + } + Set<String> groups = groupsByAdminUsers.get(userId); + if (groups != null) + { + for (String group : groups) + { + Map<String, String> userSpacesByUserId = userSpacesByGroupAndUserId.get(group); + if (userSpacesByUserId != null) + { + userSpacesByUserId.values().forEach(space -> spaces.add(space)); + } + } + } + System.err.println(userId + " is admin of " + spaces); + return spaces; } private Consumer<String> expectForSpace(AuthorizationExpectations expectations, Principal user, String groupCode, Level level) @@ -366,6 +415,7 @@ class UserManagerExpectationsBuilder { String userId = entry.getKey(); String sessionToken = v3api.login(userId, PASSWORD); + int count = 0; try { Session session = sessionManager.getSession(sessionToken); @@ -376,18 +426,19 @@ class UserManagerExpectationsBuilder for (String space : entry2.getValue()) { Level actualLevel = getActualLevel(context, space); - System.out.println("UserManagerTestExpectation: " + level + " for user " + userId + " on space " + space); if (level.equals(actualLevel) == false) { builder.append("Authorization level for user ").append(userId).append(" on space ").append(space); builder.append(". Expected: ").append(level).append(", but found: ").append(actualLevel).append("\n"); } + count++; } } } finally { v3api.logout(sessionToken); } + System.out.println(count + " authorization expectations tested for user " + userId); } if (builder.length() > 0) { @@ -431,12 +482,12 @@ class UserManagerExpectationsBuilder private <T> List<T> applyMapperToAllUsers(Function<Principal, T> mapper) { - List<T> result = new ArrayList<>(); + Set<T> result = new LinkedHashSet<>(); for (List<Principal> users : usersByGroup.values()) { result.addAll(users.stream().map(mapper).collect(Collectors.toList())); } - return result; + return new ArrayList<>(result); } private static String createCommonSpaceCode(String groupCode, String spaceCode) @@ -444,11 +495,6 @@ class UserManagerExpectationsBuilder return groupCode + "_" + spaceCode; } - private static boolean equals(Principal user1, Principal user2) - { - return user1.getUserId().equals(user2.getUserId()); - } - private enum Level { NON diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/task/UserManagerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/task/UserManagerTest.java index 4dc8559ac650a1a5ba38ddb9ae04a9556b9681b5..3d9a33c947a1ba6e5df55b95f8433d93ddec14c4 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/task/UserManagerTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/task/UserManagerTest.java @@ -54,6 +54,8 @@ public class UserManagerTest extends AbstractTest private static final Principal U3 = new Principal("u3", "Alan", "Turing", "a.t@abc.de"); + private static final Principal U4 = new Principal("u4", "Leonard", "Euler", "l.e@abc.de"); + @Autowired private UserManagerTestService testService; @@ -69,15 +71,14 @@ public class UserManagerTest extends AbstractTest } @Test - public void testAddNewGroupWithUsers() + public void testCreateOneGroupWithAUserWhichAlreadyTriedLoggedIn() { // Given + assertEquals(v3api.login(U2.getUserId(), PASSWORD), null); MockLogger logger = new MockLogger(); Map<Role, List<String>> commonSpaces = commonSpaces(); UserManager userManager = createUserManager(commonSpaces, logger); - Map<String, Principal> principals = principals(U3, U1, U2); - UserGroup group = group("G1", U1.getUserId(), "blabla"); - userManager.addGroup(group, principals); + userManager.addGroup(group("G1", U1.getUserId(), "blabla"), users(U1, U2)); // When UserManagerReport report = manage(userManager); @@ -95,20 +96,162 @@ public class UserManagerTest extends AbstractTest + "1970-01-01 01:00:08 [ADD-SPACE] G1_GAMMA\n" + "1970-01-01 01:00:09 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1, role: SPACE_OBSERVER for G1_GAMMA\n" + "1970-01-01 01:00:10 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_GAMMA\n" - + "1970-01-01 01:00:11 [ADD-USER] u1 (home space: U1)\n" - + "1970-01-01 01:00:12 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1, user: u1\n" - + "1970-01-01 01:00:13 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for U1\n" + + "1970-01-01 01:00:11 [ADD-SPACE] G1_U1\n" + + "1970-01-01 01:00:12 [ADD-USER] u1\n" + + "1970-01-01 01:00:13 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1, user: u1\n" + "1970-01-01 01:00:14 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, user: u1\n" - + "1970-01-01 01:00:15 [ADD-USER] u2 (home space: U2)\n" - + "1970-01-01 01:00:16 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1, user: u2\n" - + "1970-01-01 01:00:17 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for U2\n" - + "1970-01-01 01:00:18 [ADD-USER] u3 (home space: U3)\n" - + "1970-01-01 01:00:19 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1, user: u3\n" - + "1970-01-01 01:00:20 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for U3\n"); + + "1970-01-01 01:00:15 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_U1\n" + + "1970-01-01 01:00:16 [ADD-SPACE] G1_U2\n" + + "1970-01-01 01:00:17 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1, user: u2\n" + + "1970-01-01 01:00:18 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_U2\n"); UserManagerExpectationsBuilder builder = createBuilder(commonSpaces); builder.adminUser(U1, "G1"); builder.user(U2, "G1"); + builder.assertExpectations(); + } + + @Test + public void testCreateTwoGroupsWithDistinctUsers() + { + // Given + MockLogger logger = new MockLogger(); + Map<Role, List<String>> commonSpaces = commonSpaces(); + UserManager userManager = createUserManager(commonSpaces, logger); + List<String> globalSpaces = Arrays.asList("A", "B"); + userManager.setGlobalSpaces(globalSpaces); + userManager.addGroup(group("G1", U1.getUserId(), "blabla"), users(U3, U1, U2)); + userManager.addGroup(group("G2", U4.getUserId()), users(U4)); + + // When + UserManagerReport report = manage(userManager); + + // Then + assertEquals(report.getErrorReport(), ""); + assertEquals(report.getAuditLog(), "1970-01-01 01:00:00 [ADD-SPACES] [A, B]\n" + + "1970-01-01 01:00:01 [ADD-AUTHORIZATION-GROUP] ALL_GROUPS\n" + + "1970-01-01 01:00:02 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: ALL_GROUPS, role: SPACE_OBSERVER for A\n" + + "1970-01-01 01:00:03 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: ALL_GROUPS, role: SPACE_OBSERVER for B\n" + + "1970-01-01 01:00:04 [ADD-AUTHORIZATION-GROUP] G1\n" + + "1970-01-01 01:00:05 [ADD-AUTHORIZATION-GROUP] G1_ADMIN\n" + + "1970-01-01 01:00:06 [ADD-SPACE] G1_ALPHA\n" + + "1970-01-01 01:00:07 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1, role: SPACE_USER for G1_ALPHA\n" + + "1970-01-01 01:00:08 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_ALPHA\n" + + "1970-01-01 01:00:09 [ADD-SPACE] G1_BETA\n" + + "1970-01-01 01:00:10 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1, role: SPACE_USER for G1_BETA\n" + + "1970-01-01 01:00:11 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_BETA\n" + + "1970-01-01 01:00:12 [ADD-SPACE] G1_GAMMA\n" + + "1970-01-01 01:00:13 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1, role: SPACE_OBSERVER for G1_GAMMA\n" + + "1970-01-01 01:00:14 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_GAMMA\n" + + "1970-01-01 01:00:15 [ADD-SPACE] G1_U1\n" + + "1970-01-01 01:00:16 [ADD-USER] u1\n" + + "1970-01-01 01:00:17 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_U1\n" + + "1970-01-01 01:00:18 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1, user: u1\n" + + "1970-01-01 01:00:19 [ADD-USER-TO-AUTHORIZATION-GROUP] group: ALL_GROUPS, user: u1\n" + + "1970-01-01 01:00:20 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, user: u1\n" + + "1970-01-01 01:00:21 [ADD-SPACE] G1_U2\n" + + "1970-01-01 01:00:22 [ADD-USER] u2\n" + + "1970-01-01 01:00:23 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_U2\n" + + "1970-01-01 01:00:24 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1, user: u2\n" + + "1970-01-01 01:00:25 [ADD-USER-TO-AUTHORIZATION-GROUP] group: ALL_GROUPS, user: u2\n" + + "1970-01-01 01:00:26 [ADD-SPACE] G1_U3\n" + + "1970-01-01 01:00:27 [ADD-USER] u3\n" + + "1970-01-01 01:00:28 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_U3\n" + + "1970-01-01 01:00:29 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1, user: u3\n" + + "1970-01-01 01:00:30 [ADD-USER-TO-AUTHORIZATION-GROUP] group: ALL_GROUPS, user: u3\n" + + "1970-01-01 01:00:31 [ADD-AUTHORIZATION-GROUP] G2\n" + + "1970-01-01 01:00:32 [ADD-AUTHORIZATION-GROUP] G2_ADMIN\n" + + "1970-01-01 01:00:33 [ADD-SPACE] G2_ALPHA\n" + + "1970-01-01 01:00:34 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_USER for G2_ALPHA\n" + + "1970-01-01 01:00:35 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_ALPHA\n" + + "1970-01-01 01:00:36 [ADD-SPACE] G2_BETA\n" + + "1970-01-01 01:00:37 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_USER for G2_BETA\n" + + "1970-01-01 01:00:38 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_BETA\n" + + "1970-01-01 01:00:39 [ADD-SPACE] G2_GAMMA\n" + + "1970-01-01 01:00:40 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_OBSERVER for G2_GAMMA\n" + + "1970-01-01 01:00:41 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_GAMMA\n" + + "1970-01-01 01:00:42 [ADD-SPACE] G2_U4\n" + + "1970-01-01 01:00:43 [ADD-USER] u4\n" + + "1970-01-01 01:00:44 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_U4\n" + + "1970-01-01 01:00:45 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u4\n" + + "1970-01-01 01:00:46 [ADD-USER-TO-AUTHORIZATION-GROUP] group: ALL_GROUPS, user: u4\n" + + "1970-01-01 01:00:47 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, user: u4\n"); + UserManagerExpectationsBuilder builder = createBuilder(commonSpaces); + builder.setGlobalSpaces(globalSpaces); + builder.adminUser(U1, "G1"); + builder.user(U2, "G1"); + builder.user(U3, "G1"); + builder.adminUser(U4, "G2"); + builder.assertExpectations(); + } + + @Test + public void testCreateTwoGroupsWithSharedUsers() + { + // Given + MockLogger logger = new MockLogger(); + Map<Role, List<String>> commonSpaces = commonSpaces(); + UserManager userManager = createUserManager(commonSpaces, logger); + userManager.addGroup(group("G1", U1.getUserId()), users(U1, U2, U3)); + userManager.addGroup(group("G2", U3.getUserId(), U4.getUserId()), users(U2, U3, U4)); + + // When + UserManagerReport report = manage(userManager); + + // Then + assertEquals(report.getErrorReport(), ""); + assertEquals(report.getAuditLog(), "1970-01-01 01:00:00 [ADD-AUTHORIZATION-GROUP] G1\n" + + "1970-01-01 01:00:01 [ADD-AUTHORIZATION-GROUP] G1_ADMIN\n" + + "1970-01-01 01:00:02 [ADD-SPACE] G1_ALPHA\n" + + "1970-01-01 01:00:03 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1, role: SPACE_USER for G1_ALPHA\n" + + "1970-01-01 01:00:04 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_ALPHA\n" + + "1970-01-01 01:00:05 [ADD-SPACE] G1_BETA\n" + + "1970-01-01 01:00:06 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1, role: SPACE_USER for G1_BETA\n" + + "1970-01-01 01:00:07 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_BETA\n" + + "1970-01-01 01:00:08 [ADD-SPACE] G1_GAMMA\n" + + "1970-01-01 01:00:09 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1, role: SPACE_OBSERVER for G1_GAMMA\n" + + "1970-01-01 01:00:10 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_GAMMA\n" + + "1970-01-01 01:00:11 [ADD-SPACE] G1_U1\n" + + "1970-01-01 01:00:12 [ADD-USER] u1\n" + + "1970-01-01 01:00:13 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_U1\n" + + "1970-01-01 01:00:14 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1, user: u1\n" + + "1970-01-01 01:00:15 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, user: u1\n" + + "1970-01-01 01:00:16 [ADD-SPACE] G1_U2\n" + + "1970-01-01 01:00:17 [ADD-USER] u2\n" + + "1970-01-01 01:00:18 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_U2\n" + + "1970-01-01 01:00:19 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1, user: u2\n" + + "1970-01-01 01:00:20 [ADD-SPACE] G1_U3\n" + + "1970-01-01 01:00:21 [ADD-USER] u3\n" + + "1970-01-01 01:00:22 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G1_ADMIN, role: SPACE_ADMIN for G1_U3\n" + + "1970-01-01 01:00:23 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G1, user: u3\n" + + "1970-01-01 01:00:24 [ADD-AUTHORIZATION-GROUP] G2\n" + + "1970-01-01 01:00:25 [ADD-AUTHORIZATION-GROUP] G2_ADMIN\n" + + "1970-01-01 01:00:26 [ADD-SPACE] G2_ALPHA\n" + + "1970-01-01 01:00:27 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_USER for G2_ALPHA\n" + + "1970-01-01 01:00:28 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_ALPHA\n" + + "1970-01-01 01:00:29 [ADD-SPACE] G2_BETA\n" + + "1970-01-01 01:00:30 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_USER for G2_BETA\n" + + "1970-01-01 01:00:31 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_BETA\n" + + "1970-01-01 01:00:32 [ADD-SPACE] G2_GAMMA\n" + + "1970-01-01 01:00:33 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_OBSERVER for G2_GAMMA\n" + + "1970-01-01 01:00:34 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_GAMMA\n" + + "1970-01-01 01:00:35 [ADD-SPACE] G2_U2\n" + + "1970-01-01 01:00:36 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_U2\n" + + "1970-01-01 01:00:37 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u2\n" + + "1970-01-01 01:00:38 [ADD-SPACE] G2_U3\n" + + "1970-01-01 01:00:39 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_U3\n" + + "1970-01-01 01:00:40 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u3\n" + + "1970-01-01 01:00:41 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, user: u3\n" + + "1970-01-01 01:00:42 [ADD-SPACE] G2_U4\n" + + "1970-01-01 01:00:43 [ADD-USER] u4\n" + + "1970-01-01 01:00:44 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_U4\n" + + "1970-01-01 01:00:45 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u4\n" + + "1970-01-01 01:00:46 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, user: u4\n"); + UserManagerExpectationsBuilder builder = createBuilder(commonSpaces); + builder.adminUser(U1, "G1"); + builder.user(U2, "G1", "G2"); builder.user(U3, "G1"); + builder.adminUser(U3, "G2"); + builder.adminUser(U4, "G2"); builder.assertExpectations(); } @@ -116,30 +259,30 @@ public class UserManagerTest extends AbstractTest public void testAddUsersToAnExistingGroup() { // Given - // 1. create group G2 with user U1 + // 1. create group G2 with user U1 (admin) MockLogger logger = new MockLogger(); Map<Role, List<String>> commonSpaces = commonSpaces(); UserManager userManager = createUserManager(commonSpaces, logger); - UserGroup group = group("G2", U1.getUserId(), "blabla"); - userManager.addGroup(group, principals(U1)); + userManager.addGroup(group("G2", U1.getUserId(), "blabla"), users(U1)); assertEquals(manage(userManager).getErrorReport(), ""); createBuilder(commonSpaces).adminUser(U1, "G2").assertExpectations(); // 2. add users U2 and U3 to group G2 userManager = createUserManager(commonSpaces, logger); - group.setAdmins(Arrays.asList(U1.getUserId())); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group("G2", U1.getUserId()), users(U1, U2, U3)); // When UserManagerReport report = manage(userManager); // Then assertEquals(report.getErrorReport(), ""); - assertEquals(report.getAuditLog(), "1970-01-01 01:00:00 [ADD-USER] u2 (home space: U2)\n" - + "1970-01-01 01:00:01 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u2\n" - + "1970-01-01 01:00:02 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for U2\n" - + "1970-01-01 01:00:03 [ADD-USER] u3 (home space: U3)\n" - + "1970-01-01 01:00:04 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u3\n" - + "1970-01-01 01:00:05 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for U3\n"); + assertEquals(report.getAuditLog(), "1970-01-01 01:00:00 [ADD-SPACE] G2_U2\n" + + "1970-01-01 01:00:01 [ADD-USER] u2\n" + + "1970-01-01 01:00:02 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_U2\n" + + "1970-01-01 01:00:03 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u2\n" + + "1970-01-01 01:00:04 [ADD-SPACE] G2_U3\n" + + "1970-01-01 01:00:05 [ADD-USER] u3\n" + + "1970-01-01 01:00:06 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_U3\n" + + "1970-01-01 01:00:07 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u3\n"); UserManagerExpectationsBuilder builder = createBuilder(commonSpaces); builder.adminUser(U1, "G2"); builder.user(U2, "G2"); @@ -155,13 +298,12 @@ public class UserManagerTest extends AbstractTest MockLogger logger = new MockLogger(); Map<Role, List<String>> commonSpaces = commonSpaces(); UserManager userManager = createUserManager(commonSpaces, logger); - UserGroup group = group("G2", U1.getUserId(), "blabla"); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group("G2", U1.getUserId()), users(U1, U2, U3)); assertEquals(manage(userManager).getErrorReport(), ""); createBuilder(commonSpaces).adminUser(U1, "G2").user(U2, "G2").user(U3, "G2").assertExpectations(); // 2. remove U2 from group G2 userManager = createUserManager(commonSpaces, logger); - userManager.addGroup(group, principals(U1, U3)); + userManager.addGroup(group("G2", U1.getUserId()), users(U1, U3)); // When UserManagerReport report = manage(userManager); @@ -185,13 +327,13 @@ public class UserManagerTest extends AbstractTest Map<Role, List<String>> commonSpaces = commonSpaces(); UserManager userManager = createUserManager(commonSpaces, logger); UserGroup group = group("G2"); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group, users(U1, U2, U3)); assertEquals(manage(userManager).getErrorReport(), ""); createBuilder(commonSpaces).user(U1, "G2").user(U2, "G2").user(U3, "G2").assertExpectations(); // 2. make U1 admin userManager = createUserManager(commonSpaces, logger); group = group("G2", U1.getUserId()); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group, users(U1, U2, U3)); // When UserManagerReport report = manage(userManager); @@ -215,13 +357,13 @@ public class UserManagerTest extends AbstractTest Map<Role, List<String>> commonSpaces = commonSpaces(); UserManager userManager = createUserManager(commonSpaces, logger); UserGroup group = group("G2", U1.getUserId()); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group, users(U1, U2, U3)); assertEquals(manage(userManager).getErrorReport(), ""); createBuilder(commonSpaces).adminUser(U1, "G2").user(U2, "G2").user(U3, "G2").assertExpectations(); // 2. make U1 normal user userManager = createUserManager(commonSpaces, logger); group = group("G2"); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group, users(U1, U2, U3)); // When UserManagerReport report = manage(userManager); @@ -245,16 +387,16 @@ public class UserManagerTest extends AbstractTest Map<Role, List<String>> commonSpaces = commonSpaces(); UserManager userManager = createUserManager(commonSpaces, logger); UserGroup group = group("G2", U1.getUserId(), "blabla"); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group, users(U1, U2, U3)); assertEquals(manage(userManager).getErrorReport(), ""); // 2. remove U2 from group G2 userManager = createUserManager(commonSpaces, logger); - userManager.addGroup(group, principals(U1, U3)); + userManager.addGroup(group, users(U1, U3)); assertEquals(manage(userManager).getErrorReport(), ""); createBuilder(commonSpaces).adminUser(U1, "G2").disabledUser(U2, "G2").user(U3, "G2").assertExpectations(); // 3. add U2 again to group G2 userManager = createUserManager(commonSpaces, logger); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group, users(U1, U2, U3)); // When UserManagerReport report = manage(userManager); @@ -278,12 +420,12 @@ public class UserManagerTest extends AbstractTest Map<Role, List<String>> commonSpaces = commonSpaces(); UserManager userManager = createUserManager(commonSpaces, logger); UserGroup group = group("G2", U1.getUserId(), "blabla"); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group, users(U1, U2, U3)); assertEquals(manage(userManager).getErrorReport(), ""); createBuilder(commonSpaces).adminUser(U1, "G2").user(U2, "G2").user(U3, "G2").assertExpectations(); // 2. remove U1 from group G2 userManager = createUserManager(commonSpaces, logger); - userManager.addGroup(group, principals(U2, U3)); + userManager.addGroup(group, users(U2, U3)); // When UserManagerReport report = manage(userManager); @@ -308,16 +450,17 @@ public class UserManagerTest extends AbstractTest Map<Role, List<String>> commonSpaces = commonSpaces(); UserManager userManager = createUserManager(commonSpaces, logger); UserGroup group = group("G2", U1.getUserId(), "blabla"); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group, users(U1, U2, U3)); assertEquals(manage(userManager).getErrorReport(), ""); + createBuilder(commonSpaces).adminUser(U1, "G2").user(U2, "G2").user(U3, "G2").assertExpectations(); // 2. remove U1 from group G2 userManager = createUserManager(commonSpaces, logger); - userManager.addGroup(group, principals(U2, U3)); + userManager.addGroup(group, users(U2, U3)); assertEquals(manage(userManager).getErrorReport(), ""); createBuilder(commonSpaces).disabledUser(U1, "G2").user(U2, "G2").user(U3, "G2").assertExpectations(); // 3. add U1 again to group G2 userManager = createUserManager(commonSpaces, logger); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group, users(U1, U2, U3)); // When UserManagerReport report = manage(userManager); @@ -333,6 +476,180 @@ public class UserManagerTest extends AbstractTest builder.assertExpectations(); } + @Test + public void testCreateSecondGroupWithNormalUserInBothGroups() + { + // Given + // 1. create group G1 with users U1 (admin) and U2 + MockLogger logger = new MockLogger(); + Map<Role, List<String>> commonSpaces = commonSpaces(); + UserManager userManager = createUserManager(commonSpaces, logger); + userManager.addGroup(group("G1", U1.getUserId()), users(U1, U2)); + assertEquals(manage(userManager).getErrorReport(), ""); + createBuilder(commonSpaces).adminUser(U1, "G1").user(U2, "G1").unknownUser(U3).assertExpectations(); + // 2. create group G2 with users U2 and U3 (admin) + userManager = createUserManager(commonSpaces, logger); + userManager.addGroup(group("G1", U1.getUserId()), users(U1, U2)); + userManager.addGroup(group("G2", U3.getUserId()), users(U2, U3)); + + // When + UserManagerReport report = manage(userManager); + + // Then + assertEquals(report.getErrorReport(), ""); + assertEquals(report.getAuditLog(), "1970-01-01 01:00:00 [ADD-AUTHORIZATION-GROUP] G2\n" + + "1970-01-01 01:00:01 [ADD-AUTHORIZATION-GROUP] G2_ADMIN\n" + + "1970-01-01 01:00:02 [ADD-SPACE] G2_ALPHA\n" + + "1970-01-01 01:00:03 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_USER for G2_ALPHA\n" + + "1970-01-01 01:00:04 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_ALPHA\n" + + "1970-01-01 01:00:05 [ADD-SPACE] G2_BETA\n" + + "1970-01-01 01:00:06 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_USER for G2_BETA\n" + + "1970-01-01 01:00:07 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_BETA\n" + + "1970-01-01 01:00:08 [ADD-SPACE] G2_GAMMA\n" + + "1970-01-01 01:00:09 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_OBSERVER for G2_GAMMA\n" + + "1970-01-01 01:00:10 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_GAMMA\n" + + "1970-01-01 01:00:11 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u2\n" + + "1970-01-01 01:00:12 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for U2\n" + + "1970-01-01 01:00:13 [ADD-USER] u3 (home space: U3)\n" + + "1970-01-01 01:00:14 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u3\n" + + "1970-01-01 01:00:15 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for U3\n" + + "1970-01-01 01:00:16 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, user: u3\n"); + UserManagerExpectationsBuilder builder = createBuilder(commonSpaces); + builder.adminUser(U1, "G1"); + builder.user(U2, "G1", "G2"); + builder.adminUser(U3, "G2"); + builder.assertExpectations(); + } + + @Test + public void testCreateSecondGroupWithAdminUserInBothGroups() + { + // Given + // 1. create group G1 with users U1 (admin) and U2 + MockLogger logger = new MockLogger(); + Map<Role, List<String>> commonSpaces = commonSpaces(); + UserManager userManager = createUserManager(commonSpaces, logger); + userManager.addGroup(group("G1", U1.getUserId()), users(U1, U2)); + assertEquals(manage(userManager).getErrorReport(), ""); + createBuilder(commonSpaces).adminUser(U1, "G1").user(U2, "G1").unknownUser(U3).assertExpectations(); + // 2. create group G2 with users U1 (admin) and U3 + userManager = createUserManager(commonSpaces, logger); + userManager.addGroup(group("G1", U1.getUserId()), users(U1, U2)); + userManager.addGroup(group("G2", U1.getUserId()), users(U1, U3)); + + // When + UserManagerReport report = manage(userManager); + + // Then + assertEquals(report.getErrorReport(), ""); + assertEquals(report.getAuditLog(), "1970-01-01 01:00:00 [ADD-AUTHORIZATION-GROUP] G2\n" + + "1970-01-01 01:00:01 [ADD-AUTHORIZATION-GROUP] G2_ADMIN\n" + + "1970-01-01 01:00:02 [ADD-SPACE] G2_ALPHA\n" + + "1970-01-01 01:00:03 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_USER for G2_ALPHA\n" + + "1970-01-01 01:00:04 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_ALPHA\n" + + "1970-01-01 01:00:05 [ADD-SPACE] G2_BETA\n" + + "1970-01-01 01:00:06 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_USER for G2_BETA\n" + + "1970-01-01 01:00:07 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_BETA\n" + + "1970-01-01 01:00:08 [ADD-SPACE] G2_GAMMA\n" + + "1970-01-01 01:00:09 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_OBSERVER for G2_GAMMA\n" + + "1970-01-01 01:00:10 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_GAMMA\n" + + "1970-01-01 01:00:11 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u1\n" + + "1970-01-01 01:00:12 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for U1\n" + + "1970-01-01 01:00:13 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, user: u1\n" + + "1970-01-01 01:00:14 [ADD-USER] u3 (home space: U3)\n" + + "1970-01-01 01:00:15 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u3\n" + + "1970-01-01 01:00:16 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for U3\n"); + UserManagerExpectationsBuilder builder = createBuilder(commonSpaces); + builder.adminUser(U1, "G1", "G2"); + builder.user(U2, "G1"); + builder.user(U3, "G2"); + builder.assertExpectations(); + } + + @Test + public void testCreateSecondGroupWithUserNormalInFirstGroupAndAdminInSecondGroup() + { + // Given + // 1. create group G1 with users U1 (admin) and U2 + MockLogger logger = new MockLogger(); + Map<Role, List<String>> commonSpaces = commonSpaces(); + UserManager userManager = createUserManager(commonSpaces, logger); + userManager.addGroup(group("G1", U1.getUserId()), users(U1, U2)); + assertEquals(manage(userManager).getErrorReport(), ""); + createBuilder(commonSpaces).adminUser(U1, "G1").user(U2, "G1").unknownUser(U3).assertExpectations(); + // 2. create group G2 with users U2 (admin) and U3 + userManager = createUserManager(commonSpaces, logger); + userManager.addGroup(group("G1", U1.getUserId()), users(U1, U2)); + userManager.addGroup(group("G2", U2.getUserId()), users(U2, U3)); + + // When + UserManagerReport report = manage(userManager); + + // Then + assertEquals(report.getErrorReport(), ""); + assertEquals(report.getAuditLog(), "1970-01-01 01:00:00 [ADD-AUTHORIZATION-GROUP] G2\n" + + "1970-01-01 01:00:01 [ADD-AUTHORIZATION-GROUP] G2_ADMIN\n" + + "1970-01-01 01:00:02 [ADD-SPACE] G2_ALPHA\n" + + "1970-01-01 01:00:03 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_USER for G2_ALPHA\n" + + "1970-01-01 01:00:04 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_ALPHA\n" + + "1970-01-01 01:00:05 [ADD-SPACE] G2_BETA\n" + + "1970-01-01 01:00:06 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_USER for G2_BETA\n" + + "1970-01-01 01:00:07 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_BETA\n" + + "1970-01-01 01:00:08 [ADD-SPACE] G2_GAMMA\n" + + "1970-01-01 01:00:09 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2, role: SPACE_OBSERVER for G2_GAMMA\n" + + "1970-01-01 01:00:10 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for G2_GAMMA\n" + + "1970-01-01 01:00:11 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u2\n" + + "1970-01-01 01:00:12 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for U2\n" + + "1970-01-01 01:00:13 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, user: u2\n" + + "1970-01-01 01:00:14 [ADD-USER] u3 (home space: U3)\n" + + "1970-01-01 01:00:15 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u3\n" + + "1970-01-01 01:00:16 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for U3\n"); + UserManagerExpectationsBuilder builder = createBuilder(commonSpaces); + builder.adminUser(U1, "G1"); + builder.user(U2, "G1"); + builder.adminUser(U2, "G2"); + builder.user(U3, "G2"); + builder.assertExpectations(); + } + + @Test + public void testCreateTwoGroupsAndMoveUserBetweenGroups() + { + // Given + // 1. create group G1 with users U1 (admin) and U2 + MockLogger logger = new MockLogger(); + Map<Role, List<String>> commonSpaces = commonSpaces(); + UserManager userManager = createUserManager(commonSpaces, logger); + userManager.addGroup(group("G1", U1.getUserId()), users(U1, U2)); + assertEquals(manage(userManager).getErrorReport(), ""); + createBuilder(commonSpaces).adminUser(U1, "G1").user(U2, "G1").unknownUser(U3).assertExpectations(); + // 2. create group G2 with users U3 (admin) and U4 + userManager = createUserManager(commonSpaces, logger); + userManager.addGroup(group("G1", U1.getUserId()), users(U1, U2)); + userManager.addGroup(group("G2", U3.getUserId()), users(U3, U4)); + assertEquals(manage(userManager).getErrorReport(), ""); + createBuilder(commonSpaces).adminUser(U1, "G1").user(U2, "G1").adminUser(U3, "G2").user(U4, "G2").assertExpectations(); + // 3. Move U2 from G1 -> G2 + userManager = createUserManager(commonSpaces, logger); + userManager.addGroup(group("G1", U1.getUserId()), users(U1)); + userManager.addGroup(group("G2", U3.getUserId()), users(U2, U3, U4)); + + // When + UserManagerReport report = manage(userManager); + + // Then + assertEquals(report.getErrorReport(), ""); + assertEquals(report.getAuditLog(), "1970-01-01 01:00:00 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u2\n" + + "1970-01-01 01:00:01 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for U2\n" + + "1970-01-01 01:00:02 [REMOVE-USER-FROM-AUTHORIZATION-GROUP] group: G1, user: u2\n"); + UserManagerExpectationsBuilder builder = createBuilder(commonSpaces); + builder.adminUser(U1, "G1"); + builder.user(U2, "G2"); + builder.adminUser(U3, "G2"); + builder.user(U4, "G2"); + builder.assertExpectations(); + } + @Test public void testUserFromAGroupHasLefted() { @@ -342,7 +659,7 @@ public class UserManagerTest extends AbstractTest Map<Role, List<String>> commonSpaces = commonSpaces(); UserManager userManager = createUserManager(commonSpaces, logger); UserGroup group = group("G2", U1.getUserId(), "blabla"); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group, users(U1, U2, U3)); assertEquals(manage(userManager).getErrorReport(), ""); createBuilder(commonSpaces).adminUser(U1, "G2").user(U2, "G2").user(U3, "G2").assertExpectations(); // 2. U2 is no longer known by the authentication service @@ -370,37 +687,83 @@ public class UserManagerTest extends AbstractTest Map<Role, List<String>> commonSpaces = commonSpaces(); UserManager userManager = createUserManager(commonSpaces, logger); UserGroup group = group("G2", U1.getUserId(), "blabla"); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group, users(U1, U2, U3)); + assertEquals(manage(userManager).getErrorReport(), ""); + createBuilder(commonSpaces).adminUser(U1, "G2").user(U2, "G2").user(U3, "G2").assertExpectations(); + // 2. U2 is no longer known by the authentication service + userManager = createUserManager(commonSpaces, logger, U2); + userManager.addGroup(group, users(U1, U3)); + assertEquals(manage(userManager).getErrorReport(), ""); + createBuilder(commonSpaces).adminUser(U1, "G2").unknownUser(U2).user(U3, "G2").assertExpectations(); + // 3. U2 is reused and added to group G2 + userManager = createUserManager(commonSpaces, logger); + userManager.addGroup(group, users(U1, U2, U3)); + + // When + UserManagerReport report = manage(userManager); + + // Then + assertEquals(report.getErrorReport(), ""); + assertEquals(report.getAuditLog(), "1970-01-01 01:00:00 [REUSE-USER] u2 (home space: U2_2)\n" + + "1970-01-01 01:00:01 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u2\n" + + "1970-01-01 01:00:02 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for U2_2\n"); + UserManagerExpectationsBuilder builder = createBuilder(commonSpaces); + builder.adminUser(U1, "G2"); + builder.user(reuse(U2, "U2_2"), "G2"); + builder.user(U3, "G2"); + builder.assertExpectations(); + } + + @Test + public void testReuseSameUserIdTwice() + { + // Given + // 1. create group G2 with users U1 (admin), U2 and U3 + MockLogger logger = new MockLogger(); + Map<Role, List<String>> commonSpaces = commonSpaces(); + UserManager userManager = createUserManager(commonSpaces, logger); + UserGroup group = group("G2", U1.getUserId(), "blabla"); + userManager.addGroup(group, users(U1, U2, U3)); assertEquals(manage(userManager).getErrorReport(), ""); createBuilder(commonSpaces).adminUser(U1, "G2").user(U2, "G2").user(U3, "G2").assertExpectations(); // 2. U2 is no longer known by the authentication service userManager = createUserManager(commonSpaces, logger, U2); - userManager.addGroup(group, principals(U1, U3)); + userManager.addGroup(group, users(U1, U3)); assertEquals(manage(userManager).getErrorReport(), ""); createBuilder(commonSpaces).adminUser(U1, "G2").unknownUser(U2).user(U3, "G2").assertExpectations(); // 3. U2 is reused and added to group G2 userManager = createUserManager(commonSpaces, logger); - userManager.addGroup(group, principals(U1, U2, U3)); + userManager.addGroup(group, users(U1, U2, U3)); + assertEquals(manage(userManager).getErrorReport(), ""); + createBuilder(commonSpaces).adminUser(U1, "G2").user(reuse(U2, "U2_2"), "G2").user(U3, "G2").assertExpectations(); + // 4. U2 is no longer known by the authentication service + userManager = createUserManager(commonSpaces, logger, U2); + userManager.addGroup(group, users(U1, U3)); + assertEquals(manage(userManager).getErrorReport(), ""); + createBuilder(commonSpaces).adminUser(U1, "G2").unknownUser(U2).user(U3, "G2").assertExpectations(); + // 5. U2 is reused and added to group G2 + userManager = createUserManager(commonSpaces, logger); + userManager.addGroup(group, users(U1, U2, U3)); // When UserManagerReport report = manage(userManager); // Then assertEquals(report.getErrorReport(), ""); - assertEquals(report.getAuditLog(), "1970-01-01 01:00:00 [REUSE-USER] u2 (home space: U2_1)\n" + assertEquals(report.getAuditLog(), "1970-01-01 01:00:00 [REUSE-USER] u2 (home space: U2_3)\n" + "1970-01-01 01:00:01 [ADD-USER-TO-AUTHORIZATION-GROUP] group: G2, user: u2\n" - + "1970-01-01 01:00:02 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for U2_1\n"); + + "1970-01-01 01:00:02 [ASSIGN-ROLE-TO-AUTHORIZATION-GROUP] group: G2_ADMIN, role: SPACE_ADMIN for U2_3\n"); UserManagerExpectationsBuilder builder = createBuilder(commonSpaces); builder.adminUser(U1, "G2"); - builder.user(reuse(U2, "U2_1"), "G2"); + builder.user(reuse(U2, "U2_3"), "G2"); builder.user(U3, "G2"); builder.assertExpectations(); } - private Principal reuse(Principal user, String homeSpace) + private Principal reuse(Principal user, String userSpacePostfix) { Map<String, String> props = new TreeMap<>(); - props.put(UserManagerExpectationsBuilder.HOME_SPACE_KEY, homeSpace); + props.put(UserManagerExpectationsBuilder.USER_SPACE_POSTFIX_KEY, userSpacePostfix); return new Principal(user.getUserId(), user.getFirstName(), user.getLastName(), user.getEmail(), true, props); } @@ -420,7 +783,9 @@ public class UserManagerTest extends AbstractTest return new Principal(user, "John", "Doe", "jd@abc.de"); } }; - return new UserManager(authenticationService, v3api, commonSpaces, logger, new MockTimeProvider(0, 1000)); + UserManager userManager = new UserManager(authenticationService, v3api, logger, new MockTimeProvider(0, 1000)); + userManager.setCommonSpacesByRole(commonSpaces); + return userManager; } private UserManagerExpectationsBuilder createBuilder(Map<Role, List<String>> commonSpaces) @@ -435,7 +800,7 @@ public class UserManagerTest extends AbstractTest return errorReport; } - private Map<String, Principal> principals(Principal... principals) + private Map<String, Principal> users(Principal... principals) { Map<String, Principal> map = new TreeMap<>(); for (Principal principal : principals)