package it.inaf.ia2.gms.service; 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.rap.RapClient; import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.List; import java.util.Map; 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 GroupsService groupsService; @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(String query, String userId, int page, int pageSize) { List items = searchUsers(query); items.addAll(searchGroups(query, userId)); // sort by label items.sort((i1, i2) -> i1.getLabel().compareTo(i2.getLabel())); return new PaginatedData<>(items, page, pageSize); } private List searchUsers(String query) { return rapClient.searchUsers(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); List> groupsIdPath = new ArrayList<>(); for (GroupEntity group : allGroups) { PermissionUtils.getGroupPermission(group, permissions).ifPresent(permission -> { groupsIdPath.add(new SimpleEntry<>(group.getId(), group.getPath())); }); } List items = new ArrayList<>(); Map> groupNames = groupNameService.getNames(groupsIdPath); for (Map.Entry entry : groupsIdPath) { String groupId = entry.getKey(); SearchResponseItem item = new SearchResponseItem(); item.setType(SearchResponseType.GROUP); item.setId(groupId); List names = groupNames.get(groupId); 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(); response.setGroups(getUserGroups(targetUserId, actorPermissions)); response.setPermissions(getUserPermission(targetUserId, actorPermissions)); return response; } private List getUserGroups(String targetUserId, List actorPermissions) { List allGroups = membershipsDAO.getUserMemberships(targetUserId); // Select only groups visible to the actor user List> visibleGroupsIdPath = new ArrayList<>(); for (GroupEntity group : allGroups) { PermissionUtils.getGroupPermission(group, actorPermissions).ifPresent(permission -> { visibleGroupsIdPath.add(new SimpleEntry<>(group.getId(), group.getPath())); }); } return groupNameService.getNames(visibleGroupsIdPath).entrySet().stream() .map(entry -> { UserGroup ug = new UserGroup(); ug.setGroupId(entry.getKey()); ug.setGroupCompleteName(entry.getValue()); return ug; }) .collect(Collectors.toList()); } private List getUserPermission(String targetUserId, List actorPermissions) { List permissions = new ArrayList<>(); // Super-admin user is able to see also other user permissions PermissionUtils.getGroupPermission(groupsService.getRoot(), actorPermissions).ifPresent(permission -> { if (permission.equals(Permission.ADMIN)) { Map targetUserPermissions = permissionsDAO.findUserPermissions(targetUserId).stream() .collect(Collectors.toMap(PermissionEntity::getGroupId, p -> p)); List> groupsIdPath = new ArrayList<>(); for (PermissionEntity p : targetUserPermissions.values()) { groupsIdPath.add(new SimpleEntry<>(p.getGroupId(), p.getGroupPath())); } for (Map.Entry> entry : groupNameService.getNames(groupsIdPath).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; } }