Skip to content
PermissionsManager.java 7.06 KiB
Newer Older
package it.inaf.ia2.gms.manager;

import it.inaf.ia2.gms.exception.UnauthorizedException;
import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.model.RapUserPermission;
import it.inaf.ia2.gms.persistence.LoggingDAO;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.persistence.model.PermissionEntity;
import it.inaf.ia2.gms.service.PermissionUtils;
import it.inaf.ia2.gms.service.PermissionsService;
import it.inaf.ia2.gms.authn.RapClient;
Sonia Zorba's avatar
Sonia Zorba committed
import it.inaf.ia2.gms.persistence.model.ActionType;
import it.inaf.ia2.gms.service.GroupsService;
import it.inaf.ia2.rap.data.RapUser;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PermissionsManager extends UserAwareComponent {

    private final PermissionsService permissionsService;
    private final RapClient rapClient;
    private final LoggingDAO loggingDAO;

    @Autowired
    public PermissionsManager(PermissionsService permissionsService, RapClient rapClient, LoggingDAO loggingDAO) {
        this.permissionsService = permissionsService;
        this.rapClient = rapClient;
        this.loggingDAO = loggingDAO;
    }

    public List<RapUserPermission> getAllPermissions(GroupEntity group) {

        verifyUserCanManagePermissions(group);

        List<PermissionEntity> permissions = permissionsService.getGroupPermissions(group);

        Set<String> userIdentifiers = permissions.stream()
                .map(p -> p.getUserId())
                .collect(Collectors.toSet());

        List<RapUser> users = rapClient.getUsers(userIdentifiers);

        Map<String, RapUser> usersMap = users.stream()
                .collect(Collectors.toMap(RapUser::getId, Function.identity()));

        List<RapUserPermission> result = new ArrayList<>();

        for (PermissionEntity p : permissions) {
            RapUser rapUser = usersMap.get(p.getUserId());
                RapUserPermission permission = new RapUserPermission();
                permission.setPermission(p.getPermission());
                permission.setUser(rapUser);
                result.add(permission);
            }
        }

        return result;
    }

    public Permission getDirectUserPermission(GroupEntity group, String userId) {
        verifyUserCanManagePermissions(group);
        List<PermissionEntity> permissions = permissionsService.findUserPermissions(group, userId);
        for (PermissionEntity permission : permissions) {
            if (permission.getGroupId().equals(group.getId())) {
                return permission.getPermission();
            }
        }
        return null;
    }

    public PermissionEntity addPermission(GroupEntity group, String userId, Permission permission) {

        Permission currentUserPermission = getCurrentUserPermission(group);

        if (currentUserPermission == Permission.MANAGE_MEMBERS && permission == Permission.VIEW_MEMBERS) {
            // Automatically assign the VIEW_MEMBERS permission ("Add collaborator" feature)
            return permissionsService.addPermission(group, userId, Permission.VIEW_MEMBERS, getCurrentUserId());
        } else if (currentUserPermission == Permission.ADMIN) {
            // Admin users can specify a permission
            return permissionsService.addPermission(group, userId, permission, getCurrentUserId());
        }
        throw unauthorizedExceptionSupplier(group).get();
    public PermissionEntity createOrUpdatePermission(GroupEntity group, String userId, Permission permission) {
        verifyUserCanManagePermissions(group);
        return permissionsService.createOrUpdatePermission(group, userId, permission, getCurrentUserId());
    public PermissionEntity updatePermission(GroupEntity group, String userId, Permission permission) {
        verifyUserCanManagePermissions(group);
        return permissionsService.updatePermission(group, userId, permission, getCurrentUserId());
    }

    public void removePermission(GroupEntity group, String userId) {

        Permission currentUserPermission = getCurrentUserPermission(group);

        // For users having the MANAGE_MEMBERS permission, the VIEW_MEMBERS permission
        // is automatically assigned when they add a member ("Add collaborator" feature).
        // We want to keep also the reverse behavior.
        if (currentUserPermission == Permission.MANAGE_MEMBERS) {
            if (getUserPermission(group, userId, false) == Permission.VIEW_MEMBERS) {
                permissionsService.removePermission(group, userId);
            }
            // If the member permission is not VIEW_MEMBERS that means that it has been
            // changed by an ADMIN user, so we don't remove it.
        } else if (currentUserPermission == Permission.ADMIN) {
            permissionsService.removePermission(group, userId);
        } else {
            throw unauthorizedExceptionSupplier(group).get();
        }
    }

    public List<PermissionEntity> findUserPermissions(GroupEntity group, String userId) {
        verifyUserCanManagePermissions(group);
        return permissionsService.findUserPermissions(group, userId);
    }

    public Permission getUserPermission(GroupEntity group, String userId) {
        return getUserPermission(group, userId, true);
    }

    private Permission getUserPermission(GroupEntity group, String userId, boolean verify) {
        if (verify) {
            verifyUserCanManagePermissions(group);
        }
        List<PermissionEntity> permissions = permissionsService.findUserPermissions(group, userId);
        return PermissionUtils.getGroupPermission(group, permissions).orElse(null);
    }

    private void verifyUserCanManagePermissions(GroupEntity group) {
        Permission permission = getCurrentUserPermission(group);
        if (permission != Permission.ADMIN) {
            throw unauthorizedExceptionSupplier(group).get();
    private Supplier<UnauthorizedException> unauthorizedExceptionSupplier(GroupEntity group) {
Sonia Zorba's avatar
Sonia Zorba committed
        loggingDAO.logAction(ActionType.UNAUTHORIZED_ACCESS_ATTEMPT, "Unauthorized attempt to manage permissions [group_id=" + group.getId() + "]");
        return () -> new UnauthorizedException("You don't have the privileges for managing the requested permission");
    }

Sonia Zorba's avatar
Sonia Zorba committed
    public List<PermissionEntity> getCurrentUserPermissions() {
        return permissionsService.findUserPermissions(getCurrentUserId());
    }

    public List<PermissionEntity> getCurrentUserPermissions(GroupEntity group) {
        return permissionsService.findUserPermissions(group, getCurrentUserId());
    }

    public Permission getCurrentUserPermission(GroupEntity group) {
        List<PermissionEntity> permissions = permissionsService.findUserPermissions(group, getCurrentUserId());
        return PermissionUtils.getGroupPermission(group, permissions).orElse(
                GroupsService.ROOT.equals(group.getId()) ? Permission.TRAVERSE : null
        );