Compare commits

...

2 Commits

14 changed files with 146 additions and 107 deletions

View File

@ -22,7 +22,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnCo
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify; import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@ -135,32 +135,22 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
.createPermission(INSERT).grantedTo("global", ADMIN) .createPermission(INSERT).grantedTo("global", ADMIN)
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationEntity.class, .importRootEntityAliasProxy("debitorRel", HsOfficeRelationEntity.class,
fetchedBySql(""" directlyFetchedByDependsOnColumn(),
SELECT *
FROM hs_office_relation AS r
WHERE r.type = 'DEBITOR' AND r.holderUuid = ${REF}.debitorRelUuid
"""),
dependsOnColumn("debitorRelUuid")) dependsOnColumn("debitorRelUuid"))
.createPermission(DELETE).grantedTo("debitorRel", OWNER) .createPermission(DELETE).grantedTo("debitorRel", OWNER)
.createPermission(UPDATE).grantedTo("debitorRel", ADMIN) .createPermission(UPDATE).grantedTo("debitorRel", ADMIN)
.createPermission(SELECT).grantedTo("debitorRel", TENANT) .createPermission(SELECT).grantedTo("debitorRel", TENANT)
.importEntityAlias("refundBankAccount", HsOfficeBankAccountEntity.class, .importEntityAlias("refundBankAccount", HsOfficeBankAccountEntity.class,
dependsOnColumn("refundBankAccountUuid"), fetchedBySql(""" dependsOnColumn("refundBankAccountUuid"),
SELECT * directlyFetchedByDependsOnColumn(),
FROM hs_office_relation AS r
WHERE r.type = 'DEBITOR' AND r.holderUuid = ${REF}.debitorRelUuid
"""),
NULLABLE) NULLABLE)
.toRole("refundBankAccount", ADMIN).grantRole("debitorRel", AGENT) .toRole("refundBankAccount", ADMIN).grantRole("debitorRel", AGENT)
.toRole("debitorRel", AGENT).grantRole("refundBankAccount", REFERRER) .toRole("debitorRel", AGENT).grantRole("refundBankAccount", REFERRER)
.importEntityAlias("partnerRel", HsOfficeRelationEntity.class, .importEntityAlias("partnerRel", HsOfficeRelationEntity.class,
dependsOnColumn("partnerRelUuid"), fetchedBySql(""" dependsOnColumn("partnerRelUuid"),
SELECT * directlyFetchedByDependsOnColumn(),
FROM hs_office_relation AS partnerRel
WHERE ${debitorRel}.anchorUuid = partnerRel.holderUuid
"""),
NULLABLE) NULLABLE)
.toRole("partnerRel", ADMIN).grantRole("debitorRel", ADMIN) .toRole("partnerRel", ADMIN).grantRole("debitorRel", ADMIN)
.toRole("partnerRel", AGENT).grantRole("debitorRel", AGENT) .toRole("partnerRel", AGENT).grantRole("debitorRel", AGENT)

View File

@ -22,7 +22,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnCo
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify; import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@ -93,14 +93,14 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
.createPermission(INSERT).grantedTo("global", ADMIN) .createPermission(INSERT).grantedTo("global", ADMIN)
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationEntity.class, .importRootEntityAliasProxy("partnerRel", HsOfficeRelationEntity.class,
fetchedBySql("SELECT * FROM hs_office_relation AS r WHERE r.uuid = ${ref}.partnerRelUuid"), directlyFetchedByDependsOnColumn(),
dependsOnColumn("partnerRelUuid")) dependsOnColumn("partnerRelUuid"))
.createPermission(DELETE).grantedTo("partnerRel", ADMIN) .createPermission(DELETE).grantedTo("partnerRel", ADMIN)
.createPermission(UPDATE).grantedTo("partnerRel", AGENT) .createPermission(UPDATE).grantedTo("partnerRel", AGENT)
.createPermission(SELECT).grantedTo("partnerRel", TENANT) .createPermission(SELECT).grantedTo("partnerRel", TENANT)
.importSubEntityAlias("partnerDetails", HsOfficePartnerDetailsEntity.class, .importSubEntityAlias("partnerDetails", HsOfficePartnerDetailsEntity.class,
fetchedBySql("SELECT * FROM hs_office_partner_details AS d WHERE d.uuid = ${ref}.detailsUuid"), directlyFetchedByDependsOnColumn(),
dependsOnColumn("detailsUuid")) dependsOnColumn("detailsUuid"))
.createPermission("partnerDetails", DELETE).grantedTo("partnerRel", ADMIN) .createPermission("partnerDetails", DELETE).grantedTo("partnerRel", ADMIN)
.createPermission("partnerDetails", UPDATE).grantedTo("partnerRel", AGENT) .createPermission("partnerDetails", UPDATE).grantedTo("partnerRel", AGENT)

