RBAC Diagram+PostgreSQL Generator #21
@ -1,6 +1,7 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
|
||||
@ -95,10 +96,6 @@ public class InsertTriggerGenerator {
|
||||
}
|
||||
|
||||
private void generateInsertCheckTrigger(final StringWriter plPgSql) {
|
||||
rbacDef.getGrantDefs().stream()
|
||||
.filter(g -> g.isToCreate() && g.grantType() == PERM_TO_ROLE &&
|
||||
g.getPermDef().getPermission() == INSERT )
|
||||
.forEach(g -> {
|
||||
plPgSql.writeLn("""
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to ${rawSubTable}.
|
||||
@ -107,24 +104,51 @@ public class InsertTriggerGenerator {
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception 'insert into ${rawSubTable} not allowed for current subjects %', currentSubjectsUuids();
|
||||
raise exception 'insert into ${rawSubTable} not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
""",
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||
getOptionalInsertGrant().ifPresentOrElse(g -> {
|
||||
plPgSql.writeLn("""
|
||||
create trigger ${rawSubTable}_insert_permission_check_tg
|
||||
before insert on ${rawSubTable}
|
||||
for each row
|
||||
when ( not hasInsertPermission(NEW.${referenceColumn}, 'INSERT', '${rawSubTable}') )
|
||||
execute procedure ${rawSubTable}_insert_permission_missing_tf();
|
||||
""",
|
||||
with("rawSubTable", g.getPermDef().entityAlias.getRawTableName()),
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()),
|
||||
with("referenceColumn", g.getSuperRoleDef().getEntityAlias().dependsOnColumName() ));
|
||||
},
|
||||
() -> {
|
||||
plPgSql.writeLn("""
|
||||
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()));
|
||||
});
|
||||
}
|
||||
|
||||
private Stream<RbacView.RbacGrantDefinition> getInsertGrants() {
|
||||
return rbacDef.getGrantDefs().stream()
|
||||
.filter(g -> g.grantType() == PERM_TO_ROLE)
|
||||
.filter(g -> g.getPermDef().toCreate && g.getPermDef().getPermission() == INSERT);
|
||||
}
|
||||
|
||||
private Optional<RbacView.RbacGrantDefinition> getOptionalInsertGrant() {
|
||||
return getInsertGrants()
|
||||
.reduce((x, y) -> {
|
||||
throw new IllegalStateException("only a single INSERT permission grant allowed");
|
||||
});
|
||||
}
|
||||
|
||||
private Optional<RbacView.RbacRoleDefinition> getOptionalInsertSuperRole() {
|
||||
return rbacDef.getGrantDefs().stream()
|
||||
.filter(g -> g.grantType() == PERM_TO_ROLE)
|
||||
.filter(g -> g.getPermDef().toCreate && g.getPermDef().getPermission() == INSERT)
|
||||
return getInsertGrants()
|
||||
.map(RbacView.RbacGrantDefinition::getSuperRoleDef)
|
||||
.reduce((x, y) -> {
|
||||
throw new IllegalStateException("only a single INSERT permission grant allowed");
|
||||
|
@ -334,6 +334,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
.map(RbacPermissionDefinition::getPermission)
|
||||
.map(RbacView.Permission::permission)
|
||||
.map(p -> "'" + p + "'")
|
||||
.sorted()
|
||||
.toList();
|
||||
plPgSql.indented(() ->
|
||||
plPgSql.writeLn("permissions => array[" + joinArrayElements(arrayElements, 3) + "],\n"));
|
||||
|
@ -22,6 +22,19 @@ grant select on global to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset rbac-global-IS-GLOBAL-ADMIN:1 endDelimiter:--//
|
||||
-- ------------------------------------------------------------------
|
||||
|
||||
create or replace function isGlobalAdmin()
|
||||
returns boolean
|
||||
language plpgsql as $$
|
||||
begin
|
||||
return isGranted(currentSubjectsUuids(), findRoleId(globalAdmin()));
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset rbac-global-HAS-GLOBAL-PERMISSION:1 endDelimiter:--//
|
||||
-- ------------------------------------------------------------------
|
||||
|
@ -1,5 +1,5 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator at 2024-03-06T15:40:13.239729250.
|
||||
-- This code generated was by RbacViewPostgresGenerator at 2024-03-07T12:25:36.376742633.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
@ -80,6 +80,25 @@ execute procedure insertTriggerForTestCustomer_tf();
|
||||
--changeset test-customer-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to test_customer.
|
||||
*/
|
||||
create or replace function test_customer_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '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();
|
||||
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
|
@ -1,5 +1,5 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator at 2024-03-06T15:40:13.277446553.
|
||||
-- This code generated was by RbacViewPostgresGenerator at 2024-03-07T12:25:36.422351715.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
@ -194,7 +194,8 @@ create or replace function test_package_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception 'insert into test_package not allowed for current subjects %', currentSubjectsUuids();
|
||||
raise exception 'insert into test_package not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger test_package_insert_permission_check_tg
|
||||
|
@ -74,7 +74,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
|
||||
// then
|
||||
result.assertExceptionWithRootCauseMessage(
|
||||
PersistenceException.class,
|
||||
"add-customer not permitted for test_customer#xxx.admin");
|
||||
"ERROR: insert into test_customer not allowed for current subjects {test_customer#xxx.admin}");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -92,7 +92,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
|
||||
// then
|
||||
result.assertExceptionWithRootCauseMessage(
|
||||
PersistenceException.class,
|
||||
"add-customer not permitted for customer-admin@xxx.example.com");
|
||||
"ERROR: insert into test_customer not allowed for current subjects {customer-admin@xxx.example.com}");
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user