Skip to content
GroupsService.java 5.89 KiB
Newer Older
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.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;

    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);


    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.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<GroupEntity> groupsToDelete = groupsDAO.getAllChildren(group.getPath());
        groupsToDelete.add(group);
        List<String> 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());

    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<GroupBreadcrumb> getBreadcrumbs(String path) {
        return groupsDAO.getBreadcrumbs(path);
    public Optional<GroupEntity> 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<GroupEntity> findGroupByNames(List<String> 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<GroupEntity> 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<GroupEntity> groups, String parentPath, String groupName) {
        for (GroupEntity group : groups) {
            if (parentPath.equals(group.getParentPath()) && groupName.equals(group.getName())) {
                return group;
            }
        }
        return null;
    }
    public List<GroupEntity> searchGroups(String searchText) {
        return groupsDAO.searchGroups(searchText);
    }