RBAC Diagram+PostgreSQL Generator #21
@ -85,6 +85,8 @@ public class HsOfficeRelationshipEntity implements HasUuid, Stringifyable {
|
||||
|| '-with-' || target.relType || '-'
|
||||
|| (select idName from hs_office_person_iv p where p.uuid = relHolderUuid)
|
||||
"""))
|
||||
.withRestrictedViewOrderedBy(SQL.expression(
|
||||
"(select idName from hs_office_person_iv p where p.uuid = target.relHolderUuid)"))
|
||||
.withUpdatableColumns("contactUuid")
|
||||
.importEntityAlias("anchorPerson", HsOfficePersonEntity.class,
|
||||
dependsOnColumn("relAnchorUuid"),
|
||||
|
@ -0,0 +1,34 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
||||
|
||||
public class RbacIdentityViewGenerator {
|
||||
private final RbacView rbacDef;
|
||||
private final String liquibaseTagPrefix;
|
||||
private final String simpleEntityVarName;
|
||||
private final String rawTableName;
|
||||
|
||||
public RbacIdentityViewGenerator(final RbacView rbacDef, final String liquibaseTagPrefix) {
|
||||
this.rbacDef = rbacDef;
|
||||
this.liquibaseTagPrefix = liquibaseTagPrefix;
|
||||
this.simpleEntityVarName = rbacDef.getRootEntityAlias().simpleName();
|
||||
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
|
||||
}
|
||||
|
||||
void generateTo(final StringWriter plPgSql) {
|
||||
plPgSql.writeLn("""
|
||||
|
||||
-- ============================================================================
|
||||
--changeset ${liquibaseTagPrefix}-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('${rawTableName}', $idName$
|
||||
${identityViewSqlPart}
|
||||
$idName$);
|
||||
--//
|
||||
|
||||
""",
|
||||
with("liquibaseTagPrefix", liquibaseTagPrefix),
|
||||
with("identityViewSqlPart", rbacDef.getIdentityViewSqlQuery().sql), // TODO: other part types
|
||||
with("rawTableName", rawTableName));
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
|
||||
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
||||
|
||||
public class RbacRestrictedViewGenerator {
|
||||
private final RbacView rbacDef;
|
||||
private final String liquibaseTagPrefix;
|
||||
private final String simpleEntityVarName;
|
||||
private final String rawTableName;
|
||||
|
||||
public RbacRestrictedViewGenerator(final RbacView rbacDef, final String liquibaseTagPrefix) {
|
||||
this.rbacDef = rbacDef;
|
||||
this.liquibaseTagPrefix = liquibaseTagPrefix;
|
||||
this.simpleEntityVarName = rbacDef.getRootEntityAlias().simpleName();
|
||||
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
|
||||
}
|
||||
|
||||
void generateTo(final StringWriter plPgSql) {
|
||||
plPgSql.writeLn("""
|
||||
|
||||
-- ============================================================================
|
||||
--changeset ${liquibaseTagPrefix}-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('${rawTableName}',
|
||||
'${orderBy}',
|
||||
$updates$
|
||||
${updates}
|
||||
$updates$);
|
||||
--//
|
||||
|
||||
""",
|
||||
with("liquibaseTagPrefix", liquibaseTagPrefix),
|
||||
with("orderBy", rbacDef.getOrderBySqlExpression().sql),
|
||||
with("updates", rbacDef.getUpdatableColumns().stream()
|
||||
.map(c -> c + " = new." + c)
|
||||
.collect(joining("\n"))),
|
||||
with("rawTableName", rawTableName));
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
||||
|
||||
public class RbacRoleDescriptorsGenerator {
|
||||
|
||||
private final String liquibaseTagPrefix;
|
||||
private final String simpleEntityVarName;
|
||||
private final String rawTableName;
|
||||
|
||||
public RbacRoleDescriptorsGenerator(final RbacView rbacDef, final String liquibaseTagPrefix) {
|
||||
this.liquibaseTagPrefix = liquibaseTagPrefix;
|
||||
this.simpleEntityVarName = rbacDef.getRootEntityAlias().simpleName();
|
||||
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
|
||||
}
|
||||
|
||||
void generateTo(final StringWriter plPgSql) {
|
||||
plPgSql.writeLn("""
|
||||
|
||||
-- ============================================================================
|
||||
--changeset ${liquibaseTagPrefix}-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRoleDescriptors('${simpleEntityVarName}', '${rawTableName}');
|
||||
--//
|
||||
|
||||
""",
|
||||
with("liquibaseTagPrefix", liquibaseTagPrefix),
|
||||
with("simpleEntityVarName", simpleEntityVarName),
|
||||
with("rawTableName", rawTableName));
|
||||
}
|
||||
}
|
@ -27,7 +27,6 @@ public class RbacView {
|
||||
public static final String GLOBAL = "global";
|
||||
public static final String OUTPUT_BASEDIR = "src/main/resources/db/changelog";
|
||||
|
||||
|
||||
private final EntityAlias rootEntityAlias;
|
||||
|
||||
private final Set<RbacUserReference> userDefs = new LinkedHashSet<>();
|
||||
@ -47,6 +46,7 @@ public class RbacView {
|
||||
private final Set<RbacGrantDefinition> grantDefs = new LinkedHashSet<>();
|
||||
|
||||
private SQL identityViewSqlQuery;
|
||||
private SQL orderBySqlExpression;
|
||||
private EntityAlias rootEntityAliasProxy;
|
||||
private RbacRoleDefinition previousRoleDef;
|
||||
|
||||
@ -70,6 +70,11 @@ public class RbacView {
|
||||
return this;
|
||||
}
|
||||
|
||||
public RbacView withRestrictedViewOrderedBy(final SQL orderBySqlExpression) {
|
||||
this.orderBySqlExpression = orderBySqlExpression;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RbacView createRole(final Role role, final Consumer<RbacRoleDefinition> with) {
|
||||
final RbacRoleDefinition newRoleDef = findRbacRole(rootEntityAlias, role).toCreate();
|
||||
with.accept(newRoleDef);
|
||||
@ -619,11 +624,17 @@ public class RbacView {
|
||||
return new SQL(projection, Part.SQL_PROJECTION);
|
||||
}
|
||||
|
||||
public static SQL expression(final String sqlExpression) {
|
||||
// TODO: validate
|
||||
return new SQL(sqlExpression, Part.SQL_EXPRESSION);
|
||||
}
|
||||
|
||||
enum Part {
|
||||
NOOP,
|
||||
SQL_QUERY,
|
||||
AUTO_FETCH,
|
||||
SQL_PROJECTION
|
||||
SQL_PROJECTION,
|
||||
SQL_EXPRESSION
|
||||
}
|
||||
|
||||
final String sql;
|
||||
|
@ -4,7 +4,6 @@ import lombok.SneakyThrows;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ -13,7 +12,6 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
||||
|
||||
public class RbacViewPostgresGenerator {
|
||||
|
||||
|
||||
private final RbacView rbacDef;
|
||||
private final String liqibaseTagPrefix;
|
||||
private final StringWriter plPgSql = new StringWriter();
|
||||
@ -29,7 +27,11 @@ public class RbacViewPostgresGenerator {
|
||||
with("timestamp", LocalDateTime.now().toString()),
|
||||
with("ref", NEW.name()));
|
||||
|
||||
new RbacObjectGenerator(rbacDef, liqibaseTagPrefix).generateTo(plPgSql);
|
||||
new RbacRoleDescriptorsGenerator(rbacDef, liqibaseTagPrefix).generateTo(plPgSql);
|
||||
new RolesGrantsAndPermissionsGenerator(rbacDef, liqibaseTagPrefix).generateTo(plPgSql);
|
||||
new RbacIdentityViewGenerator(rbacDef, liqibaseTagPrefix).generateTo(plPgSql);
|
||||
new RbacRestrictedViewGenerator(rbacDef, liqibaseTagPrefix).generateTo(plPgSql);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -37,17 +39,6 @@ public class RbacViewPostgresGenerator {
|
||||
return plPgSql.toString();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private static void generatePostgres(final RbacView rbac) {
|
||||
final Path outputPath = Paths.get("doc", rbac.getRootEntityAlias().simpleName() + ".sql");
|
||||
Files.writeString(
|
||||
outputPath,
|
||||
new RbacViewPostgresGenerator(rbac).toString(),
|
||||
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||
|
||||
System.out.println(outputPath.toAbsolutePath());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void generateToChangeLog(final Path outputPath) {
|
||||
Files.writeString(
|
||||
|
@ -22,7 +22,6 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
private final RbacView rbacDef;
|
||||
private final Set<RbacView.RbacGrantDefinition> rbacGrants = new HashSet<>();
|
||||
private final String liquibaseTagPrefix;
|
||||
private final Class<?> entityClass;
|
||||
private final String simpleEntityName;
|
||||
private final String simpleEntityVarName;
|
||||
private final String rawTableName;
|
||||
@ -34,7 +33,6 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
.collect(toSet()));
|
||||
this.liquibaseTagPrefix = liquibaseTagPrefix;
|
||||
|
||||
entityClass = rbacDef.getRootEntityAlias().entityClass();
|
||||
simpleEntityVarName = rbacDef.getRootEntityAlias().simpleName();
|
||||
simpleEntityName = capitalize(simpleEntityVarName);
|
||||
rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
|
||||
@ -452,7 +450,6 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
on ${rawTableName}
|
||||
for each row
|
||||
execute procedure updateTriggerFor${simpleEntityName}_tf();
|
||||
--//
|
||||
"""
|
||||
.replace("${simpleEntityName}", simpleEntityName)
|
||||
.replace("${rawTableName}", rawTableName)
|
||||
|
Loading…
Reference in New Issue
Block a user