package it.inaf.ia2.gms.service; import it.inaf.ia2.gms.exception.BadRequestException; import it.inaf.ia2.gms.persistence.GroupsRepository; import it.inaf.ia2.gms.persistence.UsersRepository; import it.inaf.ia2.gms.persistence.model.Group; import it.inaf.ia2.gms.persistence.model.User; import it.inaf.ia2.gms.persistence.model.UserGroup; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import it.inaf.ia2.gms.persistence.PermissionsRepository; import it.inaf.ia2.gms.service.model.GroupNode; import it.inaf.ia2.gms.service.model.Permission; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.UUID; @Service public class GroupsService { public static final String ROOT = "ROOT"; private final GroupsRepository groupsRepository; private final UsersRepository usersRepository; private final PermissionsRepository permissionsRepository; @Autowired public GroupsService(GroupsRepository groupsRepository, UsersRepository usersRepository, PermissionsRepository permissionsRepository) { this.groupsRepository = groupsRepository; this.usersRepository = usersRepository; this.permissionsRepository = permissionsRepository; createRootIfNecessary(); } private void createRootIfNecessary() { if (groupsRepository.count() == 0) { Group root = new Group(); root.setId(ROOT); root.setName(ROOT); groupsRepository.save(root); } } public Group addGroup(String parentId, String groupName) { Group parent = getGroupById(parentId); Group group = new Group(); group.setId(UUID.randomUUID().toString()); group.setName(groupName); group.setParentGroup(parent); parent.getGroupsMembers().add(group); group = groupsRepository.save(group); groupsRepository.save(parent); return group; } public List getSubgroups(String parentId) { Group parent = getGroupById(parentId); return groupsRepository.findByParentGroup(parent); } public List getSubgroups(String parentGroupId, String userId) { User user = usersRepository.findById(userId) .orElseThrow(() -> new BadRequestException("User " + userId + " not found")); Group parent = getGroupById(parentGroupId); List permissions = permissionsRepository.findBy_user(user); Map nodes = new LinkedHashMap<>(); for (Group childGroup : parent.getGroupsMembers()) { Iterator ite = permissions.iterator(); while (ite.hasNext()) { UserGroup permission = ite.next(); boolean isChild = false; if (permission.getGroup().getId().equals(childGroup.getId()) || (isChild = isChildOf(permission.getGroup(), parentGroupId))) { GroupNode node = nodes.get(childGroup.getId()); if (node == null) { node = getGroupNode(childGroup); } if (isChild) { // Traversal only node.getPermissions().add(Permission.READ); } else { // Direct permission node.getPermissions().add(permission.getPermission()); } nodes.put(childGroup.getId(), node); ite.remove(); } } } // TODO: pagination return new ArrayList<>(nodes.values()); } private GroupNode getGroupNode(Group group) { GroupNode node = new GroupNode(); node.setGroupId(group.getId()); node.setGroupName(group.getName()); node.setHasChildren(!group.getGroupsMembers().isEmpty()); return node; } private boolean isChildOf(Group group, String parentGroupId) { Group parent = group.getParentGroup(); if (parent == null) { // ROOT has no parent return false; } if (parentGroupId.equals(parent.getId())) { return true; } // recursive call to parent group return isChildOf(parent, parentGroupId); } private Group getGroupById(String groupId) { return groupsRepository.findById(groupId) .orElseThrow(() -> new BadRequestException("Group " + groupId + " not found")); } }