new case for insert permission trigger generator: indirect role check (via relation)
This commit is contained in:
parent
386bea0e51
commit
266cd16b52
@ -103,8 +103,19 @@ public class HsOfficeSepaMandateEntity implements Stringifyable, HasUuid {
|
|||||||
.withRestrictedViewOrderBy(expression("validity"))
|
.withRestrictedViewOrderBy(expression("validity"))
|
||||||
.withUpdatableColumns("reference", "agreement", "validity")
|
.withUpdatableColumns("reference", "agreement", "validity")
|
||||||
|
|
||||||
.importEntityAlias("debitorRel", HsOfficeRelationshipEntity.class, dependsOnColumn("debitorRelUuid"))
|
.importEntityAlias("debitorRel", HsOfficeRelationshipEntity.class,
|
||||||
.importEntityAlias("bankAccount", HsOfficeBankAccountEntity.class, dependsOnColumn("bankAccountUuid"))
|
dependsOnColumn("debitorUuid"),
|
||||||
|
fetchedBySql("""
|
||||||
|
SELECT debitorRel.*
|
||||||
|
FROM hs_office_relationship debitorRel
|
||||||
|
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||||
|
WHERE debitor.uuid = ${REF}.debitorUuid
|
||||||
|
""")
|
||||||
|
)
|
||||||
|
.importEntityAlias("bankAccount", HsOfficeBankAccountEntity.class,
|
||||||
|
dependsOnColumn("bankAccountUuid"),
|
||||||
|
autoFetched()
|
||||||
|
)
|
||||||
|
|
||||||
.createRole(OWNER, (with) -> {
|
.createRole(OWNER, (with) -> {
|
||||||
with.owningUser(CREATOR);
|
with.owningUser(CREATOR);
|
||||||
@ -116,14 +127,16 @@ public class HsOfficeSepaMandateEntity implements Stringifyable, HasUuid {
|
|||||||
})
|
})
|
||||||
.createSubRole(AGENT, (with) -> {
|
.createSubRole(AGENT, (with) -> {
|
||||||
with.outgoingSubRole("bankAccount", REFERRER);
|
with.outgoingSubRole("bankAccount", REFERRER);
|
||||||
with.outgoingSubRole("debitor", AGENT);
|
with.outgoingSubRole("debitorRel", AGENT);
|
||||||
})
|
})
|
||||||
.createSubRole(REFERRER, (with) -> {
|
.createSubRole(REFERRER, (with) -> {
|
||||||
with.incomingSuperRole("bankAccount", ADMIN);
|
with.incomingSuperRole("bankAccount", ADMIN);
|
||||||
with.incomingSuperRole("debitor", AGENT);
|
with.incomingSuperRole("debitorRel", AGENT);
|
||||||
with.outgoingSubRole("debitorRel", TENANT);
|
with.outgoingSubRole("debitorRel", TENANT);
|
||||||
with.permission(SELECT);
|
with.permission(SELECT);
|
||||||
});
|
})
|
||||||
|
|
||||||
|
.toRole("debitorRel", ADMIN).grantPermission("sepaMandate", INSERT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
|
@ -4,6 +4,7 @@ import java.util.Optional;
|
|||||||
import java.util.function.BinaryOperator;
|
import java.util.function.BinaryOperator;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.PostgresTriggerReference.NEW;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
||||||
@ -91,49 +92,23 @@ public class InsertTriggerGenerator {
|
|||||||
""",
|
""",
|
||||||
with("rawSubTableName", rbacDef.getRootEntityAlias().getRawTableName()),
|
with("rawSubTableName", rbacDef.getRootEntityAlias().getRawTableName()),
|
||||||
with("rawSuperTableName", superRoleDef.getEntityAlias().getRawTableName()),
|
with("rawSuperTableName", superRoleDef.getEntityAlias().getRawTableName()),
|
||||||
with("rawSuperRoleDescriptor", toRoleDescriptor(superRoleDef, PostgresTriggerReference.NEW.name()))
|
with("rawSuperRoleDescriptor", toRoleDescriptor(superRoleDef, NEW.name()))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateInsertCheckTrigger(final StringWriter plPgSql) {
|
private void generateInsertCheckTrigger(final StringWriter plPgSql) {
|
||||||
plPgSql.writeLn("""
|
|
||||||
/**
|
|
||||||
Checks if the user or assumed roles are allowed to insert a row to ${rawSubTable}.
|
|
||||||
*/
|
|
||||||
create or replace function ${rawSubTable}_insert_permission_missing_tf()
|
|
||||||
returns trigger
|
|
||||||
language plpgsql as $$
|
|
||||||
begin
|
|
||||||
raise exception '[403] insert into ${rawSubTable} not allowed for current subjects % (%)',
|
|
||||||
currentSubjects(), currentSubjectsUuids();
|
|
||||||
end; $$;
|
|
||||||
""",
|
|
||||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
|
||||||
getOptionalInsertGrant().ifPresentOrElse(g -> {
|
getOptionalInsertGrant().ifPresentOrElse(g -> {
|
||||||
if (!g.getSuperRoleDef().getEntityAlias().isGlobal()) {
|
if (!g.getSuperRoleDef().getEntityAlias().isGlobal()) {
|
||||||
plPgSql.writeLn(
|
if (rbacDef.isRootEntityAlias(g.getSuperRoleDef().getEntityAlias())) {
|
||||||
"""
|
generateInsertPermissionTriggerAllowByDirectRole(plPgSql, g);
|
||||||
create trigger ${rawSubTable}_insert_permission_check_tg
|
} else {
|
||||||
before insert on ${rawSubTable}
|
generateInsertPermissionTriggerAllowByIndirectRole(plPgSql, g);
|
||||||
for each row
|
}
|
||||||
when ( not hasInsertPermission(NEW.${referenceColumn}, 'INSERT', '${rawSubTable}') )
|
|
||||||
execute procedure ${rawSubTable}_insert_permission_missing_tf();
|
|
||||||
""",
|
|
||||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()),
|
|
||||||
with("referenceColumn", g.getSuperRoleDef().getEntityAlias().dependsOnColumName()));
|
|
||||||
} else {
|
} else {
|
||||||
switch (g.getSuperRoleDef().getRole()) {
|
switch (g.getSuperRoleDef().getRole()) {
|
||||||
case ADMIN -> {
|
case ADMIN -> {
|
||||||
plPgSql.writeLn(
|
generateInsertPermissionTriggerAllowOnlyGlobalAdmin(plPgSql);
|
||||||
"""
|
|
||||||
create trigger ${rawSubTable}_insert_permission_check_tg
|
|
||||||
before insert on ${rawSubTable}
|
|
||||||
for each row
|
|
||||||
when ( not isGlobalAdmin() )
|
|
||||||
execute procedure ${rawSubTable}_insert_permission_missing_tf();
|
|
||||||
""",
|
|
||||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
|
||||||
}
|
}
|
||||||
case GUEST -> {
|
case GUEST -> {
|
||||||
// no permission check trigger generated, as anybody can insert rows into this table
|
// no permission check trigger generated, as anybody can insert rows into this table
|
||||||
@ -147,6 +122,7 @@ public class InsertTriggerGenerator {
|
|||||||
},
|
},
|
||||||
() -> {
|
() -> {
|
||||||
plPgSql.writeLn("""
|
plPgSql.writeLn("""
|
||||||
|
-- FIXME: Where is this case necessary?
|
||||||
create trigger ${rawSubTable}_insert_permission_check_tg
|
create trigger ${rawSubTable}_insert_permission_check_tg
|
||||||
before insert on ${rawSubTable}
|
before insert on ${rawSubTable}
|
||||||
for each row
|
for each row
|
||||||
@ -159,6 +135,92 @@ public class InsertTriggerGenerator {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void generateInsertPermissionTriggerAllowByDirectRole(final StringWriter plPgSql, final RbacView.RbacGrantDefinition g) {
|
||||||
|
plPgSql.writeLn("""
|
||||||
|
/**
|
||||||
|
Checks if the user or assumed roles are allowed to insert a row to ${rawSubTable}.
|
||||||
|
*/
|
||||||
|
create or replace function ${rawSubTable}_insert_permission_missing_tf()
|
||||||
|
returns trigger
|
||||||
|
language plpgsql as $$
|
||||||
|
begin
|
||||||
|
raise exception '[403] insert into ${rawSubTable} not allowed for current subjects % (%)',
|
||||||
|
currentSubjects(), currentSubjectsUuids();
|
||||||
|
end; $$;
|
||||||
|
|
||||||
|
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", rbacDef.getRootEntityAlias().getRawTableName()),
|
||||||
|
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}.
|
||||||
|
*/
|
||||||
|
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("""
|
||||||
|
/**
|
||||||
|
Checks if the user or assumed roles are allowed to insert a row to ${rawSubTable}.
|
||||||
|
*/
|
||||||
|
create or replace function ${rawSubTable}_insert_permission_missing_tf()
|
||||||
|
returns trigger
|
||||||
|
language plpgsql as $$
|
||||||
|
begin
|
||||||
|
raise exception '[403] insert into ${rawSubTable} not allowed for current subjects % (%)',
|
||||||
|
currentSubjects(), currentSubjectsUuids();
|
||||||
|
end; $$;
|
||||||
|
|
||||||
|
create trigger ${rawSubTable}_insert_permission_check_tg
|
||||||
|
before insert on ${rawSubTable}
|
||||||
|
for each row
|
||||||
|
when ( not isGlobalAdmin() )
|
||||||
|
execute procedure ${rawSubTable}_insert_permission_missing_tf();
|
||||||
|
""",
|
||||||
|
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||||
|
}
|
||||||
|
|
||||||
private Stream<RbacView.RbacGrantDefinition> getInsertGrants() {
|
private Stream<RbacView.RbacGrantDefinition> getInsertGrants() {
|
||||||
return rbacDef.getGrantDefs().stream()
|
return rbacDef.getGrantDefs().stream()
|
||||||
.filter(g -> g.grantType() == PERM_TO_ROLE)
|
.filter(g -> g.grantType() == PERM_TO_ROLE)
|
||||||
|
@ -38,12 +38,26 @@ public class StringWriter {
|
|||||||
--indentLevel;
|
--indentLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void indent(int levels) {
|
||||||
|
indentLevel += levels;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unindent(int levels) {
|
||||||
|
indentLevel -= levels;
|
||||||
|
}
|
||||||
|
|
||||||
void indented(final Runnable indented) {
|
void indented(final Runnable indented) {
|
||||||
indent();
|
indent();
|
||||||
indented.run();
|
indented.run();
|
||||||
unindent();
|
unindent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void indented(int levels, final Runnable indented) {
|
||||||
|
indent(levels);
|
||||||
|
indented.run();
|
||||||
|
unindent(levels);
|
||||||
|
}
|
||||||
|
|
||||||
boolean chopTail(final String tail) {
|
boolean chopTail(final String tail) {
|
||||||
if (string.toString().endsWith(tail)) {
|
if (string.toString().endsWith(tail)) {
|
||||||
string.setLength(string.length() - tail.length());
|
string.setLength(string.length() - tail.length());
|
||||||
|
@ -42,7 +42,9 @@ public class RbacGrantsDiagramService {
|
|||||||
PERMISSIONS,
|
PERMISSIONS,
|
||||||
NOT_ASSUMED,
|
NOT_ASSUMED,
|
||||||
TEST_ENTITIES,
|
TEST_ENTITIES,
|
||||||
NON_TEST_ENTITIES
|
NON_TEST_ENTITIES;
|
||||||
|
|
||||||
|
public static final EnumSet<Include> ALL = EnumSet.allOf(Include.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -65,6 +67,10 @@ public class RbacGrantsDiagramService {
|
|||||||
private void traverseGrantsTo(final Set<RawRbacGrantEntity> graph, final UUID refUuid, final EnumSet<Include> includes) {
|
private void traverseGrantsTo(final Set<RawRbacGrantEntity> graph, final UUID refUuid, final EnumSet<Include> includes) {
|
||||||
final var grants = rawGrantRepo.findByAscendingUuid(refUuid);
|
final var grants = rawGrantRepo.findByAscendingUuid(refUuid);
|
||||||
grants.forEach(g -> {
|
grants.forEach(g -> {
|
||||||
|
if ( g.getDescendantIdName() == null ) {
|
||||||
|
// FIXME: what's that?
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!includes.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm ")) {
|
if (!includes.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm ")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -116,7 +122,7 @@ public class RbacGrantsDiagramService {
|
|||||||
)
|
)
|
||||||
.collect(groupingBy(RbacGrantsDiagramService::renderEntityIdName))
|
.collect(groupingBy(RbacGrantsDiagramService::renderEntityIdName))
|
||||||
.entrySet().stream()
|
.entrySet().stream()
|
||||||
.map(entity -> "subgraph " + quoted(entity.getKey()) + renderSubgraph(entity.getKey()) + "\n\n "
|
.map(entity -> "subgraph " + cleanId(entity.getKey()) + renderSubgraph(entity.getKey()) + "\n\n "
|
||||||
+ entity.getValue().stream()
|
+ entity.getValue().stream()
|
||||||
.map(n -> renderNode(n.idName(), n.uuid()).replace("\n", "\n "))
|
.map(n -> renderNode(n.idName(), n.uuid()).replace("\n", "\n "))
|
||||||
.sorted()
|
.sorted()
|
||||||
@ -127,9 +133,9 @@ public class RbacGrantsDiagramService {
|
|||||||
: "";
|
: "";
|
||||||
|
|
||||||
final var grants = graph.stream()
|
final var grants = graph.stream()
|
||||||
.map(g -> quoted(g.getAscendantIdName())
|
.map(g -> cleanId(g.getAscendantIdName())
|
||||||
+ " -->" + (g.isAssumed() ? " " : "|XX| ")
|
+ " -->" + (g.isAssumed() ? " " : "|XX| ")
|
||||||
+ quoted(g.getDescendantIdName()))
|
+ cleanId(g.getDescendantIdName()))
|
||||||
.sorted()
|
.sorted()
|
||||||
.collect(joining("\n"));
|
.collect(joining("\n"));
|
||||||
|
|
||||||
@ -151,7 +157,7 @@ public class RbacGrantsDiagramService {
|
|||||||
// }
|
// }
|
||||||
// return "[" + table + "\n" + entity + "]";
|
// return "[" + table + "\n" + entity + "]";
|
||||||
// }
|
// }
|
||||||
return "[" + entityId + "]";
|
return "[" + cleanId(entityId) + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String renderEntityIdName(final Node node) {
|
private static String renderEntityIdName(final Node node) {
|
||||||
@ -170,7 +176,7 @@ public class RbacGrantsDiagramService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String renderNode(final String idName, final UUID uuid) {
|
private String renderNode(final String idName, final UUID uuid) {
|
||||||
return quoted(idName) + renderNodeContent(idName, uuid);
|
return cleanId(idName) + renderNodeContent(idName, uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String renderNodeContent(final String idName, final UUID uuid) {
|
private String renderNodeContent(final String idName, final UUID uuid) {
|
||||||
@ -196,8 +202,9 @@ public class RbacGrantsDiagramService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static String quoted(final String idName) {
|
private static String cleanId(final String idName) {
|
||||||
return idName.replace(" ", ":").replaceAll("@.*", "");
|
return idName.replace(" ", ":").replaceAll("@.*", "")
|
||||||
|
.replace("[", "").replace("]", "").replace("(", "").replace(")", "").replace(",", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
### rbac sepaMandate
|
### rbac sepaMandate
|
||||||
|
|
||||||
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-11T18:29:47.084556363.
|
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-15T06:12:35.337470470.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
@ -77,6 +77,7 @@ subgraph sepaMandate["`**sepaMandate**`"]
|
|||||||
perm:sepaMandate:DELETE{{sepaMandate:DELETE}}
|
perm:sepaMandate:DELETE{{sepaMandate:DELETE}}
|
||||||
perm:sepaMandate:UPDATE{{sepaMandate:UPDATE}}
|
perm:sepaMandate:UPDATE{{sepaMandate:UPDATE}}
|
||||||
perm:sepaMandate:SELECT{{sepaMandate:SELECT}}
|
perm:sepaMandate:SELECT{{sepaMandate:SELECT}}
|
||||||
|
perm:sepaMandate:INSERT{{sepaMandate:INSERT}}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -174,5 +175,6 @@ role:sepaMandate:referrer ==> role:debitorRel:tenant
|
|||||||
role:sepaMandate:owner ==> perm:sepaMandate:DELETE
|
role:sepaMandate:owner ==> perm:sepaMandate:DELETE
|
||||||
role:sepaMandate:admin ==> perm:sepaMandate:UPDATE
|
role:sepaMandate:admin ==> perm:sepaMandate:UPDATE
|
||||||
role:sepaMandate:referrer ==> perm:sepaMandate:SELECT
|
role:sepaMandate:referrer ==> perm:sepaMandate:SELECT
|
||||||
|
role:debitorRel:admin ==> perm:sepaMandate:INSERT
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
--liquibase formatted sql
|
--liquibase formatted sql
|
||||||
-- This code generated was by RbacViewPostgresGenerator at 2024-03-11T18:29:47.095199204.
|
-- This code generated was by RbacViewPostgresGenerator at 2024-03-15T06:12:35.345630060.
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-sepamandate-rbac-OBJECT:1 endDelimiter:--//
|
--changeset hs-office-sepamandate-rbac-OBJECT:1 endDelimiter:--//
|
||||||
@ -34,14 +35,23 @@ declare
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
call enterTriggerForObjectUuid(NEW.uuid);
|
call enterTriggerForObjectUuid(NEW.uuid);
|
||||||
SELECT * FROM hs_office_bankaccount WHERE uuid = NEW.bankAccountUuid into newBankAccount;
|
|
||||||
SELECT * FROM hs_office_relationship WHERE uuid = NEW.debitorUuid into newDebitorRel;
|
SELECT * FROM hs_office_bankaccount WHERE uuid = NEW.bankAccountUuid INTO newBankAccount;
|
||||||
|
assert newBankAccount.uuid is not null, format('newBankAccount must not be null for NEW.bankAccountUuid = %s', NEW.bankAccountUuid);
|
||||||
|
|
||||||
|
SELECT debitorRel.*
|
||||||
|
FROM hs_office_relationship debitorRel
|
||||||
|
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||||
|
WHERE debitor.uuid = NEW.debitorUuid
|
||||||
|
INTO newDebitorRel;
|
||||||
|
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorUuid = %s', NEW.debitorUuid);
|
||||||
|
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficeSepaMandateOwner(NEW),
|
hsOfficeSepaMandateOwner(NEW),
|
||||||
permissions => array['DELETE'],
|
permissions => array['DELETE'],
|
||||||
userUuids => array[currentUserUuid()],
|
incomingSuperRoles => array[globalAdmin()],
|
||||||
incomingSuperRoles => array[globalAdmin()]
|
userUuids => array[currentUserUuid()]
|
||||||
);
|
);
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
@ -54,16 +64,16 @@ begin
|
|||||||
hsOfficeSepaMandateAgent(NEW),
|
hsOfficeSepaMandateAgent(NEW),
|
||||||
incomingSuperRoles => array[hsOfficeSepaMandateAdmin(NEW)],
|
incomingSuperRoles => array[hsOfficeSepaMandateAdmin(NEW)],
|
||||||
outgoingSubRoles => array[
|
outgoingSubRoles => array[
|
||||||
hsOfficeBankAccountReferrer(newBankAccount),
|
hsOfficeRelationshipAgent(newDebitorRel),
|
||||||
hsOfficeRelationshipAgent(newDebitorRel)]
|
hsOfficeBankAccountReferrer(newBankAccount)]
|
||||||
);
|
);
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficeSepaMandateReferrer(NEW),
|
hsOfficeSepaMandateReferrer(NEW),
|
||||||
permissions => array['SELECT'],
|
permissions => array['SELECT'],
|
||||||
incomingSuperRoles => array[
|
incomingSuperRoles => array[
|
||||||
hsOfficeRelationshipAgent(newDebitorRel),
|
|
||||||
hsOfficeBankAccountAdmin(newBankAccount),
|
hsOfficeBankAccountAdmin(newBankAccount),
|
||||||
|
hsOfficeRelationshipAgent(newDebitorRel),
|
||||||
hsOfficeSepaMandateAgent(NEW)],
|
hsOfficeSepaMandateAgent(NEW)],
|
||||||
outgoingSubRoles => array[hsOfficeRelationshipTenant(newDebitorRel)]
|
outgoingSubRoles => array[hsOfficeRelationshipTenant(newDebitorRel)]
|
||||||
);
|
);
|
||||||
@ -88,13 +98,52 @@ create trigger insertTriggerForHsOfficeSepaMandate_tg
|
|||||||
after insert on hs_office_sepamandate
|
after insert on hs_office_sepamandate
|
||||||
for each row
|
for each row
|
||||||
execute procedure insertTriggerForHsOfficeSepaMandate_tf();
|
execute procedure insertTriggerForHsOfficeSepaMandate_tf();
|
||||||
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-sepamandate-rbac-INSERT:1 endDelimiter:--//
|
--changeset hs-office-sepamandate-rbac-INSERT:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
Creates INSERT INTO hs_office_sepamandate permissions for the related hs_office_relationship rows.
|
||||||
|
*/
|
||||||
|
do language plpgsql $$
|
||||||
|
declare
|
||||||
|
row hs_office_relationship;
|
||||||
|
permissionUuid uuid;
|
||||||
|
roleUuid uuid;
|
||||||
|
begin
|
||||||
|
call defineContext('create INSERT INTO hs_office_sepamandate permissions for the related hs_office_relationship rows');
|
||||||
|
|
||||||
|
FOR row IN SELECT * FROM hs_office_relationship
|
||||||
|
LOOP
|
||||||
|
roleUuid := findRoleId(hsOfficeRelationshipAdmin(row));
|
||||||
|
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_sepamandate');
|
||||||
|
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||||
|
END LOOP;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds hs_office_sepamandate INSERT permission to specified role of new hs_office_relationship rows.
|
||||||
|
*/
|
||||||
|
create or replace function hs_office_sepamandate_hs_office_relationship_insert_tf()
|
||||||
|
returns trigger
|
||||||
|
language plpgsql
|
||||||
|
strict as $$
|
||||||
|
begin
|
||||||
|
call grantPermissionToRole(
|
||||||
|
hsOfficeRelationshipAdmin(NEW),
|
||||||
|
createPermission(NEW.uuid, 'INSERT', 'hs_office_sepamandate'));
|
||||||
|
return NEW;
|
||||||
|
end; $$;
|
||||||
|
|
||||||
|
create trigger hs_office_sepamandate_hs_office_relationship_insert_tg
|
||||||
|
after insert on hs_office_relationship
|
||||||
|
for each row
|
||||||
|
execute procedure hs_office_sepamandate_hs_office_relationship_insert_tf();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_sepamandate.
|
Checks if the user or assumed roles are allowed to insert a row to hs_office_sepamandate.
|
||||||
*/
|
*/
|
||||||
@ -102,19 +151,29 @@ create or replace function hs_office_sepamandate_insert_permission_missing_tf()
|
|||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
raise exception '[403] insert into hs_office_sepamandate not allowed for current subjects % (%)',
|
if ( not hasInsertPermission(
|
||||||
|
( SELECT debitorRel.uuid FROM
|
||||||
|
|
||||||
|
(SELECT debitorRel.*
|
||||||
|
FROM hs_office_relationship debitorRel
|
||||||
|
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||||
|
WHERE debitor.uuid = NEW.debitorUuid
|
||||||
|
) AS debitorRel
|
||||||
|
|
||||||
|
), 'INSERT', 'hs_office_sepamandate') ) then
|
||||||
|
raise exception
|
||||||
|
'[403] insert into hs_office_sepamandate not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
|
end if;
|
||||||
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger hs_office_sepamandate_insert_permission_check_tg
|
create trigger hs_office_sepamandate_insert_permission_check_tg
|
||||||
before insert on hs_office_sepamandate
|
before insert on hs_office_sepamandate
|
||||||
for each row
|
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 hs_office_sepamandate_insert_permission_missing_tf();
|
execute procedure hs_office_sepamandate_insert_permission_missing_tf();
|
||||||
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-sepamandate-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-sepamandate-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
@ -125,13 +184,15 @@ create trigger hs_office_sepamandate_insert_permission_check_tg
|
|||||||
join hs_office_bankaccount ba on ba.uuid = sm.bankAccountUuid
|
join hs_office_bankaccount ba on ba.uuid = sm.bankAccountUuid
|
||||||
|
|
||||||
$idName$);
|
$idName$);
|
||||||
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-sepamandate-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-sepamandate-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacRestrictedView('hs_office_sepamandate',
|
call generateRbacRestrictedView('hs_office_sepamandate',
|
||||||
'validity',
|
$orderBy$
|
||||||
|
validity
|
||||||
|
$orderBy$,
|
||||||
$updates$
|
$updates$
|
||||||
reference = new.reference,
|
reference = new.reference,
|
||||||
agreement = new.agreement,
|
agreement = new.agreement,
|
||||||
@ -139,4 +200,3 @@ call generateRbacRestrictedView('hs_office_sepamandate',
|
|||||||
$updates$);
|
$updates$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user