RBAC Diagram+PostgreSQL Generator #21

Merged
hsh-michaelhoennig merged 54 commits from experimental-rbacview-generator into master 2024-03-11 12:30:44 +01:00
4 changed files with 29 additions and 29 deletions
Showing only changes of commit c1c67b3c7b - Show all commits

View File

@ -19,7 +19,7 @@ public class RbacView {
public static final String GLOBAL = "global"; public static final String GLOBAL = "global";
private final EntityAlias entityAlias; private final EntityAlias rootEntityAlias;
private final Set<RbacUserReference> userDefs = new LinkedHashSet<>(); private final Set<RbacUserReference> userDefs = new LinkedHashSet<>();
private final Set<RbacRoleDefinition> roleDefs = new LinkedHashSet<>(); private final Set<RbacRoleDefinition> roleDefs = new LinkedHashSet<>();
@ -38,7 +38,7 @@ public class RbacView {
private final Set<RbacGrantDefinition> grantDefs = new LinkedHashSet<>(); private final Set<RbacGrantDefinition> grantDefs = new LinkedHashSet<>();
private SQL identityViewSqlQuery; private SQL identityViewSqlQuery;
private EntityAlias entityAliasProxy; private EntityAlias rootEntityAliasProxy;
private RbacRoleDefinition previousRoleDef; private RbacRoleDefinition previousRoleDef;
public static <E extends RbacObject> RbacView rbacViewFor(final String alias, final Class<E> entityClass) { public static <E extends RbacObject> RbacView rbacViewFor(final String alias, final Class<E> entityClass) {
@ -46,8 +46,8 @@ public class RbacView {
} }
RbacView(final String alias, final Class<? extends RbacObject> entityClass) { RbacView(final String alias, final Class<? extends RbacObject> entityClass) {
entityAlias = new EntityAlias(alias, entityClass); rootEntityAlias = new EntityAlias(alias, entityClass);
entityAliases.put(alias, entityAlias); entityAliases.put(alias, rootEntityAlias);
new RbacUserReference(CREATOR); new RbacUserReference(CREATOR);
entityAliases.put("global", new EntityAlias("global")); entityAliases.put("global", new EntityAlias("global"));
} }
@ -63,21 +63,21 @@ public class RbacView {
} }
public RbacView createRole(final Role role, final Consumer<RbacRoleDefinition> with) { public RbacView createRole(final Role role, final Consumer<RbacRoleDefinition> with) {
final RbacRoleDefinition newRoleDef = findRbacRole(entityAlias, role).toCreate(); final RbacRoleDefinition newRoleDef = findRbacRole(rootEntityAlias, role).toCreate();
with.accept(newRoleDef); with.accept(newRoleDef);
previousRoleDef = newRoleDef; previousRoleDef = newRoleDef;
return this; return this;
} }
public RbacView createSubRole(final Role role) { public RbacView createSubRole(final Role role) {
final RbacRoleDefinition newRoleDef = findRbacRole(entityAlias, role).toCreate(); final RbacRoleDefinition newRoleDef = findRbacRole(rootEntityAlias, role).toCreate();
findOrCreateGrantDef(newRoleDef, previousRoleDef).toCreate(); findOrCreateGrantDef(newRoleDef, previousRoleDef).toCreate();
previousRoleDef = newRoleDef; previousRoleDef = newRoleDef;
return this; return this;
} }
public RbacView createSubRole(final Role role, final Consumer<RbacRoleDefinition> with) { public RbacView createSubRole(final Role role, final Consumer<RbacRoleDefinition> with) {
final RbacRoleDefinition newRoleDef = findRbacRole(entityAlias, role).toCreate(); final RbacRoleDefinition newRoleDef = findRbacRole(rootEntityAlias, role).toCreate();
findOrCreateGrantDef(newRoleDef, previousRoleDef).toCreate(); findOrCreateGrantDef(newRoleDef, previousRoleDef).toCreate();
with.accept(newRoleDef); with.accept(newRoleDef);
previousRoleDef = newRoleDef; previousRoleDef = newRoleDef;
@ -85,7 +85,7 @@ public class RbacView {
} }
public RbacPermissionDefinition createPermission(final Permission permission) { public RbacPermissionDefinition createPermission(final Permission permission) {
return createPermission(entityAlias, permission); return createPermission(rootEntityAlias, permission);
} }
private RbacPermissionDefinition createPermission(final EntityAlias entityAlias, final Permission permission) { private RbacPermissionDefinition createPermission(final EntityAlias entityAlias, final Permission permission) {
@ -103,10 +103,10 @@ public class RbacView {
public <EC extends RbacObject> RbacView importProxyEntity( public <EC extends RbacObject> RbacView importProxyEntity(
final String aliasName, final Class entityClass, final SQL fetchSql, final Column dependsOnColum) { final String aliasName, final Class entityClass, final SQL fetchSql, final Column dependsOnColum) {
if ( entityAliasProxy != null ) { if ( rootEntityAliasProxy != null ) {
throw new IllegalStateException("there is already an entityAliasProxy: " + entityAliasProxy); throw new IllegalStateException("there is already an entityAliasProxy: " + rootEntityAliasProxy);
} }
entityAliasProxy = importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum); rootEntityAliasProxy = importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum);
return this; return this;
} }
@ -135,7 +135,7 @@ public class RbacView {
private RbacView importAsAlias(final String aliasName, final RbacView importedRbacView) { private RbacView importAsAlias(final String aliasName, final RbacView importedRbacView) {
final var mapper = new AliasNameMapper(importedRbacView, aliasName); final var mapper = new AliasNameMapper(importedRbacView, aliasName);
importedRbacView.getEntityAliases().values().stream() importedRbacView.getEntityAliases().values().stream()
.filter(entityAlias -> !importedRbacView.isMainEntityAlias(entityAlias)) .filter(entityAlias -> !importedRbacView.isRootEntityAlias(entityAlias))
.filter(entityAlias -> !entityAlias.isGlobal()) .filter(entityAlias -> !entityAlias.isGlobal())
.forEach(entityAlias -> { .forEach(entityAlias -> {
final String mappedAliasName = mapper.map(entityAlias.aliasName); final String mappedAliasName = mapper.map(entityAlias.aliasName);
@ -176,12 +176,12 @@ public class RbacView {
return findOrCreateGrantDef(subRoleDefinition, superRoleDefinition).toCreate(); return findOrCreateGrantDef(subRoleDefinition, superRoleDefinition).toCreate();
} }
boolean isMainEntityAlias(final EntityAlias entityAlias) { boolean isRootEntityAlias(final EntityAlias entityAlias) {
return entityAlias == this.entityAlias; return entityAlias == this.rootEntityAlias;
} }
public boolean isEntityAliasProxy(final EntityAlias entityAlias) { public boolean isEntityAliasProxy(final EntityAlias entityAlias) {
return entityAlias == entityAliasProxy; return entityAlias == rootEntityAliasProxy;
} }
public class RbacGrantBuilder { public class RbacGrantBuilder {
@ -545,7 +545,7 @@ public class RbacView {
} }
String map(final String originalAliasName) { String map(final String originalAliasName) {
if (originalAliasName.equals(importedRbacView.entityAlias.aliasName) ) { if (originalAliasName.equals(importedRbacView.rootEntityAlias.aliasName) ) {
return outerAliasName; return outerAliasName;
} }
if (originalAliasName.equals("global") ) { if (originalAliasName.equals("global") ) {

View File

@ -36,7 +36,7 @@ public class RbacViewMermaidFlowchart {
} }
private void renderEntitySubgraph(final RbacView.EntityAlias entity) { private void renderEntitySubgraph(final RbacView.EntityAlias entity) {
final var color = rbacDef.isMainEntityAlias(entity) ? HOSTSHARING_ORANGE : HOSTSHARING_LIGHTBLUE; final var color = rbacDef.isRootEntityAlias(entity) ? HOSTSHARING_ORANGE : HOSTSHARING_LIGHTBLUE;
flowchart.writeLn(""" flowchart.writeLn("""
subgraph %{aliasName}["`**%{aliasName}**`"] subgraph %{aliasName}["`**%{aliasName}**`"]
@ -63,8 +63,8 @@ public class RbacViewMermaidFlowchart {
.map(p -> " " + permDef(p) ) .map(p -> " " + permDef(p) )
.collect(joining("\n"))); .collect(joining("\n")));
if (rbacDef.isMainEntityAlias(entity) && rbacDef.getEntityAliasProxy() != null ) { if (rbacDef.isRootEntityAlias(entity) && rbacDef.getRootEntityAliasProxy() != null ) {
renderEntitySubgraph(rbacDef.getEntityAliasProxy()); renderEntitySubgraph(rbacDef.getRootEntityAliasProxy());
} }
}); });
@ -133,7 +133,7 @@ public class RbacViewMermaidFlowchart {
} }
void generateToMarkdownFile() throws IOException { void generateToMarkdownFile() throws IOException {
final Path path = Paths.get("doc", rbacDef.getEntityAlias().simpleName() + ".md"); final Path path = Paths.get("doc", rbacDef.getRootEntityAlias().simpleName() + ".md");
Files.writeString( Files.writeString(
path, path,
""" """
@ -143,7 +143,7 @@ public class RbacViewMermaidFlowchart {
%{flowchart} %{flowchart}
``` ```
""" """
.replace("%{entityAlias}", rbacDef.getEntityAlias().aliasName()) .replace("%{entityAlias}", rbacDef.getRootEntityAlias().aliasName())
.replace("%{timestamp}", LocalDateTime.now().toString()) .replace("%{timestamp}", LocalDateTime.now().toString())
.replace("%{flowchart}", flowchart.toString()), .replace("%{flowchart}", flowchart.toString()),
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);

View File

@ -18,7 +18,7 @@ public class RbacViewPostgresGenerator {
public RbacViewPostgresGenerator(final RbacView forRbacDef) { public RbacViewPostgresGenerator(final RbacView forRbacDef) {
rbacDef = forRbacDef; rbacDef = forRbacDef;
liqibaseTagPrefix = rbacDef.getEntityAlias().entityClass().getSimpleName(); liqibaseTagPrefix = rbacDef.getRootEntityAlias().entityClass().getSimpleName();
plPgSql.append(""" plPgSql.append("""
--liquibase formatted sql --liquibase formatted sql
-- generated at: %{timestamp} -- generated at: %{timestamp}

View File

@ -29,7 +29,7 @@ class RolesGrantsAndPermissionsGenerator {
this.rbacGrants.addAll(rbacGrants); this.rbacGrants.addAll(rbacGrants);
this.liquibaseTagPrefix = liquibaseTagPrefix; this.liquibaseTagPrefix = liquibaseTagPrefix;
entityClass = rbacDef.getEntityAlias().entityClass(); entityClass = rbacDef.getRootEntityAlias().entityClass();
simpleEntityName = entityClass.getSimpleName(); simpleEntityName = entityClass.getSimpleName();
simpleEntityVarName = uncapitalize(simpleEntityName); simpleEntityVarName = uncapitalize(simpleEntityName);
rawTableName = withoutRvSuffix(entityClass.getAnnotation(Table.class).name()); rawTableName = withoutRvSuffix(entityClass.getAnnotation(Table.class).name());
@ -89,7 +89,7 @@ class RolesGrantsAndPermissionsGenerator {
private void createRolesWithGrantsSql(final StringBuilder plPgSql, final RbacView.Role role) { private void createRolesWithGrantsSql(final StringBuilder plPgSql, final RbacView.Role role) {
final var isToCreate = rbacDef.getRoleDefs().stream() final var isToCreate = rbacDef.getRoleDefs().stream()
.filter(roleDef -> rbacDef.isMainEntityAlias(roleDef.getEntityAlias()) && roleDef.getRole() == role ) .filter(roleDef -> rbacDef.isRootEntityAlias(roleDef.getEntityAlias()) && roleDef.getRole() == role )
.findFirst().map(RbacView.RbacRoleDefinition::isToCreate).orElse(false); .findFirst().map(RbacView.RbacRoleDefinition::isToCreate).orElse(false);
if (!isToCreate) { if (!isToCreate) {
return; return;
@ -103,7 +103,7 @@ class RolesGrantsAndPermissionsGenerator {
.replace("%{simpleEntityVarName)", simpleEntityVarName) .replace("%{simpleEntityVarName)", simpleEntityVarName)
.replace("%{roleSuffix}", capitalize(role.roleName()))); .replace("%{roleSuffix}", capitalize(role.roleName())));
final var permissionGrantsForRole = findPermissionsGrantsForRole(rbacDef.getEntityAlias(), role); final var permissionGrantsForRole = findPermissionsGrantsForRole(rbacDef.getRootEntityAlias(), role);
if (!permissionGrantsForRole.isEmpty()) { if (!permissionGrantsForRole.isEmpty()) {
final var permissionsForRoleInPlPgSql = permissionGrantsForRole.stream() final var permissionsForRoleInPlPgSql = permissionGrantsForRole.stream()
.map(RbacView.RbacGrantDefinition::getPermDef) .map(RbacView.RbacGrantDefinition::getPermDef)
@ -115,7 +115,7 @@ class RolesGrantsAndPermissionsGenerator {
rbacGrants.removeAll(permissionGrantsForRole); rbacGrants.removeAll(permissionGrantsForRole);
} }
final var grantsToUsers = findGrantsToUserForRole(rbacDef.getEntityAlias(), role); final var grantsToUsers = findGrantsToUserForRole(rbacDef.getRootEntityAlias(), role);
if (!grantsToUsers.isEmpty()) { if (!grantsToUsers.isEmpty()) {
final var grantsToUsersPlPgSql = grantsToUsers.stream() final var grantsToUsersPlPgSql = grantsToUsers.stream()
.map(RbacView.RbacGrantDefinition::getUserDef) .map(RbacView.RbacGrantDefinition::getUserDef)
@ -125,7 +125,7 @@ class RolesGrantsAndPermissionsGenerator {
rbacGrants.removeAll(grantsToUsers); rbacGrants.removeAll(grantsToUsers);
} }
final var incomingGrants = findIncomingSuperRolesForRole(rbacDef.getEntityAlias(), role); final var incomingGrants = findIncomingSuperRolesForRole(rbacDef.getRootEntityAlias(), role);
if (!incomingGrants.isEmpty()) { if (!incomingGrants.isEmpty()) {
final var incomingGrantsInPlPgSql = incomingGrants.stream() final var incomingGrantsInPlPgSql = incomingGrants.stream()
.map(RbacView.RbacGrantDefinition::getSuperRoleDef) .map(RbacView.RbacGrantDefinition::getSuperRoleDef)
@ -135,7 +135,7 @@ class RolesGrantsAndPermissionsGenerator {
rbacGrants.removeAll(incomingGrants); rbacGrants.removeAll(incomingGrants);
} }
final var outgoingGrants = findOutgoingSuperRolesForRole(rbacDef.getEntityAlias(), role); final var outgoingGrants = findOutgoingSuperRolesForRole(rbacDef.getRootEntityAlias(), role);
if (!outgoingGrants.isEmpty()) { if (!outgoingGrants.isEmpty()) {
final var outgoingGrantsInPlPgSql = outgoingGrants.stream() final var outgoingGrantsInPlPgSql = outgoingGrants.stream()
.map(RbacView.RbacGrantDefinition::getSuperRoleDef) .map(RbacView.RbacGrantDefinition::getSuperRoleDef)
@ -218,7 +218,7 @@ class RolesGrantsAndPermissionsGenerator {
private String toPlPgSqlReference(final PostgresTriggerReference triggerRef, final RbacView.RbacRoleDefinition roleDef) { private String toPlPgSqlReference(final PostgresTriggerReference triggerRef, final RbacView.RbacRoleDefinition roleDef) {
return toVar(roleDef) + return toVar(roleDef) +
(roleDef.getEntityAlias().isGlobal() ? "()" (roleDef.getEntityAlias().isGlobal() ? "()"
: rbacDef.isMainEntityAlias(roleDef.getEntityAlias()) ? ("(" + triggerRef.name() + ")") : rbacDef.isRootEntityAlias(roleDef.getEntityAlias()) ? ("(" + triggerRef.name() + ")")
: "(" + toTriggerReference(triggerRef, roleDef.getEntityAlias()) + ")"); : "(" + toTriggerReference(triggerRef, roleDef.getEntityAlias()) + ")");
} }