improved RBAC generators #26

Merged
hsh-michaelhoennig merged 17 commits from improved-rbac-generator into master 2024-03-26 11:25:18 +01:00
9 changed files with 37 additions and 107 deletions
Showing only changes of commit e118cfac73 - Show all commits

View File

@ -114,29 +114,16 @@ public class InsertTriggerGenerator {
}
}
} else {
if (rbacDef.isRootEntityAlias(g.getSuperRoleDef().getEntityAlias())) {
generateInsertPermissionTriggerAllowByDirectRole(plPgSql, g);
} else {
generateInsertPermissionTriggerAllowByIndirectRole(plPgSql, g);
}
generateInsertPermissionTriggerAllowByRoleOfDirectForeignKey(plPgSql, g);
}
},
() -> {
plPgSql.writeLn("""
-- FIXME: Where is this case necessary?
create trigger ${rawSubTable}_insert_permission_check_tg
before insert on ${rawSubTable}
for each row
-- As there is no explicit INSERT grant specified for this table,
-- only global admins are allowed to insert any rows.
when ( not isGlobalAdmin() )
execute procedure ${rawSubTable}_insert_permission_missing_tf();
""",
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
System.err.println("WARNING: no explicit INSERT grant for " + rbacDef.getRootEntityAlias().simpleName() + " => implicitly grant INSERT to global.admin");
generateInsertPermissionTriggerAllowOnlyGlobalAdmin(plPgSql);
});
}
private void generateInsertPermissionTriggerAllowByDirectRole(final StringWriter plPgSql, final RbacView.RbacGrantDefinition g) {
private void generateInsertPermissionTriggerAllowByRoleOfDirectForeignKey(final StringWriter plPgSql, final RbacView.RbacGrantDefinition g) {
plPgSql.writeLn("""
/**
Checks if the user or assumed roles are allowed to insert a row to ${rawSubTable},
@ -162,50 +149,6 @@ public class InsertTriggerGenerator {
with("referenceColumn", g.getSuperRoleDef().getEntityAlias().dependsOnColumName()));
}
private void generateInsertPermissionTriggerAllowByIndirectRole(
final StringWriter plPgSql,
final RbacView.RbacGrantDefinition g) {
plPgSql.writeLn("""
/**
Checks if the user or assumed roles are allowed to insert a row to ${rawSubTable},
where the check is performed by an indirect role.
An indirect role is a role FIXME.
*/
create or replace function ${rawSubTable}_insert_permission_missing_tf()
returns trigger
language plpgsql as $$
begin
if ( not hasInsertPermission(
( SELECT ${varName}.uuid FROM
""",
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()),
with("varName", g.getSuperRoleDef().getEntityAlias().aliasName()));
plPgSql.indented(3, () -> {
plPgSql.writeLn(
"(" + g.getSuperRoleDef().getEntityAlias().fetchSql().sql + ") AS ${varName}",
with("varName", g.getSuperRoleDef().getEntityAlias().aliasName()),
with("ref", NEW.name()));
});
plPgSql.writeLn("""
), 'INSERT', '${rawSubTable}') ) then
raise exception
'[403] insert into ${rawSubTable} not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids();
end if;
return NEW;
end; $$;
create trigger ${rawSubTable}_insert_permission_check_tg
before insert on ${rawSubTable}
for each row
execute procedure ${rawSubTable}_insert_permission_missing_tf();
""",
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
}
private void generateInsertPermissionTriggerAllowOnlyGlobalAdmin(final StringWriter plPgSql) {
plPgSql.writeLn("""
/**

View File

@ -8,13 +8,11 @@ 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();
}
@ -28,7 +26,7 @@ public class RbacRestrictedViewGenerator {
${orderBy}
$orderBy$,
$updates$
${updates}
${updates}
$updates$);
--//

View File

@ -831,7 +831,7 @@ public class RbacView {
throw new RuntimeException(e);
}
} else {
System.err.println("no main method in: " + c.getName());
System.err.println("WARNING: no main method in: " + c.getName() + " => no RBAC rules generated");
}
});
}

View File

@ -1,6 +1,6 @@
### rbac customer
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-22T11:19:38.310302721.
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-22T14:02:48.041634681.
```mermaid
%%{init:{'flowchart':{'htmlLabels':false}}}%%

View File

@ -1,5 +1,5 @@
--liquibase formatted sql
-- This code generated was by RbacViewPostgresGenerator at 2024-03-22T11:19:38.329089492.
-- This code generated was by RbacViewPostgresGenerator at 2024-03-22T14:02:48.059763974.
-- ============================================================================
@ -80,12 +80,21 @@ execute procedure insertTriggerForTestCustomer_tf();
--changeset test-customer-rbac-INSERT:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
-- FIXME: Where is this case necessary?
/**
Checks if the user or assumed roles are allowed to insert a row to test_customer,
where only global-admin has that permission.
*/
create or replace function test_customer_insert_permission_missing_tf()
returns trigger
language plpgsql as $$
begin
raise exception '[403] insert into test_customer not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids();
end; $$;
create trigger test_customer_insert_permission_check_tg
before insert on test_customer
for each row
-- As there is no explicit INSERT grant specified for this table,
-- only global admins are allowed to insert any rows.
when ( not isGlobalAdmin() )
execute procedure test_customer_insert_permission_missing_tf();
--//
@ -107,7 +116,7 @@ call generateRbacRestrictedView('test_customer',
reference
$orderBy$,
$updates$
reference = new.reference,
reference = new.reference,
prefix = new.prefix,
adminUserName = new.adminUserName
$updates$);

View File

@ -1,6 +1,6 @@
### rbac package
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-22T11:19:38.365161640.
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-22T14:02:48.107522933.
```mermaid
%%{init:{'flowchart':{'htmlLabels':false}}}%%

View File

@ -1,5 +1,5 @@
--liquibase formatted sql
-- This code generated was by RbacViewPostgresGenerator at 2024-03-22T11:19:38.365610181.
-- This code generated was by RbacViewPostgresGenerator at 2024-03-22T14:02:48.108087056.
-- ============================================================================
@ -195,32 +195,22 @@ execute procedure test_package_test_customer_insert_tf();
/**
Checks if the user or assumed roles are allowed to insert a row to test_package,
where the check is performed by an indirect role.
where the check is performed by a direct role.
An indirect role is a role FIXME.
A direct role is a role depending on a foreign key directly available in the NEW row.
*/
create or replace function test_package_insert_permission_missing_tf()
returns trigger
language plpgsql as $$
begin
if ( not hasInsertPermission(
( SELECT customer.uuid FROM
(SELECT * FROM test_customer c
WHERE c.uuid= NEW.customerUuid
) AS customer
), 'INSERT', 'test_package') ) then
raise exception
'[403] insert into test_package not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids();
end if;
return NEW;
raise exception '[403] insert into test_package not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids();
end; $$;
create trigger test_package_insert_permission_check_tg
before insert on test_package
for each row
when ( not hasInsertPermission(NEW.customerUuid, 'INSERT', 'test_package') )
execute procedure test_package_insert_permission_missing_tf();
--//
@ -241,7 +231,7 @@ call generateRbacRestrictedView('test_package',
name
$orderBy$,
$updates$
version = new.version,
version = new.version,
customerUuid = new.customerUuid,
description = new.description
$updates$);

View File

@ -1,6 +1,6 @@
### rbac domain
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-22T11:19:38.391784384.
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-22T14:02:48.134524089.
```mermaid
%%{init:{'flowchart':{'htmlLabels':false}}}%%

View File

@ -1,5 +1,5 @@
--liquibase formatted sql
-- This code generated was by RbacViewPostgresGenerator at 2024-03-22T11:19:38.392306652.
-- This code generated was by RbacViewPostgresGenerator at 2024-03-22T14:02:48.134964758.
-- ============================================================================
@ -194,32 +194,22 @@ execute procedure test_domain_test_package_insert_tf();
/**
Checks if the user or assumed roles are allowed to insert a row to test_domain,
where the check is performed by an indirect role.
where the check is performed by a direct role.
An indirect role is a role FIXME.
A direct role is a role depending on a foreign key directly available in the NEW row.
*/
create or replace function test_domain_insert_permission_missing_tf()
returns trigger
language plpgsql as $$
begin
if ( not hasInsertPermission(
( SELECT package.uuid FROM
(SELECT * FROM test_package p
WHERE p.uuid= NEW.packageUuid
) AS package
), 'INSERT', 'test_domain') ) then
raise exception
'[403] insert into test_domain not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids();
end if;
return NEW;
raise exception '[403] insert into test_domain not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids();
end; $$;
create trigger test_domain_insert_permission_check_tg
before insert on test_domain
for each row
when ( not hasInsertPermission(NEW.packageUuid, 'INSERT', 'test_domain') )
execute procedure test_domain_insert_permission_missing_tf();
--//
@ -240,7 +230,7 @@ call generateRbacRestrictedView('test_domain',
name
$orderBy$,
$updates$
version = new.version,
version = new.version,
packageUuid = new.packageUuid,
description = new.description
$updates$);