View File

@ -20,7 +20,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify; import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@ -91,15 +91,15 @@ public class HsOfficeRelationEntity implements HasUuid, Stringifyable {
.withUpdatableColumns("contactUuid") .withUpdatableColumns("contactUuid")
.importEntityAlias("anchorPerson", HsOfficePersonEntity.class, .importEntityAlias("anchorPerson", HsOfficePersonEntity.class,
dependsOnColumn("anchorUuid"), dependsOnColumn("anchorUuid"),
fetchedBySql("select * from hs_office_person as p where p.uuid = ${REF}.anchorUuid"), directlyFetchedByDependsOnColumn(),
NULLABLE) NULLABLE)
.importEntityAlias("holderPerson", HsOfficePersonEntity.class, .importEntityAlias("holderPerson", HsOfficePersonEntity.class,
dependsOnColumn("holderUuid"), dependsOnColumn("holderUuid"),
fetchedBySql("select * from hs_office_person as p where p.uuid = ${REF}.holderUuid"), directlyFetchedByDependsOnColumn(),
NULLABLE) NULLABLE)
.importEntityAlias("contact", HsOfficeContactEntity.class, .importEntityAlias("contact", HsOfficeContactEntity.class,
dependsOnColumn("contactUuid"), dependsOnColumn("contactUuid"),
fetchedBySql("select * from hs_office_contact as c where c.uuid = ${REF}.contactUuid"), directlyFetchedByDependsOnColumn(),
NULLABLE) NULLABLE)
.createRole(OWNER, (with) -> { .createRole(OWNER, (with) -> {
with.owningUser(CREATOR); with.owningUser(CREATOR);

View File

@ -114,7 +114,12 @@ public class InsertTriggerGenerator {
} }
} }
} else { } else {
generateInsertPermissionTriggerAllowByRoleOfDirectForeignKey(plPgSql, g); final var superRoleEntityAlias = g.getSuperRoleDef().getEntityAlias();
if (superRoleEntityAlias.fetchSql().part == RbacView.SQL.Part.AUTO_FETCH) {
generateInsertPermissionTriggerAllowByRoleOfDirectForeignKey(plPgSql, g);
} else {
generateInsertPermissionTriggerAllowByRoleOfIndirectForeignKey(plPgSql, g);
}
} }
}, },
() -> { () -> {
@ -149,6 +154,50 @@ public class InsertTriggerGenerator {
with("referenceColumn", g.getSuperRoleDef().getEntityAlias().dependsOnColumName())); with("referenceColumn", g.getSuperRoleDef().getEntityAlias().dependsOnColumName()));
} }
private void generateInsertPermissionTriggerAllowByRoleOfIndirectForeignKey(
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) { private void generateInsertPermissionTriggerAllowOnlyGlobalAdmin(final StringWriter plPgSql) {
plPgSql.writeLn(""" plPgSql.writeLn("""
/** /**

View File

@ -34,7 +34,7 @@ import static java.util.Arrays.stream;
import static java.util.Optional.ofNullable; import static java.util.Optional.ofNullable;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.autoFetched; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static org.apache.commons.lang3.StringUtils.uncapitalize; import static org.apache.commons.lang3.StringUtils.uncapitalize;
@Getter @Getter
@ -343,7 +343,7 @@ public class RbacView {
public RbacView importEntityAlias( public RbacView importEntityAlias(
final String aliasName, final Class<? extends HasUuid> entityClass, final String aliasName, final Class<? extends HasUuid> entityClass,
final Column dependsOnColum) { final Column dependsOnColum) {
importEntityAliasImpl(aliasName, entityClass, autoFetched(), dependsOnColum, false, null); importEntityAliasImpl(aliasName, entityClass, directlyFetchedByDependsOnColumn(), dependsOnColum, false, null);
return this; return this;
} }
@ -839,6 +839,10 @@ public class RbacView {
}; };
} }
public boolean hasFetchSql() {
return fetchSql != null;
}
private String withoutEntitySuffix(final String simpleEntityName) { private String withoutEntitySuffix(final String simpleEntityName) {
return simpleEntityName.substring(0, simpleEntityName.length() - "Entity".length()); return simpleEntityName.substring(0, simpleEntityName.length() - "Entity".length());
} }
@ -924,7 +928,7 @@ public class RbacView {
* *
* @return the wrapped SQL definition object * @return the wrapped SQL definition object
*/ */
public static SQL autoFetched() { public static SQL directlyFetchedByDependsOnColumn() {
return new SQL(null, Part.AUTO_FETCH); return new SQL(null, Part.AUTO_FETCH);
} }
@ -1033,6 +1037,23 @@ public class RbacView {
} }
} }
private static void generateRbacView(final Class<? extends HasUuid> c) {
final Method mainMethod = stream(c.getMethods()).filter(
m -> isStatic(m.getModifiers()) && m.getName().equals("main")
)
.findFirst()
.orElse(null);
if (mainMethod != null) {
try {
mainMethod.invoke(null, new Object[] { null });
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
} else {
System.err.println("WARNING: no main method in: " + c.getName() + " => no RBAC rules generated");
}
}
/** /**
* This main method generates the RbacViews (PostgreSQL+diagram) for all given entity classes. * This main method generates the RbacViews (PostgreSQL+diagram) for all given entity classes.
*/ */
@ -1052,21 +1073,6 @@ public class RbacView {
HsOfficeSepaMandateEntity.class, HsOfficeSepaMandateEntity.class,
HsOfficeCoopSharesTransactionEntity.class, HsOfficeCoopSharesTransactionEntity.class,
HsOfficeMembershipEntity.class HsOfficeMembershipEntity.class
).forEach(c -> { ).forEach(RbacView::generateRbacView);
final Method mainMethod = stream(c.getMethods()).filter(
m -> isStatic(m.getModifiers()) && m.getName().equals("main")
)
.findFirst()
.orElse(null);
if (mainMethod != null) {
try {
mainMethod.invoke(null, new Object[] { null });
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
} else {
System.err.println("WARNING: no main method in: " + c.getName() + " => no RBAC rules generated");
}
});
} }
} }

