package sonia.scm.security; import javax.inject.Inject; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; public class PermissionAssigner { private final SecuritySystem securitySystem; @Inject public PermissionAssigner(SecuritySystem securitySystem) { this.securitySystem = securitySystem; } public Collection getAvailablePermissions() { PermissionPermissions.read().check(); return securitySystem.getAvailablePermissions(); } public Collection readPermissionsForUser(String id) { return readPermissions(filterForUser(id)); } public Collection readPermissionsForGroup(String id) { return readPermissions(filterForGroup(id)); } private Predicate filterForUser(String id) { return p -> !p.isGroupPermission() && p.getName().equals(id); } private Predicate filterForGroup(String id) { return p -> p.isGroupPermission() && p.getName().equals(id); } private Set readPermissions(Predicate predicate) { PermissionPermissions.read().check(); return securitySystem.getPermissions(predicate) .stream() .map(AssignedPermission::getPermission) .collect(Collectors.toSet()); } public void setPermissionsForUser(String id, Collection permissions) { Collection existingPermissions = securitySystem.getPermissions(filterForUser(id)); adaptPermissions(id, false, permissions, existingPermissions); } public void setPermissionsForGroup(String id, Collection permissions) { Collection existingPermissions = securitySystem.getPermissions(filterForGroup(id)); adaptPermissions(id, true, permissions, existingPermissions); } private void adaptPermissions(String id, boolean groupPermission, Collection permissions, Collection existingPermissions) { PermissionPermissions.assign().check(); List toRemove = existingPermissions.stream() .filter(p -> !permissions.contains(p.getPermission())) .collect(Collectors.toList()); toRemove.forEach(securitySystem::deletePermission); permissions.stream() .map(p -> new AssignedPermission(id, groupPermission, p)) .filter(p -> !existingPermissions.contains(p)) .forEach(securitySystem::addPermission); } }