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; 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 getAllPermissions(GroupEntity group) { verifyUserCanManagePermissions(group); List permissions = permissionsService.getGroupPermissions(group); Set userIdentifiers = permissions.stream() .map(p -> p.getUserId()) .collect(Collectors.toSet()); List users = rapClient.getUsers(userIdentifiers); Map usersMap = users.stream() .collect(Collectors.toMap(RapUser::getId, Function.identity())); List result = new ArrayList<>(); for (PermissionEntity p : permissions) { RapUser rapUser = usersMap.get(p.getUserId()); if (rapUser != null) { 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 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 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 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 unauthorizedExceptionSupplier(GroupEntity group) { 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"); } public List getCurrentUserPermissions() { return permissionsService.findUserPermissions(getCurrentUserId()); } public List getCurrentUserPermissions(GroupEntity group) { return permissionsService.findUserPermissions(group, getCurrentUserId()); } public Permission getCurrentUserPermission(GroupEntity group) { List permissions = permissionsService.findUserPermissions(group, getCurrentUserId()); return PermissionUtils.getGroupPermission(group, permissions).orElse( GroupsService.ROOT.equals(group.getId()) ? Permission.TRAVERSE : null ); } }