diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java index 30953c7b..50175146 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java @@ -4,6 +4,7 @@ import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacPermissionDefinition; import org.apache.commons.lang3.StringUtils; import jakarta.persistence.Table; +import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; @@ -17,6 +18,7 @@ import static org.apache.commons.lang3.StringUtils.uncapitalize; class RolesGrantsAndPermissionsGenerator { private final RbacView rbacDef; + private final Set rbacGrants = new HashSet<>(); private final String liquibaseTagPrefix; private final Class entityClass; private final String simpleEntityName; @@ -25,6 +27,7 @@ class RolesGrantsAndPermissionsGenerator { RolesGrantsAndPermissionsGenerator(final RbacView rbacDef, final String liquibaseTagPrefix) { this.rbacDef = rbacDef; + this.rbacGrants.addAll(rbacGrants); this.liquibaseTagPrefix = liquibaseTagPrefix; entityClass = rbacDef.getEntityAlias().entityClass(); @@ -101,22 +104,26 @@ class RolesGrantsAndPermissionsGenerator { .replace("%{simpleEntityVarName)", simpleEntityVarName) .replace("%{roleSuffix}", capitalize(role.roleName()))); - final var permissionsForRole = findPermissionsGrantsForRole(rbacDef.getEntityAlias(), role); - if (!permissionsForRole.isEmpty()) { - final var permissionsForRoleInPlPgSql = permissionsForRole.stream() + final var permissionGrantsForRole = findPermissionsGrantsForRole(rbacDef.getEntityAlias(), role); + if (!permissionGrantsForRole.isEmpty()) { + final var permissionsForRoleInPlPgSql = permissionGrantsForRole.stream() + .map(RbacView.RbacGrantDefinition::getPermDef) .map(RbacPermissionDefinition::getPermission) .map(RbacView.Permission::permission) .map(p -> "'" + p + "'") .collect(joining(", ")); plPgSql.append(indent(3) + "permissions => array[" + permissionsForRoleInPlPgSql + "],\n"); + rbacGrants.removeAll(permissionGrantsForRole); } final var grantsToUsers = findGrantsToUserForRole(rbacDef.getEntityAlias(), role); if (!grantsToUsers.isEmpty()) { final var grantsToUsersPlPgSql = grantsToUsers.stream() - .map(u -> toPlPgSqlReference(u)) + .map(RbacView.RbacGrantDefinition::getUserDef) + .map(this::toPlPgSqlReference) .collect(joining(", ")); plPgSql.append(indent(3) + "userUuids => array[" + grantsToUsersPlPgSql + "],\n"); + rbacGrants.removeAll(grantsToUsers); } final var incomingGrants = findIncomingSuperRolesForRole(rbacDef.getEntityAlias(), role); @@ -126,6 +133,7 @@ class RolesGrantsAndPermissionsGenerator { .map(r -> toPlPgSqlReference(NEW, r)) .collect(joining(", ")); plPgSql.append(indent(3) + "incomingSuperRoles => array[" + incomingGrantsInPlPgSql + "],\n"); + rbacGrants.removeAll(incomingGrants); } final var outgoingGrants = findOutgoingSuperRolesForRole(rbacDef.getEntityAlias(), role); @@ -135,38 +143,41 @@ class RolesGrantsAndPermissionsGenerator { .map(r -> toPlPgSqlReference(NEW, r)) .collect(joining(", ")); plPgSql.append(indent(3) + "outgoingSubRoles => array[" + outgoingGrantsInPlPgSql + "],\n"); + rbacGrants.removeAll(outgoingGrants); + } + + if (!rbacGrants.isEmpty()) { + throw new IllegalStateException("unprocessed grants: " + rbacGrants); } chopTail(plPgSql, ",\n"); plPgSql.append("\n" + indent(2) + ");\n"); } - private Set findPermissionsGrantsForRole(final RbacView.EntityAlias entityAlias, final RbacView.Role role) { + private Set findPermissionsGrantsForRole(final RbacView.EntityAlias entityAlias, final RbacView.Role role) { final var roleDef = rbacDef.findRbacRole(entityAlias, role); - return rbacDef.getGrantDefs().stream() + return rbacGrants.stream() .filter(g -> g.grantType() == ROLE_TO_PERM && g.getSuperRoleDef()==roleDef ) - .map(RbacView.RbacGrantDefinition::getPermDef) .collect(Collectors.toSet()); } - private Set findGrantsToUserForRole(final RbacView.EntityAlias entityAlias, final RbacView.Role role) { + private Set findGrantsToUserForRole(final RbacView.EntityAlias entityAlias, final RbacView.Role role) { final var roleDef = rbacDef.findRbacRole(entityAlias, role); - return rbacDef.getGrantDefs().stream() + return rbacGrants.stream() .filter(g -> g.grantType() == USER_TO_ROLE && g.getSubRoleDef() == roleDef ) - .map(RbacView.RbacGrantDefinition::getUserDef) .collect(Collectors.toSet()); } private Set findIncomingSuperRolesForRole(final RbacView.EntityAlias entityAlias, final RbacView.Role role) { final var roleDef = rbacDef.findRbacRole(entityAlias, role); - return rbacDef.getGrantDefs().stream() + return rbacGrants.stream() .filter(g -> g.grantType() == ROLE_TO_ROLE && g.getSubRoleDef()==roleDef ) .collect(Collectors.toSet()); } private Set findOutgoingSuperRolesForRole(final RbacView.EntityAlias entityAlias, final RbacView.Role role) { final var roleDef = rbacDef.findRbacRole(entityAlias, role); - return rbacDef.getGrantDefs().stream() + return rbacGrants.stream() .filter(g -> g.grantType() == ROLE_TO_ROLE && g.getSuperRoleDef()==roleDef ) .filter(g -> g.getSubRoleDef().getEntityAlias() != entityAlias) .collect(Collectors.toSet());