From e118cfac731ab3f48402ead0141764ccedcd3af8 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Fri, 22 Mar 2024 13:49:45 +0100 Subject: [PATCH] simplify InsertTriggerGenerator cases --- .../rbac/rbacdef/InsertTriggerGenerator.java | 65 ++----------------- .../rbacdef/RbacRestrictedViewGenerator.java | 4 +- .../hsadminng/rbac/rbacdef/RbacView.java | 2 +- .../db/changelog/113-test-customer-rbac.md | 2 +- .../db/changelog/113-test-customer-rbac.sql | 19 ++++-- .../db/changelog/123-test-package-rbac.md | 2 +- .../db/changelog/123-test-package-rbac.sql | 24 ++----- .../db/changelog/133-test-domain-rbac.md | 2 +- .../db/changelog/133-test-domain-rbac.sql | 24 ++----- 9 files changed, 37 insertions(+), 107 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/InsertTriggerGenerator.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/InsertTriggerGenerator.java index faa3d565..d625c0d7 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/InsertTriggerGenerator.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/InsertTriggerGenerator.java @@ -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(""" /** diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacRestrictedViewGenerator.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacRestrictedViewGenerator.java index a2d53d39..0a6d23ac 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacRestrictedViewGenerator.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacRestrictedViewGenerator.java @@ -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$); --// diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacView.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacView.java index 2ce71379..57499bb2 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacView.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacView.java @@ -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"); } }); } diff --git a/src/main/resources/db/changelog/113-test-customer-rbac.md b/src/main/resources/db/changelog/113-test-customer-rbac.md index 14057c2a..997c5e97 100644 --- a/src/main/resources/db/changelog/113-test-customer-rbac.md +++ b/src/main/resources/db/changelog/113-test-customer-rbac.md @@ -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}}}%% diff --git a/src/main/resources/db/changelog/113-test-customer-rbac.sql b/src/main/resources/db/changelog/113-test-customer-rbac.sql index 2b3fda9f..9472f71e 100644 --- a/src/main/resources/db/changelog/113-test-customer-rbac.sql +++ b/src/main/resources/db/changelog/113-test-customer-rbac.sql @@ -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$); diff --git a/src/main/resources/db/changelog/123-test-package-rbac.md b/src/main/resources/db/changelog/123-test-package-rbac.md index 0ca13fc4..b4281d6d 100644 --- a/src/main/resources/db/changelog/123-test-package-rbac.md +++ b/src/main/resources/db/changelog/123-test-package-rbac.md @@ -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}}}%% diff --git a/src/main/resources/db/changelog/123-test-package-rbac.sql b/src/main/resources/db/changelog/123-test-package-rbac.sql index 1e79ac4b..26a2d1af 100644 --- a/src/main/resources/db/changelog/123-test-package-rbac.sql +++ b/src/main/resources/db/changelog/123-test-package-rbac.sql @@ -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$); diff --git a/src/main/resources/db/changelog/133-test-domain-rbac.md b/src/main/resources/db/changelog/133-test-domain-rbac.md index 71fb6074..f856c2f7 100644 --- a/src/main/resources/db/changelog/133-test-domain-rbac.md +++ b/src/main/resources/db/changelog/133-test-domain-rbac.md @@ -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}}}%% diff --git a/src/main/resources/db/changelog/133-test-domain-rbac.sql b/src/main/resources/db/changelog/133-test-domain-rbac.sql index 8bd6b8df..c98a9bb4 100644 --- a/src/main/resources/db/changelog/133-test-domain-rbac.sql +++ b/src/main/resources/db/changelog/133-test-domain-rbac.sql @@ -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$);