package org.molgenis.ui.admin.usermanager; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import org.molgenis.auth.*; import org.molgenis.data.DataService; import org.molgenis.data.Query; import org.molgenis.data.support.QueryImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.toList; import static org.molgenis.auth.GroupMemberMetaData.GROUP_MEMBER; import static org.molgenis.auth.GroupMetaData.GROUP; import static org.molgenis.auth.UserMetaData.USER; /** * Manage user in groups */ @Service public class UserManagerServiceImpl implements UserManagerService { private final DataService dataService; private final GroupMemberFactory groupMemberFactory; @Autowired public UserManagerServiceImpl(DataService dataService, GroupMemberFactory groupMemberFactory) { this.dataService = requireNonNull(dataService); this.groupMemberFactory = requireNonNull(groupMemberFactory); } @Override @PreAuthorize("hasAnyRole('ROLE_SU')") @Transactional(readOnly = true) public List<UserViewData> getAllUsers() { Stream<User> users = dataService.findAll(USER, User.class); return this.parseToMolgenisUserViewData(users); } @Override @PreAuthorize("hasAnyRole('ROLE_SU')") @Transactional public void setActivationUser(String userId, Boolean active) { User mu = this.dataService.findOneById(USER, userId, User.class); mu.setActive(active); this.dataService.update(USER, mu); } @Override @PreAuthorize("hasAnyRole('ROLE_SU')") @Transactional public void setActivationGroup(String groupId, Boolean active) { Group mg = this.dataService.findOneById(GROUP, groupId, Group.class); mg.setActive(active); this.dataService.update(GROUP, mg); } @Override @PreAuthorize("hasAnyRole('ROLE_SU')") @Transactional(readOnly = true) public List<Group> getAllGroups() { return dataService.findAll(GROUP, Group.class).collect(toList()); } @Override @PreAuthorize("hasAnyRole('ROLE_SU')") @Transactional(readOnly = true) public List<Group> getGroupsWhereUserIsMember(String userId) { return this.getMolgenisGroups(userId); } @Override @PreAuthorize("hasAnyRole('ROLE_SU')") @Transactional(readOnly = true) public List<UserViewData> getUsersMemberInGroup(String groupId) { return this.parseToMolgenisUserViewData(this.getMolgenisUsers(groupId).stream()); } private List<Group> getMolgenisGroups(String userId) { final User user = dataService.findOneById(USER, userId, User.class); if (user == null) { throw new RuntimeException("unknown user id [" + userId + "]"); } final List<GroupMember> groupMembers = dataService.findAll(GROUP_MEMBER, new QueryImpl<GroupMember>().eq(GroupMemberMetaData.USER, user), GroupMember.class).collect(toList()); return this.getAllMolgenisGroupsFromGroupMembers(groupMembers); } private List<User> getMolgenisUsers(final String groupId) { final Group group = dataService.findOneById(GROUP, groupId, Group.class); if (group == null) { throw new RuntimeException("unknown user id [" + groupId + "]"); } final List<GroupMember> groupMembers = dataService.findAll(GROUP_MEMBER, new QueryImpl<GroupMember>().eq(GroupMemberMetaData.GROUP, group), GroupMember.class).collect(toList()); return this.getAllMolgenisUsersFromGroupMembers(groupMembers); } @Override @PreAuthorize("hasAnyRole('ROLE_SU')") @Transactional(readOnly = true) public List<Group> getGroupsWhereUserIsNotMember(final String userId) { final User user = dataService.findOneById(USER, userId, User.class); if (user == null) { throw new RuntimeException("unknown user id [" + userId + "]"); } final List<GroupMember> groupMembers = dataService.findAll(GROUP_MEMBER, new QueryImpl<GroupMember>().eq(GroupMemberMetaData.USER, user), GroupMember.class).collect(toList()); final List<Group> groupsWhereUserIsMember = this.getAllMolgenisGroupsFromGroupMembers(groupMembers); Predicate<Group> predicate = new PredicateNotInMolgenisGroupList(groupsWhereUserIsMember); List<Group> groups = this.getAllGroups(); return Lists.<Group>newArrayList(Iterables.filter(groups, predicate)); } @Override @PreAuthorize("hasAnyRole('ROLE_SU')") @Transactional public void addUserToGroup(String molgenisGroupId, String molgenisUserId) { Group group = dataService.findOneById(GROUP, molgenisGroupId, Group.class); User user = dataService.findOneById(USER, molgenisUserId, User.class); GroupMember groupMember = groupMemberFactory.create(); groupMember.setGroup(group); groupMember.setUser(user); dataService.add(GROUP_MEMBER, groupMember); } @Override @PreAuthorize("hasAnyRole('ROLE_SU')") @Transactional public void removeUserFromGroup(String molgenisGroupId, String molgenisUserId) { final User user = dataService.findOneById(USER, molgenisUserId, User.class); if (user == null) { throw new RuntimeException("unknown user id [" + molgenisUserId + "]"); } final Group group = dataService .findOneById(GROUP, molgenisGroupId, Group.class); if (group == null) { throw new RuntimeException("unknown user id [" + molgenisGroupId + "]"); } Query<GroupMember> q = new QueryImpl<GroupMember>() .eq(GroupMemberMetaData.USER, user).and() .eq(GroupMemberMetaData.GROUP, group); final List<GroupMember> groupMembers = dataService .findAll(GROUP_MEMBER, q, GroupMember.class).collect(toList()); if (null == groupMembers || groupMembers.isEmpty()) { throw new RuntimeException("molgenis group member is not found"); } if (groupMembers.size() > 1) { throw new RuntimeException("there are more than one group member found"); } GroupMember groupMember = groupMembers.get(0); dataService.delete(GROUP_MEMBER, groupMember); } /** * Get All the molgenis groups from the list of molgenis group members * * @param groupMembers A list of MolgenisGroupMember instances * @return List<MolgenisGroup> */ private List<Group> getAllMolgenisGroupsFromGroupMembers(final List<GroupMember> groupMembers) { List<Group> groups = new ArrayList<Group>(); if (groupMembers != null && !groupMembers.isEmpty()) { groups = Lists.transform(groupMembers, new Function<GroupMember, Group>() { @Override public Group apply(GroupMember groupMember) { return groupMember.getGroup(); } }); } return groups; } /** * Get All the molgenis users from the list of molgenis group members * * @param groupMembers A list of MolgenisGroupMember instances * @return List<MolgenisUser> */ private List<User> getAllMolgenisUsersFromGroupMembers(final List<GroupMember> groupMembers) { List<User> user = new ArrayList<User>(); if (groupMembers != null && !groupMembers.isEmpty()) { user = Lists.transform(groupMembers, new Function<GroupMember, User>() { @Override public User apply(GroupMember groupMember) { return groupMember.getUser(); } }); } return user; } private static class PredicateNotInMolgenisGroupList implements Predicate<Group> { final List<Group> toFilterItemList; PredicateNotInMolgenisGroupList(List<Group> notInList) { this.toFilterItemList = notInList; } @Override public boolean apply(Group item) { Object id = item.getId(); for (Group toFilterItem : toFilterItemList) { if (toFilterItem.getId().equals(id)) return false; } return true; } } private List<UserViewData> parseToMolgenisUserViewData(Stream<User> users) { return users.map(user -> new UserViewData(user, getMolgenisGroups(user.getId()))).collect(toList()); } }