RBAC Diagram+PostgreSQL Generator #21
@ -1,7 +1,5 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@ -16,11 +14,11 @@ public class RbacViewMermaidFlowchart {
|
||||
public static final String HOSTSHARING_ORANGE = "#dd4901";
|
||||
public static final String HOSTSHARING_LIGHTBLUE = "#99bcdb";
|
||||
private final RbacView rbacDef;
|
||||
private final StringBuilder flowchart = new StringBuilder();
|
||||
private final StringWriter flowchart = new StringWriter();
|
||||
|
||||
public RbacViewMermaidFlowchart(final RbacView rbacDef) {
|
||||
this.rbacDef = rbacDef;
|
||||
flowchart.append("""
|
||||
flowchart.writeLn("""
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
""");
|
||||
@ -36,54 +34,63 @@ public class RbacViewMermaidFlowchart {
|
||||
|
||||
private void renderEntitySubgraph(final RbacView.EntityAlias entity) {
|
||||
final var color = rbacDef.isMainEntityAlias(entity) ? HOSTSHARING_ORANGE : HOSTSHARING_LIGHTBLUE;
|
||||
flowchart.append("""
|
||||
flowchart.writeLn("""
|
||||
|
||||
subgraph %{aliasName}["`**%{aliasName}**`"]
|
||||
direction TB
|
||||
style %{aliasName} fill:%{color},stroke:darkblue,stroke-width:8px
|
||||
|
||||
"""
|
||||
.replace("%{aliasName}", entity.aliasName())
|
||||
.replace("%{color}", color ));
|
||||
|
||||
rbacDef.getEntityAliases().values().stream()
|
||||
.filter(e -> e.aliasName().startsWith(entity.aliasName() + "."))
|
||||
.forEach(this::renderEntitySubgraph);
|
||||
flowchart.indented( () -> {
|
||||
rbacDef.getEntityAliases().values().stream()
|
||||
.filter(e -> e.aliasName().startsWith(entity.aliasName() + "."))
|
||||
.forEach(this::renderEntitySubgraph);
|
||||
|
||||
wrapOutputInSubgraph(entity.aliasName() + ":roles", color,
|
||||
rbacDef.getRoleDefs().stream()
|
||||
.filter(r -> r.getEntityAlias() == entity)
|
||||
.map(r -> " " + roleDef(r))
|
||||
.collect(joining("\n")));
|
||||
|
||||
wrapOutputInSubgraph(entity.aliasName() + ":permissions", color,
|
||||
rbacDef.getPermDefs().stream()
|
||||
.filter(p -> p.getEntityAlias() == entity)
|
||||
.map(p -> " " + permDef(p) )
|
||||
wrapOutputInSubgraph(entity.aliasName() + ":roles", color,
|
||||
rbacDef.getRoleDefs().stream()
|
||||
.filter(r -> r.getEntityAlias() == entity)
|
||||
.map(r -> " " + roleDef(r))
|
||||
.collect(joining("\n")));
|
||||
|
||||
if (rbacDef.isMainEntityAlias(entity) && rbacDef.getEntityAliasProxy() != null ) {
|
||||
renderEntitySubgraph(rbacDef.getEntityAliasProxy());
|
||||
}
|
||||
wrapOutputInSubgraph(entity.aliasName() + ":permissions", color,
|
||||
rbacDef.getPermDefs().stream()
|
||||
.filter(p -> p.getEntityAlias() == entity)
|
||||
.map(p -> " " + permDef(p) )
|
||||
.collect(joining("\n")));
|
||||
|
||||
flowchart.append("end\n\n");
|
||||
if (rbacDef.isMainEntityAlias(entity) && rbacDef.getEntityAliasProxy() != null ) {
|
||||
renderEntitySubgraph(rbacDef.getEntityAliasProxy());
|
||||
}
|
||||
|
||||
});
|
||||
flowchart.chopEmptyLines();
|
||||
flowchart.writeLn("end");
|
||||
flowchart.writeLn();
|
||||
}
|
||||
|
||||
private void wrapOutputInSubgraph(final String name, final String color, final String content) {
|
||||
if (!StringUtils.isEmpty(content)) {
|
||||
flowchart.append("subgraph " + name + "[ ]\n");
|
||||
flowchart.append("style %{aliasName} fill: %{color}\n\n"
|
||||
.replace("%{aliasName}", name)
|
||||
.replace("%{color}", color));
|
||||
flowchart.append(content);
|
||||
flowchart.append("\nend\n\n");
|
||||
flowchart.emptyLine();
|
||||
flowchart.writeLn("subgraph " + name + "[ ]\n");
|
||||
flowchart.indented(() -> {
|
||||
flowchart.writeLn("style %{aliasName} fill: %{color}"
|
||||
.replace("%{aliasName}", name)
|
||||
.replace("%{color}", color));
|
||||
flowchart.writeLn();
|
||||
flowchart.writeLn(content);
|
||||
});
|
||||
flowchart.chopEmptyLines();
|
||||
flowchart.writeLn("end");
|
||||
flowchart.writeLn();
|
||||
}
|
||||
}
|
||||
|
||||
private void renderGrants() {
|
||||
rbacDef.getGrantDefs()
|
||||
.forEach(g -> {
|
||||
flowchart.append(grantDef(g) + "\n" );
|
||||
flowchart.writeLn(grantDef(g) + "\n");
|
||||
});
|
||||
}
|
||||
|
||||
@ -141,8 +148,8 @@ public class RbacViewMermaidFlowchart {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
new RbacViewMermaidFlowchart(HsOfficeBankAccountEntity.rbac()).generateToMarkdownFile();
|
||||
// new RbacViewMermaidFlowchart(HsOfficeBankAccountEntity.rbac()).generateToMarkdownFile();
|
||||
new RbacViewMermaidFlowchart(HsOfficeRelationshipEntity.rbac()).generateToMarkdownFile();
|
||||
new RbacViewMermaidFlowchart(HsOfficeDebitorEntity.rbac()).generateToMarkdownFile();
|
||||
// new RbacViewMermaidFlowchart(HsOfficeDebitorEntity.rbac()).generateToMarkdownFile();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,71 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
public class StringWriter {
|
||||
|
||||
private final StringBuilder string = new StringBuilder();
|
||||
private int indentLevel = 0;
|
||||
|
||||
void writeLn(final String text) {
|
||||
string.append( indented(text));
|
||||
writeLn();
|
||||
}
|
||||
|
||||
void writeLn() {
|
||||
string.append( "\n");
|
||||
}
|
||||
|
||||
private String indented(final String text) {
|
||||
if ( indentLevel == 0) {
|
||||
return text.trim();
|
||||
}
|
||||
final var indentation = StringUtils.repeat(" ", indentLevel);
|
||||
final var indented = stream(text.split("\n"))
|
||||
.map(line -> line.trim().isBlank() ? "" : indentation + line.trim())
|
||||
.collect(joining("\n"));
|
||||
return indented;
|
||||
}
|
||||
|
||||
void indent() {
|
||||
++indentLevel;
|
||||
}
|
||||
|
||||
void unindent() {
|
||||
--indentLevel;
|
||||
}
|
||||
|
||||
void indented(final Runnable indented) {
|
||||
indent();
|
||||
indented.run();
|
||||
unindent();
|
||||
}
|
||||
|
||||
boolean chopTail(final String tail) {
|
||||
if (string.toString().endsWith(tail)) {
|
||||
string.setLength(string.length() - tail.length());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void chopEmptyLines() {
|
||||
while (string.toString().endsWith("\n\n")) {
|
||||
string.setLength(string.length() - 1);
|
||||
};
|
||||
}
|
||||
|
||||
void emptyLine() {
|
||||
if (!string.toString().endsWith("\n\n")) {
|
||||
writeLn();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return string.toString();
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ class TestCustomerEntityTest {
|
||||
end
|
||||
|
||||
subgraph contact:permissions[ ]
|
||||
style contact:permissions fill: #dd4901
|
||||
style contact:permissions fill: #dd4901
|
||||
|
||||
perm:contact:*{{contact:*}}
|
||||
perm:contact:add-package{{contact:add-package}}
|
||||
|
Loading…
Reference in New Issue
Block a user