diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacViewMermaidFlowchart.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacViewMermaidFlowchart.java index fcc8a83f..9acf5df4 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacViewMermaidFlowchart.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacViewMermaidFlowchart.java @@ -16,9 +16,10 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinitio public class RbacViewMermaidFlowchart { - public static final String HOSTSHARING_ORANGE = "#dd4901"; - public static final String HOSTSHARING_ORANGE_LIGHT = "#feb28c"; - public static final String HOSTSHARING_LIGHTBLUE = "#99bcdb"; + public static final String HOSTSHARING_DARK_ORANGE = "#dd4901"; + public static final String HOSTSHARING_LIGHT_ORANGE = "#feb28c"; + public static final String HOSTSHARING_DARK_BLUE = "#274d6e"; + public static final String HOSTSHARING_LIGHT_BLUE = "#99bcdb"; private final RbacView rbacDef; private final StringWriter flowchart = new StringWriter(); @@ -39,9 +40,9 @@ public class RbacViewMermaidFlowchart { } private void renderEntitySubgraph(final RbacView.EntityAlias entity) { - final var color = rbacDef.isRootEntityAlias(entity) ? HOSTSHARING_ORANGE - : entity.isSubEntity() ? HOSTSHARING_ORANGE_LIGHT - : HOSTSHARING_LIGHTBLUE; + final var color = rbacDef.isRootEntityAlias(entity) ? HOSTSHARING_DARK_ORANGE + : entity.isSubEntity() ? HOSTSHARING_LIGHT_ORANGE + : HOSTSHARING_LIGHT_BLUE; flowchart.writeLn(""" subgraph %{aliasName}["`**%{aliasName}**`"] direction TB @@ -79,7 +80,7 @@ public class RbacViewMermaidFlowchart { private void wrapOutputInSubgraph(final String name, final String color, final String content) { if (!StringUtils.isEmpty(content)) { - flowchart.emptyLine(); + flowchart.ensureEmptyLine(); flowchart.writeLn("subgraph " + name + "[ ]\n"); flowchart.indented(() -> { flowchart.writeLn("style %{aliasName} fill: %{color}" @@ -105,7 +106,7 @@ public class RbacViewMermaidFlowchart { .filter(g -> g.grantType() == f) .toList(); if ( !userGrants.isEmpty()) { - flowchart.emptyLine(); + flowchart.ensureEmptyLine(); flowchart.writeLn(t); userGrants.forEach(g -> flowchart.writeLn(grantDef(g))); } 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 0ae74bd7..6801d5d4 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java @@ -97,9 +97,9 @@ class RolesGrantsAndPermissionsGenerator { createRolesWithGrantsSql(plPgSql, TENANT); createRolesWithGrantsSql(plPgSql, REFERRER); - plPgSql.writeLn(); - // TODO: we need to group and sort the grants, similar to the Flowchart generator - rbacGrants.forEach(g -> plPgSql.writeLn(generateGrant(g))); + generateGrants(plPgSql, ROLE_TO_USER); + generateGrants(plPgSql, ROLE_TO_ROLE); + generateGrants(plPgSql, PERM_TO_ROLE); plPgSql.writeLn("return NEW;"); }); @@ -108,6 +108,15 @@ class RolesGrantsAndPermissionsGenerator { plPgSql.writeLn(); } + private void generateGrants(final StringWriter plPgSql, final RbacView.RbacGrantDefinition.GrantType grantType) { + plPgSql.ensureEmptyLine(); + rbacGrants.stream() + .filter(g -> g.grantType() == grantType) + .map(this::generateGrant) + .sorted() + .forEach(plPgSql::writeLn); + } + private String generateGrant(RbacView.RbacGrantDefinition grantDef) { return switch (grantDef.grantType()) { case ROLE_TO_USER -> throw new IllegalArgumentException("unexpected grant"); diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/StringWriter.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/StringWriter.java index 6e615dba..9ee873ec 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/StringWriter.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/StringWriter.java @@ -58,7 +58,7 @@ public class StringWriter { }; } - void emptyLine() { + void ensureEmptyLine() { if (!string.toString().endsWith("\n\n")) { writeLn(); }