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 478c10db..b3c37bad 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/InsertTriggerGenerator.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/InsertTriggerGenerator.java @@ -164,6 +164,19 @@ public class InsertTriggerGenerator { } private void generateInsertPermissionChecks(final StringWriter plPgSql) { + generateInsertPermissionsCheckHeader(plPgSql); + + plPgSql.indented(1, () -> { + getInsertGrants().forEach(g -> { + generateInsertPermissionChecksForSingleGrant(plPgSql, g); + }); + plPgSql.chopTail(" or\n"); + }); + + generateInsertPermissionsChecksFooter(plPgSql); + } + + private void generateInsertPermissionsCheckHeader(final StringWriter plPgSql) { plPgSql.writeLn(""" -- ============================================================================ --changeset ${rawSubTable}-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--// @@ -179,68 +192,67 @@ public class InsertTriggerGenerator { superObjectUuid uuid; begin """, - with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName())); + with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName())); plPgSql.chopEmptyLines(); + } - plPgSql.indented(1, () -> { - getInsertGrants().forEach(g -> { - final RbacView.EntityAlias superRoleEntityAlias = g.getSuperRoleDef().getEntityAlias(); + private void generateInsertPermissionChecksForSingleGrant(final StringWriter plPgSql, final RbacView.RbacGrantDefinition g) { + final RbacView.EntityAlias superRoleEntityAlias = g.getSuperRoleDef().getEntityAlias(); - final var caseCondition = g.isConditional() - ? ("NEW.type in (" + toStringList(g.getForCases()) + ") and ") - : ""; + final var caseCondition = g.isConditional() + ? ("NEW.type in (" + toStringList(g.getForCases()) + ") and ") + : ""; - if (g.getSuperRoleDef().isGlobal(GUEST)) { - plPgSql.writeLn( - """ - -- check INSERT INSERT permission for global anyone - if ${caseCondition}true then - return NEW; - end if; - """, - with("caseCondition", caseCondition)); - } else if (g.getSuperRoleDef().isGlobal(ADMIN)) { - plPgSql.writeLn( - """ - -- check INSERT INSERT if global ADMIN - if ${caseCondition}isGlobalAdmin() then - return NEW; - end if; - """, - with("caseCondition", caseCondition)); - } else if (g.getSuperRoleDef().getEntityAlias().isFetchedByDirectForeignKey()) { - plPgSql.writeLn( - """ - -- check INSERT permission via direct foreign key: NEW.${refColumn} - if ${caseCondition}hasInsertPermission(NEW.${refColumn}, '${rawSubTable}') then - return NEW; - end if; - """, - with("caseCondition", caseCondition), - with("refColumn", superRoleEntityAlias.dependsOnColumName()), - with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName())); - } else { - plPgSql.writeLn( - """ - -- check INSERT permission via indirect foreign key: NEW.${refColumn} - superObjectUuid := (${fetchSql}); - assert superObjectUuid is not null, 'object uuid fetched depending on ${rawSubTable}.${refColumn} must not be null, also check fetchSql in RBAC DSL'; - if ${caseCondition}hasInsertPermission(superObjectUuid, '${rawSubTable}') then - return NEW; - end if; - """, - with("caseCondition", caseCondition), - with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()), - with("refColumn", superRoleEntityAlias.dependsOnColumName()), - with("fetchSql", g.getSuperRoleDef().getEntityAlias().fetchSql().sql), - with("columns", g.getSuperRoleDef().getEntityAlias().aliasName() + ".uuid"), - with("ref", NEW.name())); - } - }); - plPgSql.chopTail(" or\n"); - }); + if (g.getSuperRoleDef().isGlobal(GUEST)) { + plPgSql.writeLn( + """ + -- check INSERT INSERT permission for global anyone + if ${caseCondition}true then + return NEW; + end if; + """, + with("caseCondition", caseCondition)); + } else if (g.getSuperRoleDef().isGlobal(ADMIN)) { + plPgSql.writeLn( + """ + -- check INSERT INSERT if global ADMIN + if ${caseCondition}isGlobalAdmin() then + return NEW; + end if; + """, + with("caseCondition", caseCondition)); + } else if (g.getSuperRoleDef().getEntityAlias().isFetchedByDirectForeignKey()) { + plPgSql.writeLn( + """ + -- check INSERT permission via direct foreign key: NEW.${refColumn} + if ${caseCondition}hasInsertPermission(NEW.${refColumn}, '${rawSubTable}') then + return NEW; + end if; + """, + with("caseCondition", caseCondition), + with("refColumn", superRoleEntityAlias.dependsOnColumName()), + with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName())); + } else { + plPgSql.writeLn( + """ + -- check INSERT permission via indirect foreign key: NEW.${refColumn} + superObjectUuid := (${fetchSql}); + assert superObjectUuid is not null, 'object uuid fetched depending on ${rawSubTable}.${refColumn} must not be null, also check fetchSql in RBAC DSL'; + if ${caseCondition}hasInsertPermission(superObjectUuid, '${rawSubTable}') then + return NEW; + end if; + """, + with("caseCondition", caseCondition), + with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()), + with("refColumn", superRoleEntityAlias.dependsOnColumName()), + with("fetchSql", g.getSuperRoleDef().getEntityAlias().fetchSql().sql), + with("columns", g.getSuperRoleDef().getEntityAlias().aliasName() + ".uuid"), + with("ref", NEW.name())); + } + } + + private void generateInsertPermissionsChecksFooter(final StringWriter plPgSql) { plPgSql.writeLn(); - plPgSql.writeLn(""" raise exception '[403] insert into ${rawSubTable} not allowed for current subjects % (%)', currentSubjects(), currentSubjectsUuids();