View File

@ -17,7 +17,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnCo
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Entity @Entity
@ -50,10 +50,7 @@ public class TestDomainEntity implements HasUuid {
.importEntityAlias("package", TestPackageEntity.class, .importEntityAlias("package", TestPackageEntity.class,
dependsOnColumn("packageUuid"), dependsOnColumn("packageUuid"),
fetchedBySql(""" directlyFetchedByDependsOnColumn(),
SELECT * FROM test_package p
WHERE p.uuid= ${ref}.packageUuid
"""),
NULLABLE) NULLABLE)
.toRole("package", ADMIN).grantPermission(INSERT) .toRole("package", ADMIN).grantPermission(INSERT)

View File

@ -51,10 +51,7 @@ public class TestPackageEntity implements HasUuid {
.importEntityAlias("customer", TestCustomerEntity.class, .importEntityAlias("customer", TestCustomerEntity.class,
dependsOnColumn("customerUuid"), dependsOnColumn("customerUuid"),
fetchedBySql(""" directlyFetchedByDependsOnColumn(),
SELECT * FROM test_customer c
WHERE c.uuid= ${ref}.customerUuid
"""),
NOT_NULL) NOT_NULL)
.toRole("customer", ADMIN).grantPermission(INSERT) .toRole("customer", ADMIN).grantPermission(INSERT)

View File

@ -35,9 +35,7 @@ declare
begin begin
call enterTriggerForObjectUuid(NEW.uuid); call enterTriggerForObjectUuid(NEW.uuid);
SELECT * FROM test_customer c SELECT * FROM test_customer WHERE uuid = NEW.customerUuid INTO newCustomer;
WHERE c.uuid= NEW.customerUuid
INTO newCustomer;
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s', NEW.customerUuid); assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s', NEW.customerUuid);
@ -103,14 +101,10 @@ declare
begin begin
call enterTriggerForObjectUuid(NEW.uuid); call enterTriggerForObjectUuid(NEW.uuid);
SELECT * FROM test_customer c SELECT * FROM test_customer WHERE uuid = OLD.customerUuid INTO oldCustomer;
WHERE c.uuid= OLD.customerUuid
INTO oldCustomer;
assert oldCustomer.uuid is not null, format('oldCustomer must not be null for OLD.customerUuid = %s', OLD.customerUuid); assert oldCustomer.uuid is not null, format('oldCustomer must not be null for OLD.customerUuid = %s', OLD.customerUuid);
SELECT * FROM test_customer c SELECT * FROM test_customer WHERE uuid = NEW.customerUuid INTO newCustomer;
WHERE c.uuid= NEW.customerUuid
INTO newCustomer;
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s', NEW.customerUuid); assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s', NEW.customerUuid);
@ -195,22 +189,30 @@ execute procedure test_package_test_customer_insert_tf();
/** /**
Checks if the user or assumed roles are allowed to insert a row to test_package, Checks if the user or assumed roles are allowed to insert a row to test_package,
where the check is performed by a direct role. where the check is performed by an indirect role.
A direct role is a role depending on a foreign key directly available in the NEW row. An indirect role is a role FIXME.
*/ */
create or replace function test_package_insert_permission_missing_tf() create or replace function test_package_insert_permission_missing_tf()
returns trigger returns trigger
language plpgsql as $$ language plpgsql as $$
begin begin
raise exception '[403] insert into test_package not allowed for current subjects % (%)', if ( not hasInsertPermission(
currentSubjects(), currentSubjectsUuids(); ( SELECT customer.uuid FROM
(SELECT * FROM test_customer WHERE 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;
end; $$; end; $$;
create trigger test_package_insert_permission_check_tg create trigger test_package_insert_permission_check_tg
before insert on test_package before insert on test_package
for each row for each row
when ( not hasInsertPermission(NEW.customerUuid, 'INSERT', 'test_package') )
execute procedure test_package_insert_permission_missing_tf(); execute procedure test_package_insert_permission_missing_tf();
--// --//

View File

@ -35,9 +35,7 @@ declare
begin begin
call enterTriggerForObjectUuid(NEW.uuid); call enterTriggerForObjectUuid(NEW.uuid);
SELECT * FROM test_package p SELECT * FROM test_package WHERE uuid = NEW.packageUuid INTO newPackage;
WHERE p.uuid= NEW.packageUuid
INTO newPackage;
perform createRoleWithGrants( perform createRoleWithGrants(
testDomainOwner(NEW), testDomainOwner(NEW),
@ -163,22 +161,30 @@ execute procedure test_domain_test_package_insert_tf();
/** /**
Checks if the user or assumed roles are allowed to insert a row to test_domain, Checks if the user or assumed roles are allowed to insert a row to test_domain,
where the check is performed by a direct role. where the check is performed by an indirect role.
A direct role is a role depending on a foreign key directly available in the NEW row. An indirect role is a role FIXME.
*/ */
create or replace function test_domain_insert_permission_missing_tf() create or replace function test_domain_insert_permission_missing_tf()
returns trigger returns trigger
language plpgsql as $$ language plpgsql as $$
begin begin
raise exception '[403] insert into test_domain not allowed for current subjects % (%)', if ( not hasInsertPermission(
currentSubjects(), currentSubjectsUuids(); ( SELECT package.uuid FROM
(SELECT * FROM test_package WHERE 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;
end; $$; end; $$;
create trigger test_domain_insert_permission_check_tg create trigger test_domain_insert_permission_check_tg
before insert on test_domain before insert on test_domain
for each row for each row
when ( not hasInsertPermission(NEW.packageUuid, 'INSERT', 'test_domain') )
execute procedure test_domain_insert_permission_missing_tf(); execute procedure test_domain_insert_permission_missing_tf();
--// --//

View File

@ -37,11 +37,11 @@ declare
begin begin
call enterTriggerForObjectUuid(NEW.uuid); call enterTriggerForObjectUuid(NEW.uuid);
select * from hs_office_person as p where p.uuid = NEW.holderUuid INTO newHolderPerson; SELECT * FROM hs_office_person WHERE uuid = NEW.holderUuid INTO newHolderPerson;
select * from hs_office_person as p where p.uuid = NEW.anchorUuid INTO newAnchorPerson; SELECT * FROM hs_office_person WHERE uuid = NEW.anchorUuid INTO newAnchorPerson;
select * from hs_office_contact as c where c.uuid = NEW.contactUuid INTO newContact; SELECT * FROM hs_office_contact WHERE uuid = NEW.contactUuid INTO newContact;
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeRelationOwner(NEW), hsOfficeRelationOwner(NEW),
@ -54,28 +54,28 @@ begin
hsOfficeRelationAdmin(NEW), hsOfficeRelationAdmin(NEW),
permissions => array['UPDATE'], permissions => array['UPDATE'],
incomingSuperRoles => array[ incomingSuperRoles => array[
hsOfficePersonAdmin(newAnchorPerson), hsOfficeRelationOwner(NEW),
hsOfficeRelationOwner(NEW)] hsOfficePersonAdmin(newAnchorPerson)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeRelationAgent(NEW), hsOfficeRelationAgent(NEW),
incomingSuperRoles => array[ incomingSuperRoles => array[
hsOfficePersonAdmin(newHolderPerson), hsOfficeRelationAdmin(NEW),
hsOfficeRelationAdmin(NEW)] hsOfficePersonAdmin(newHolderPerson)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeRelationTenant(NEW), hsOfficeRelationTenant(NEW),
permissions => array['SELECT'], permissions => array['SELECT'],
incomingSuperRoles => array[ incomingSuperRoles => array[
hsOfficeContactAdmin(newContact),
hsOfficeRelationAgent(NEW), hsOfficeRelationAgent(NEW),
hsOfficeContactAdmin(newContact),
hsOfficePersonAdmin(newHolderPerson)], hsOfficePersonAdmin(newHolderPerson)],
outgoingSubRoles => array[ outgoingSubRoles => array[
hsOfficeContactReferrer(newContact),
hsOfficePersonReferrer(newAnchorPerson), hsOfficePersonReferrer(newAnchorPerson),
hsOfficePersonReferrer(newHolderPerson)] hsOfficePersonReferrer(newHolderPerson),
hsOfficeContactReferrer(newContact)]
); );
call leaveTriggerForObjectUuid(NEW.uuid); call leaveTriggerForObjectUuid(NEW.uuid);

View File

@ -36,10 +36,10 @@ declare
begin begin
call enterTriggerForObjectUuid(NEW.uuid); call enterTriggerForObjectUuid(NEW.uuid);
SELECT * FROM hs_office_relation AS r WHERE r.uuid = NEW.partnerRelUuid INTO newPartnerRel; SELECT * FROM hs_office_relation WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerRelUuid = %s', NEW.partnerRelUuid); assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerRelUuid = %s', NEW.partnerRelUuid);
SELECT * FROM hs_office_partner_details AS d WHERE d.uuid = NEW.detailsUuid INTO newPartnerDetails; SELECT * FROM hs_office_partner_details WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s', NEW.detailsUuid); assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s', NEW.detailsUuid);
call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationAdmin(newPartnerRel)); call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationAdmin(newPartnerRel));
@ -95,16 +95,16 @@ declare
begin begin
call enterTriggerForObjectUuid(NEW.uuid); call enterTriggerForObjectUuid(NEW.uuid);
SELECT * FROM hs_office_relation AS r WHERE r.uuid = OLD.partnerRelUuid INTO oldPartnerRel; SELECT * FROM hs_office_relation WHERE uuid = OLD.partnerRelUuid INTO oldPartnerRel;
assert oldPartnerRel.uuid is not null, format('oldPartnerRel must not be null for OLD.partnerRelUuid = %s', OLD.partnerRelUuid); assert oldPartnerRel.uuid is not null, format('oldPartnerRel must not be null for OLD.partnerRelUuid = %s', OLD.partnerRelUuid);
SELECT * FROM hs_office_relation AS r WHERE r.uuid = NEW.partnerRelUuid INTO newPartnerRel; SELECT * FROM hs_office_relation WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerRelUuid = %s', NEW.partnerRelUuid); assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerRelUuid = %s', NEW.partnerRelUuid);
SELECT * FROM hs_office_partner_details AS d WHERE d.uuid = OLD.detailsUuid INTO oldPartnerDetails; SELECT * FROM hs_office_partner_details WHERE uuid = OLD.detailsUuid INTO oldPartnerDetails;
assert oldPartnerDetails.uuid is not null, format('oldPartnerDetails must not be null for OLD.detailsUuid = %s', OLD.detailsUuid); assert oldPartnerDetails.uuid is not null, format('oldPartnerDetails must not be null for OLD.detailsUuid = %s', OLD.detailsUuid);
SELECT * FROM hs_office_partner_details AS d WHERE d.uuid = NEW.detailsUuid INTO newPartnerDetails; SELECT * FROM hs_office_partner_details WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s', NEW.detailsUuid); assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s', NEW.detailsUuid);

View File

@ -57,17 +57,17 @@ begin
hsOfficeSepaMandateAgent(NEW), hsOfficeSepaMandateAgent(NEW),
incomingSuperRoles => array[hsOfficeSepaMandateAdmin(NEW)], incomingSuperRoles => array[hsOfficeSepaMandateAdmin(NEW)],
outgoingSubRoles => array[ outgoingSubRoles => array[
hsOfficeRelationAgent(newDebitorRel), hsOfficeBankAccountReferrer(newBankAccount),
hsOfficeBankAccountReferrer(newBankAccount)] hsOfficeRelationAgent(newDebitorRel)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeSepaMandateReferrer(NEW), hsOfficeSepaMandateReferrer(NEW),
permissions => array['SELECT'], permissions => array['SELECT'],
incomingSuperRoles => array[ incomingSuperRoles => array[
hsOfficeSepaMandateAgent(NEW), hsOfficeBankAccountAdmin(newBankAccount),
hsOfficeRelationAgent(newDebitorRel), hsOfficeRelationAgent(newDebitorRel),
hsOfficeBankAccountAdmin(newBankAccount)], hsOfficeSepaMandateAgent(NEW)],
outgoingSubRoles => array[hsOfficeRelationTenant(newDebitorRel)] outgoingSubRoles => array[hsOfficeRelationTenant(newDebitorRel)]
); );

View File

@ -37,21 +37,12 @@ declare
begin begin
call enterTriggerForObjectUuid(NEW.uuid); call enterTriggerForObjectUuid(NEW.uuid);
SELECT * SELECT * FROM hs_office_relation WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
FROM hs_office_relation AS partnerRel
WHERE ${debitorRel}.anchorUuid = partnerRel.holderUuid
INTO newPartnerRel;
SELECT * SELECT * FROM hs_office_relation WHERE uuid = NEW.debitorRelUuid INTO newDebitorRel;
FROM hs_office_relation AS r
WHERE r.type = 'DEBITOR' AND r.holderUuid = NEW.debitorRelUuid
INTO newDebitorRel;
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorRelUuid = %s', NEW.debitorRelUuid); assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorRelUuid = %s', NEW.debitorRelUuid);
SELECT * SELECT * FROM hs_office_bankaccount WHERE uuid = NEW.refundBankAccountUuid INTO newRefundBankAccount;
FROM hs_office_relation AS r
WHERE r.type = 'DEBITOR' AND r.holderUuid = NEW.debitorRelUuid
INTO newRefundBankAccount;
call grantRoleToRole(hsOfficeBankAccountReferrer(newRefundBankAccount), hsOfficeRelationAgent(newDebitorRel)); call grantRoleToRole(hsOfficeBankAccountReferrer(newRefundBankAccount), hsOfficeRelationAgent(newDebitorRel));
call grantRoleToRole(hsOfficeRelationAdmin(newDebitorRel), hsOfficeRelationAdmin(newPartnerRel)); call grantRoleToRole(hsOfficeRelationAdmin(newDebitorRel), hsOfficeRelationAdmin(newPartnerRel));

View File

@ -4,8 +4,9 @@ spring:
platform: postgres platform: postgres
datasource: datasource:
url: jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers url-tc: jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers
url-local: jdbc:postgresql://localhost:5432/postgres url-local: jdbc:postgresql://localhost:5432/postgres
url: ${spring.datasource.url-tc}
username: postgres username: postgres
password: password password: password