1
0

uniform idnames (#28)

Co-authored-by: Michael Hoennig <michael@hoennig.de>
Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/28
Reviewed-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
This commit is contained in:
Michael Hoennig
2024-04-02 12:01:37 +02:00
parent f8fb273918
commit 7f418c12a1
90 changed files with 1207 additions and 1665 deletions

View File

@ -24,7 +24,10 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;

View File

@ -68,7 +68,7 @@ public class HsOfficePartnerDetailsEntity implements HasUuid, Stringifyable {
public static RbacView rbac() {
return rbacViewFor("partnerDetails", HsOfficePartnerDetailsEntity.class)
.withIdentityView(SQL.query("""
SELECT partnerDetails.uuid as uuid, partner_iv.idName || '-details' as idName
SELECT partnerDetails.uuid as uuid, partner_iv.idName as idName
FROM hs_office_partner_details AS partnerDetails
JOIN hs_office_partner partner ON partner.detailsUuid = partnerDetails.uuid
JOIN hs_office_partner_iv partner_iv ON partner_iv.uuid = partner.uuid

View File

@ -120,7 +120,7 @@ public class InsertTriggerGenerator {
}
},
() -> {
System.err.println("WARNING: no explicit INSERT grant for " + rbacDef.getRootEntityAlias().simpleName() + " => implicitly grant INSERT to global.admin");
System.err.println("WARNING: no explicit INSERT grant for " + rbacDef.getRootEntityAlias().simpleName() + " => implicitly grant INSERT to global:ADMIN");
generateInsertPermissionTriggerAllowOnlyGlobalAdmin(plPgSql);
});
}
@ -246,7 +246,7 @@ public class InsertTriggerGenerator {
}
private static String toVar(final RbacView.RbacRoleDefinition roleDef) {
return uncapitalize(roleDef.getEntityAlias().simpleName()) + capitalize(roleDef.getRole().roleName());
return uncapitalize(roleDef.getEntityAlias().simpleName()) + capitalize(roleDef.getRole().name());
}

View File

@ -113,7 +113,7 @@ public class RbacView {
* <p>An identity view is a view which maps an objectUuid to an idName.
* The idName should be a human-readable representation of the row, but as short as possible.
* The idName must only consist of letters (A-Z, a-z), digits (0-9), dash (-), dot (.) and unserscore '_'.
* It's used to create the object-specific-role-names like test_customer#abc.admin - here 'abc' is the idName.
* It's used to create the object-specific-role-names like test_customer#abc:ADMIN - here 'abc' is the idName.
* The idName not necessarily unique in a table, but it should be avoided.
* </p>
*
@ -882,15 +882,12 @@ public class RbacView {
TENANT,
REFERRER,
@Deprecated
GUEST;
@Override
public String toString() {
return ":" + roleName();
}
String roleName() {
return name().toLowerCase();
return ":" + name();
}
}

View File

@ -48,7 +48,7 @@ public class RbacViewMermaidFlowchartGenerator {
flowchart.indented( () -> {
rbacDef.getEntityAliases().values().stream()
.filter(e -> e.aliasName().startsWith(entity.aliasName() + "."))
.filter(e -> e.aliasName().startsWith(entity.aliasName() + ":"))
.forEach(this::renderEntitySubgraph);
wrapOutputInSubgraph(entity.aliasName() + ":roles", color,

View File

@ -333,7 +333,7 @@ class RolesGrantsAndPermissionsGenerator {
return "globalAdmin()";
}
final String entityRefVar = entityRefVar(rootRefVar, roleDef.getEntityAlias());
return roleDef.getEntityAlias().simpleName() + capitalize(roleDef.getRole().roleName())
return roleDef.getEntityAlias().simpleName() + capitalize(roleDef.getRole().name())
+ "(" + entityRefVar + ")";
}
@ -359,7 +359,7 @@ class RolesGrantsAndPermissionsGenerator {
plPgSql.indented(() -> {
plPgSql.writeLn("${simpleVarName)${roleSuffix}(NEW),"
.replace("${simpleVarName)", simpleEntityVarName)
.replace("${roleSuffix}", capitalize(role.roleName())));
.replace("${roleSuffix}", capitalize(role.name())));
generatePermissionsForRole(plPgSql, role);
@ -562,7 +562,7 @@ class RolesGrantsAndPermissionsGenerator {
}
private static String toRoleRef(final RbacView.RbacRoleDefinition roleDef) {
return uncapitalize(roleDef.getEntityAlias().simpleName()) + capitalize(roleDef.getRole().roleName());
return uncapitalize(roleDef.getEntityAlias().simpleName()) + capitalize(roleDef.getRole().name());
}
private static String toTriggerReference(

View File

@ -59,9 +59,9 @@ public class RbacGrantEntity {
}
public String toDisplay() {
return "{ grant role " + grantedRoleIdName +
" to user " + granteeUserName +
" by role " + grantedByRoleIdName +
return "{ grant role:" + grantedRoleIdName +
" to user:" + granteeUserName +
" by role:" + grantedByRoleIdName +
(assumed ? " and assume" : "") +
" }";
}

View File

@ -71,14 +71,14 @@ public class RbacGrantsDiagramService {
private void traverseGrantsTo(final Set<RawRbacGrantEntity> graph, final UUID refUuid, final EnumSet<Include> includes) {
final var grants = rawGrantRepo.findByAscendingUuid(refUuid);
grants.forEach(g -> {
if (!includes.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm ")) {
if (!includes.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm:")) {
return;
}
if ( !g.getDescendantIdName().startsWith("role global")) {
if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(" test_")) {
if ( !g.getDescendantIdName().startsWith("role:global")) {
if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(":test_")) {
return;
}
if (!includes.contains(NON_TEST_ENTITIES) && !g.getDescendantIdName().contains(" test_")) {
if (!includes.contains(NON_TEST_ENTITIES) && !g.getDescendantIdName().contains(":test_")) {
return;
}
}
@ -102,7 +102,7 @@ public class RbacGrantsDiagramService {
private void traverseGrantsFrom(final Set<RawRbacGrantEntity> graph, final UUID refUuid, final EnumSet<Include> option) {
final var grants = rawGrantRepo.findByDescendantUuid(refUuid);
grants.forEach(g -> {
if (!option.contains(USERS) && g.getAscendantIdName().startsWith("user ")) {
if (!option.contains(USERS) && g.getAscendantIdName().startsWith("user:")) {
return;
}
graph.add(g);
@ -171,7 +171,7 @@ public class RbacGrantsDiagramService {
}
if (refType.equals("role")) {
final var withoutRolePrefix = node.idName().substring("role:".length());
return withoutRolePrefix.substring(0, withoutRolePrefix.lastIndexOf('.'));
return withoutRolePrefix.substring(0, withoutRolePrefix.lastIndexOf(':'));
}
throw new IllegalArgumentException("unknown refType '" + refType + "' in '" + node.idName() + "'");
}
@ -188,23 +188,23 @@ public class RbacGrantsDiagramService {
return "(" + displayName + "\nref:" + uuid + ")";
}
if (refType.equals("role")) {
final var roleType = idName.substring(idName.lastIndexOf('.') + 1);
final var roleType = idName.substring(idName.lastIndexOf(':') + 1);
return "[" + roleType + "\nref:" + uuid + "]";
}
if (refType.equals("perm")) {
final var roleType = idName.split(" ")[1];
final var roleType = idName.split(":")[1];
return "{{" + roleType + "\nref:" + uuid + "}}";
}
return "";
}
private static String refType(final String idName) {
return idName.split(" ", 2)[0];
return idName.split(":", 2)[0];
}
@NotNull
private static String cleanId(final String idName) {
return idName.replace(" ", ":").replaceAll("@.*", "")
return idName.replaceAll("@.*", "")
.replace("[", "").replace("]", "").replace("(", "").replace(")", "").replace(",", "");
}

View File

@ -34,6 +34,6 @@ public class RbacRoleEntity {
@Enumerated(EnumType.STRING)
private RbacRoleType roleType;
@Formula("objectTable||'#'||objectIdName||'.'||roleType")
@Formula("objectTable||'#'||objectIdName||':'||roleType")
private String roleName;
}

View File

@ -1,5 +1,5 @@
package net.hostsharing.hsadminng.rbac.rbacrole;
public enum RbacRoleType {
owner, admin, agent, tenant, guest, referrer
OWNER, ADMIN, AGENT, TENANT, GUEST, REFERRER
}