simplified updateRbacGrants for entities with nullable updatable references

This commit is contained in:
Michael Hoennig 2024-03-20 14:09:18 +01:00
parent d62fcd45cf
commit b97243f28f
2 changed files with 47 additions and 14 deletions

View File

@ -91,6 +91,37 @@ class RolesGrantsAndPermissionsGenerator {
plPgSql.writeLn(); plPgSql.writeLn();
} }
private void generateSimplifiedUpdateTriggerFunction(final StringWriter plPgSql) {
final var updateConditions = updatableEntityAliases()
.map(RbacView.EntityAlias::dependsOnColumName)
.distinct()
.map(columnName -> "NEW." + columnName + " is distinct from OLD." + columnName)
.collect(joining( "\n or "));
plPgSql.writeLn("""
/*
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
*/
create or replace procedure updateRbacRulesFor${simpleEntityName}(
OLD ${rawTableName},
NEW ${rawTableName}
)
language plpgsql as $$
begin
if ${updateConditions} then
delete from rbacgrants g where g.grantedbytriggerof = OLD.uuid;
call buildRbacSystemFor${simpleEntityName}(NEW);
end if;
end; $$;
""",
with("simpleEntityName", simpleEntityName),
with("rawTableName", rawTableName),
with("updateConditions", updateConditions));
}
private void generateUpdateTriggerFunction(final StringWriter plPgSql) { private void generateUpdateTriggerFunction(final StringWriter plPgSql) {
plPgSql.writeLn(""" plPgSql.writeLn("""
/* /*
@ -134,6 +165,12 @@ class RolesGrantsAndPermissionsGenerator {
return updatableEntityAliases().anyMatch(e -> true); return updatableEntityAliases().anyMatch(e -> true);
} }
private boolean hasAnyUpdatableAndNullableEntityAliases() {
return updatableEntityAliases()
.filter(ea -> ea.nullable() == RbacView.Nullable.NULLABLE)
.anyMatch(e -> true);
}
private void generateCreateRolesAndGrantsAfterInsert(final StringWriter plPgSql) { private void generateCreateRolesAndGrantsAfterInsert(final StringWriter plPgSql) {
referencedEntityAliases() referencedEntityAliases()
.forEach((ea) -> { .forEach((ea) -> {
@ -465,7 +502,11 @@ class RolesGrantsAndPermissionsGenerator {
private void generateUpdateTrigger(final StringWriter plPgSql) { private void generateUpdateTrigger(final StringWriter plPgSql) {
generateHeader(plPgSql, "update"); generateHeader(plPgSql, "update");
generateUpdateTriggerFunction(plPgSql); if ( hasAnyUpdatableAndNullableEntityAliases() ) {
generateSimplifiedUpdateTriggerFunction(plPgSql);
} else {
generateUpdateTriggerFunction(plPgSql);
}
plPgSql.writeLn(""" plPgSql.writeLn("""
/* /*

View File

@ -1,5 +1,5 @@
--liquibase formatted sql --liquibase formatted sql
-- This code generated was by RbacViewPostgresGenerator at 2024-03-16T13:52:18.491882945. -- This code generated was by RbacViewPostgresGenerator at 2024-03-20T13:55:16.722860098.
-- ============================================================================ -- ============================================================================
@ -54,7 +54,7 @@ begin
SELECT * SELECT *
FROM hs_office_bankaccount AS b FROM hs_office_bankaccount AS b
WHERE b.uuid = NEW.refundbankaccountuuid WHERE b.uuid = NEW.refundBankAccountUuid
INTO newRefundBankAccount; INTO newRefundBankAccount;
call grantRoleToRole(hsOfficeBankAccountReferrer(newRefundBankAccount), hsOfficeRelationshipAgent(newDebitorRel)); call grantRoleToRole(hsOfficeBankAccountReferrer(newRefundBankAccount), hsOfficeRelationshipAgent(newDebitorRel));
@ -103,18 +103,10 @@ create or replace procedure updateRbacRulesForHsOfficeDebitor(
NEW hs_office_debitor NEW hs_office_debitor
) )
language plpgsql as $$ language plpgsql as $$
declare
oldPartnerRel hs_office_relationship;
newPartnerRel hs_office_relationship;
oldDebitorRel hs_office_relationship;
newDebitorRel hs_office_relationship;
oldRefundBankAccount hs_office_bankaccount;
newRefundBankAccount hs_office_bankaccount;
begin begin
if NEW.refundbankaccountuuid <> OLD.refundbankaccountuuid
or NEW.debitorreluuid <> OLD.debitorreluuid then if NEW.debitorRelUuid is distinct from OLD.debitorRelUuid
or NEW.refundBankAccountUuid is distinct from OLD.refundBankAccountUuid then
delete from rbacgrants g where g.grantedbytriggerof = OLD.uuid; delete from rbacgrants g where g.grantedbytriggerof = OLD.uuid;
call buildRbacSystemForHsOfficeDebitor(NEW); call buildRbacSystemForHsOfficeDebitor(NEW);
end if; end if;