package it.inaf.ia2.gms.service; import it.inaf.ia2.gms.exception.BadRequestException; import it.inaf.ia2.gms.exception.UnauthorizedException; import it.inaf.ia2.gms.model.GroupBreadcrumb; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import it.inaf.ia2.gms.persistence.GroupsDAO; import it.inaf.ia2.gms.persistence.LoggingDAO; import it.inaf.ia2.gms.persistence.MembershipsDAO; import it.inaf.ia2.gms.persistence.PermissionsDAO; import it.inaf.ia2.gms.persistence.model.GroupEntity; import java.util.List; import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; @Service public class GroupsService { public static final String ROOT = "ROOT"; private final GroupsDAO groupsDAO; private final PermissionsDAO permissionsDAO; private final MembershipsDAO membershipsDAO; private final LoggingDAO loggingDAO; @Autowired public GroupsService(GroupsDAO groupsDAO, PermissionsDAO permissionsDAO, MembershipsDAO membershipsDAO, LoggingDAO loggingDAO) { this.groupsDAO = groupsDAO; this.permissionsDAO = permissionsDAO; this.membershipsDAO = membershipsDAO; this.loggingDAO = loggingDAO; createRootIfNecessary(); } private void createRootIfNecessary() { if (groupsDAO.count() == 0) { GroupEntity root = new GroupEntity(); root.setId(ROOT); root.setName(ROOT); root.setPath(""); groupsDAO.createGroup(root); } } public GroupEntity addGroup(GroupEntity parent, String groupName, boolean leaf) { if (groupsDAO.getDirectSubGroups(parent.getPath()).stream() .anyMatch(g -> g.getName().equals(groupName))) { throw new BadRequestException("There is already a group named " + groupName); } String newGroupId = UUID.randomUUID().toString().replaceAll("-", ""); String path = parent.getPath(); if (!path.isEmpty()) { path += "."; } path += newGroupId; GroupEntity group = new GroupEntity(); group.setId(newGroupId); group.setName(groupName); group.setPath(path); group.setLeaf(leaf); groupsDAO.createGroup(group); loggingDAO.logAction("Added group: parent_path=" + parent.getPath() + ", group_name=" + groupName); return group; } public GroupEntity updateGroup(GroupEntity group, String newGroupName, boolean leaf) { if (groupsDAO.getDirectSubGroups(group.getPath()).stream() .anyMatch(g -> g.getName().equals(newGroupName))) { throw new BadRequestException("There is already a group named " + newGroupName); } group.setName(newGroupName); group.setLeaf(leaf); GroupEntity entity = groupsDAO.updateGroup(group); loggingDAO.logAction("Group updated, group_id=" + group.getId() + ", new name: " + newGroupName + ", leaf: " + leaf); return entity; } public GroupEntity deleteGroup(GroupEntity group) { if (ROOT.equals(group.getId())) { throw new UnauthorizedException("It is not possible to remove the ROOT"); } String parentPath = group.getParentPath(); GroupEntity parent = groupsDAO.findGroupByPath(parentPath) .orElseThrow(() -> new BadRequestException("No group found at path " + parentPath)); List groupsToDelete = groupsDAO.getAllChildren(group.getPath()); groupsToDelete.add(group); List groupsToDeleteIds = groupsToDelete.stream() .map(g -> g.getId()).collect(Collectors.toList()); membershipsDAO.deleteAllGroupsMembership(groupsToDeleteIds); permissionsDAO.deleteAllGroupsPermissions(groupsToDeleteIds); for (GroupEntity g : groupsToDelete) { groupsDAO.deleteGroup(g); } loggingDAO.logAction("Group deleted, group_id=" + group.getId()); return parent; } public GroupEntity getGroupById(String groupId) { return groupsDAO.findGroupById(groupId) .orElseThrow(() -> new BadRequestException("Group " + groupId + " not found")); } public GroupEntity getGroupByPath(String path) { return groupsDAO.findGroupByPath(path) .orElseThrow(() -> new BadRequestException("Group not found at path " + path)); } public List getBreadcrumbs(String path) { return groupsDAO.getBreadcrumbs(path); } public Optional findGroupByParentAndName(GroupEntity parent, String childName) { return groupsDAO.findGroupByParentAndName(parent.getPath(), childName); } /** * Retrieves a group given the sequence of group names corresponding to its * path. */ public Optional findGroupByNames(List names) { // There can be groups with the same name under different parents, so // after retrieving this list it is necessary to match for the correct // group List groups = groupsDAO.findGroupsByNames(names); String parentPath = ""; GroupEntity group = null; for (String name : names) { group = findGroup(groups, parentPath, name); if (group == null) { break; } else { parentPath = group.getPath(); } } return Optional.ofNullable(group); } private GroupEntity findGroup(List groups, String parentPath, String groupName) { for (GroupEntity group : groups) { if (parentPath.equals(group.getParentPath()) && groupName.equals(group.getName())) { return group; } } return null; } public List searchGroups(String searchText) { return groupsDAO.searchGroups(searchText); } }