package it.inaf.ia2.gms.service; import it.inaf.ia2.gms.manager.GroupsManager; import it.inaf.ia2.gms.model.Permission; import it.inaf.ia2.gms.model.response.PaginatedData; import it.inaf.ia2.gms.model.response.SearchResponseItem; import it.inaf.ia2.gms.model.response.SearchResponseType; import it.inaf.ia2.gms.model.response.UserGroup; import it.inaf.ia2.gms.model.response.UserPermission; import it.inaf.ia2.gms.model.response.UserSearchResponse; import it.inaf.ia2.gms.persistence.GroupsDAO; import it.inaf.ia2.gms.persistence.MembershipsDAO; import it.inaf.ia2.gms.persistence.PermissionsDAO; import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.persistence.model.PermissionEntity; import it.inaf.ia2.gms.authn.RapClient; import it.inaf.ia2.gms.model.request.GenericSearchRequest; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class SearchService { @Autowired private RapClient rapClient; @Autowired private GroupsManager groupsManager; @Autowired private GroupsDAO groupsDAO; @Autowired private PermissionsDAO permissionsDAO; @Autowired private MembershipsDAO membershipsDAO; @Autowired private GroupNameService groupNameService; /** * Generic search (both groups and users). */ public PaginatedData search(GenericSearchRequest searchRequest, String userId) { List items = new ArrayList<>(); if (searchRequest.isUsers()) { items.addAll(searchUsers(searchRequest.getQuery())); } if (searchRequest.isGroups()) { items.addAll(searchGroups(searchRequest.getQuery(), userId)); } // sort by label items.sort((i1, i2) -> i1.getLabel().compareTo(i2.getLabel())); return new PaginatedData<>(items, searchRequest.getPaginatorPage(), searchRequest.getPaginatorPageSize()); } private List searchUsers(String query) { return rapClient.getUsers(query).stream() .map(u -> { SearchResponseItem item = new SearchResponseItem(); item.setType(SearchResponseType.USER); item.setId(u.getId()); item.setLabel(u.getDisplayName()); return item; }) .collect(Collectors.toList()); } private List searchGroups(String query, String userId) { List allGroups = groupsDAO.searchGroups(query); // Select only the groups visible to the user List permissions = permissionsDAO.findUserPermissions(userId); Set visibleGroups = getVisibleGroups(allGroups, permissions); List items = new ArrayList<>(); Map> groupNames = groupNameService.getNames(visibleGroups); for (GroupEntity group : visibleGroups) { SearchResponseItem item = new SearchResponseItem(); item.setType(SearchResponseType.GROUP); item.setId(group.getId()); List names = groupNames.get(group.getId()); item.setLabel(String.join(" / ", names)); items.add(item); } return items; } /** * Retrieve additional data about an user displayed into the generic search. * * @param actorUserId the user who performed the search * @param targetUserId the user displayed into the search results */ public UserSearchResponse getUserSearchResult(String actorUserId, String targetUserId) { // Select only the information visible to the actor user List actorPermissions = permissionsDAO.findUserPermissions(actorUserId); UserSearchResponse response = new UserSearchResponse(); List groups = getUserGroups(targetUserId, actorPermissions); sortByGroupCompleteName(groups); response.setGroups(groups); List permissions = getUserPermission(groupsManager.getRoot(), targetUserId, actorPermissions); sortByGroupCompleteName(permissions); response.setPermissions(permissions); response.setUser(rapClient.getUser(targetUserId)); return response; } private List getUserGroups(String targetUserId, List actorPermissions) { List allGroups = membershipsDAO.getUserMemberships(targetUserId); // Select only groups visible to the actor user Set visibleGroups = getVisibleGroups(allGroups, actorPermissions); return groupNameService.getNames(visibleGroups).entrySet().stream() .map(entry -> { UserGroup ug = new UserGroup(); ug.setGroupId(entry.getKey()); ug.setGroupCompleteName(entry.getValue()); return ug; }) .collect(Collectors.toList()); } private Set getVisibleGroups(List allGroups, List permissions) { return allGroups.stream() .filter(g -> PermissionUtils.getGroupPermission(g, permissions).isPresent()) .collect(Collectors.toSet()); } public List getUserPermission(GroupEntity group, String targetUserId, List actorPermissions) { List permissions = new ArrayList<>(); // Super-admin user is able to see also other user permissions PermissionUtils.getGroupPermission(group, actorPermissions).ifPresent(permission -> { if (permission.equals(Permission.ADMIN)) { Map targetUserPermissions = permissionsDAO.findUserPermissions(targetUserId).stream() .collect(Collectors.toMap(PermissionEntity::getGroupId, p -> p)); Set groupIds = targetUserPermissions.values().stream() .map(p -> p.getGroupId()).collect(Collectors.toSet()); for (Map.Entry> entry : groupNameService.getNamesFromIds(groupIds).entrySet()) { UserPermission up = new UserPermission(); up.setGroupId(entry.getKey()); up.setGroupCompleteName(entry.getValue()); up.setPermission(targetUserPermissions.get(entry.getKey()).getPermission()); permissions.add(up); } } }); return permissions; } private void sortByGroupCompleteName(List items) { items.sort((i1, i2) -> { String completeName1 = String.join(" / ", i1.getGroupCompleteName()); String completeName2 = String.join(" / ", i2.getGroupCompleteName()); return completeName1.compareTo(completeName2); }); } }