Compare commits
No commits in common. "670ba8e9c910b2256a6d9727337f7b941f332a51" and "823269d8aa7ade7d3ccf01ef6110b43fda05ac42" have entirely different histories.
670ba8e9c9
...
823269d8aa
@ -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.directlyFetchedByDependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
|
||||||
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,22 +135,32 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
.createPermission(INSERT).grantedTo("global", ADMIN)
|
.createPermission(INSERT).grantedTo("global", ADMIN)
|
||||||
|
|
||||||
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationEntity.class,
|
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationEntity.class,
|
||||||
directlyFetchedByDependsOnColumn(),
|
fetchedBySql("""
|
||||||
|
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"),
|
dependsOnColumn("refundBankAccountUuid"), fetchedBySql("""
|
||||||
directlyFetchedByDependsOnColumn(),
|
SELECT *
|
||||||
|
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"),
|
dependsOnColumn("partnerRelUuid"), fetchedBySql("""
|
||||||
directlyFetchedByDependsOnColumn(),
|
SELECT *
|
||||||
|
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)
|
||||||
|
@ -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.directlyFetchedByDependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
|
||||||
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,
|
||||||
directlyFetchedByDependsOnColumn(),
|
fetchedBySql("SELECT * FROM hs_office_relation AS r WHERE r.uuid = ${ref}.partnerRelUuid"),
|
||||||
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,
|
||||||
directlyFetchedByDependsOnColumn(),
|
fetchedBySql("SELECT * FROM hs_office_partner_details AS d WHERE d.uuid = ${ref}.detailsUuid"),
|
||||||
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)
|
||||||
|
@ -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.directlyFetchedByDependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
|
||||||
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"),
|
||||||
directlyFetchedByDependsOnColumn(),
|
fetchedBySql("select * from hs_office_person as p where p.uuid = ${REF}.anchorUuid"),
|
||||||
NULLABLE)
|
NULLABLE)
|
||||||
.importEntityAlias("holderPerson", HsOfficePersonEntity.class,
|
.importEntityAlias("holderPerson", HsOfficePersonEntity.class,
|
||||||
dependsOnColumn("holderUuid"),
|
dependsOnColumn("holderUuid"),
|
||||||
directlyFetchedByDependsOnColumn(),
|
fetchedBySql("select * from hs_office_person as p where p.uuid = ${REF}.holderUuid"),
|
||||||
NULLABLE)
|
NULLABLE)
|
||||||
.importEntityAlias("contact", HsOfficeContactEntity.class,
|
.importEntityAlias("contact", HsOfficeContactEntity.class,
|
||||||
dependsOnColumn("contactUuid"),
|
dependsOnColumn("contactUuid"),
|
||||||
directlyFetchedByDependsOnColumn(),
|
fetchedBySql("select * from hs_office_contact as c where c.uuid = ${REF}.contactUuid"),
|
||||||
NULLABLE)
|
NULLABLE)
|
||||||
.createRole(OWNER, (with) -> {
|
.createRole(OWNER, (with) -> {
|
||||||
with.owningUser(CREATOR);
|
with.owningUser(CREATOR);
|
||||||
|
@ -114,12 +114,7 @@ public class InsertTriggerGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final var superRoleEntityAlias = g.getSuperRoleDef().getEntityAlias();
|
generateInsertPermissionTriggerAllowByRoleOfDirectForeignKey(plPgSql, g);
|
||||||
if (superRoleEntityAlias.fetchSql().part == RbacView.SQL.Part.AUTO_FETCH) {
|
|
||||||
generateInsertPermissionTriggerAllowByRoleOfDirectForeignKey(plPgSql, g);
|
|
||||||
} else {
|
|
||||||
generateInsertPermissionTriggerAllowByRoleOfIndirectForeignKey(plPgSql, g);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() -> {
|
() -> {
|
||||||
@ -154,50 +149,6 @@ 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("""
|
||||||
/**
|
/**
|
||||||
|
@ -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.directlyFetchedByDependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.autoFetched;
|
||||||
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, directlyFetchedByDependsOnColumn(), dependsOnColum, false, null);
|
importEntityAliasImpl(aliasName, entityClass, autoFetched(), dependsOnColum, false, null);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -839,10 +839,6 @@ 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());
|
||||||
}
|
}
|
||||||
@ -928,7 +924,7 @@ public class RbacView {
|
|||||||
*
|
*
|
||||||
* @return the wrapped SQL definition object
|
* @return the wrapped SQL definition object
|
||||||
*/
|
*/
|
||||||
public static SQL directlyFetchedByDependsOnColumn() {
|
public static SQL autoFetched() {
|
||||||
return new SQL(null, Part.AUTO_FETCH);
|
return new SQL(null, Part.AUTO_FETCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1037,23 +1033,6 @@ 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.
|
||||||
*/
|
*/
|
||||||
@ -1073,6 +1052,21 @@ public class RbacView {
|
|||||||
HsOfficeSepaMandateEntity.class,
|
HsOfficeSepaMandateEntity.class,
|
||||||
HsOfficeCoopSharesTransactionEntity.class,
|
HsOfficeCoopSharesTransactionEntity.class,
|
||||||
HsOfficeMembershipEntity.class
|
HsOfficeMembershipEntity.class
|
||||||
).forEach(RbacView::generateRbacView);
|
).forEach(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");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.directlyFetchedByDependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@ -50,7 +50,10 @@ public class TestDomainEntity implements HasUuid {
|
|||||||
|
|
||||||
.importEntityAlias("package", TestPackageEntity.class,
|
.importEntityAlias("package", TestPackageEntity.class,
|
||||||
dependsOnColumn("packageUuid"),
|
dependsOnColumn("packageUuid"),
|
||||||
directlyFetchedByDependsOnColumn(),
|
fetchedBySql("""
|
||||||
|
SELECT * FROM test_package p
|
||||||
|
WHERE p.uuid= ${ref}.packageUuid
|
||||||
|
"""),
|
||||||
NULLABLE)
|
NULLABLE)
|
||||||
.toRole("package", ADMIN).grantPermission(INSERT)
|
.toRole("package", ADMIN).grantPermission(INSERT)
|
||||||
|
|
||||||
|
@ -51,7 +51,10 @@ public class TestPackageEntity implements HasUuid {
|
|||||||
|
|
||||||
.importEntityAlias("customer", TestCustomerEntity.class,
|
.importEntityAlias("customer", TestCustomerEntity.class,
|
||||||
dependsOnColumn("customerUuid"),
|
dependsOnColumn("customerUuid"),
|
||||||
directlyFetchedByDependsOnColumn(),
|
fetchedBySql("""
|
||||||
|
SELECT * FROM test_customer c
|
||||||
|
WHERE c.uuid= ${ref}.customerUuid
|
||||||
|
"""),
|
||||||
NOT_NULL)
|
NOT_NULL)
|
||||||
.toRole("customer", ADMIN).grantPermission(INSERT)
|
.toRole("customer", ADMIN).grantPermission(INSERT)
|
||||||
|
|
||||||
|
@ -35,7 +35,9 @@ declare
|
|||||||
begin
|
begin
|
||||||
call enterTriggerForObjectUuid(NEW.uuid);
|
call enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM test_customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
SELECT * FROM test_customer c
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
@ -101,10 +103,14 @@ declare
|
|||||||
begin
|
begin
|
||||||
call enterTriggerForObjectUuid(NEW.uuid);
|
call enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM test_customer WHERE uuid = OLD.customerUuid INTO oldCustomer;
|
SELECT * FROM test_customer c
|
||||||
|
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 WHERE uuid = NEW.customerUuid INTO newCustomer;
|
SELECT * FROM test_customer c
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
@ -189,30 +195,22 @@ 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 an indirect role.
|
where the check is performed by a direct role.
|
||||||
|
|
||||||
An indirect role is a role FIXME.
|
A direct role is a role depending on a foreign key directly available in the NEW row.
|
||||||
*/
|
*/
|
||||||
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
|
||||||
if ( not hasInsertPermission(
|
raise exception '[403] insert into test_package not allowed for current subjects % (%)',
|
||||||
( SELECT customer.uuid FROM
|
currentSubjects(), currentSubjectsUuids();
|
||||||
|
|
||||||
(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();
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -35,7 +35,9 @@ declare
|
|||||||
begin
|
begin
|
||||||
call enterTriggerForObjectUuid(NEW.uuid);
|
call enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM test_package WHERE uuid = NEW.packageUuid INTO newPackage;
|
SELECT * FROM test_package p
|
||||||
|
WHERE p.uuid= NEW.packageUuid
|
||||||
|
INTO newPackage;
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
testDomainOwner(NEW),
|
testDomainOwner(NEW),
|
||||||
@ -161,30 +163,22 @@ 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 an indirect role.
|
where the check is performed by a direct role.
|
||||||
|
|
||||||
An indirect role is a role FIXME.
|
A direct role is a role depending on a foreign key directly available in the NEW row.
|
||||||
*/
|
*/
|
||||||
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
|
||||||
if ( not hasInsertPermission(
|
raise exception '[403] insert into test_domain not allowed for current subjects % (%)',
|
||||||
( SELECT package.uuid FROM
|
currentSubjects(), currentSubjectsUuids();
|
||||||
|
|
||||||
(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();
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -37,11 +37,11 @@ declare
|
|||||||
begin
|
begin
|
||||||
call enterTriggerForObjectUuid(NEW.uuid);
|
call enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office_person WHERE uuid = NEW.holderUuid INTO newHolderPerson;
|
select * from hs_office_person as p where p.uuid = NEW.holderUuid INTO newHolderPerson;
|
||||||
|
|
||||||
SELECT * FROM hs_office_person WHERE uuid = NEW.anchorUuid INTO newAnchorPerson;
|
select * from hs_office_person as p where p.uuid = NEW.anchorUuid INTO newAnchorPerson;
|
||||||
|
|
||||||
SELECT * FROM hs_office_contact WHERE uuid = NEW.contactUuid INTO newContact;
|
select * from hs_office_contact as c where c.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[
|
||||||
hsOfficeRelationOwner(NEW),
|
hsOfficePersonAdmin(newAnchorPerson),
|
||||||
hsOfficePersonAdmin(newAnchorPerson)]
|
hsOfficeRelationOwner(NEW)]
|
||||||
);
|
);
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficeRelationAgent(NEW),
|
hsOfficeRelationAgent(NEW),
|
||||||
incomingSuperRoles => array[
|
incomingSuperRoles => array[
|
||||||
hsOfficeRelationAdmin(NEW),
|
hsOfficePersonAdmin(newHolderPerson),
|
||||||
hsOfficePersonAdmin(newHolderPerson)]
|
hsOfficeRelationAdmin(NEW)]
|
||||||
);
|
);
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficeRelationTenant(NEW),
|
hsOfficeRelationTenant(NEW),
|
||||||
permissions => array['SELECT'],
|
permissions => array['SELECT'],
|
||||||
incomingSuperRoles => array[
|
incomingSuperRoles => array[
|
||||||
hsOfficeRelationAgent(NEW),
|
|
||||||
hsOfficeContactAdmin(newContact),
|
hsOfficeContactAdmin(newContact),
|
||||||
|
hsOfficeRelationAgent(NEW),
|
||||||
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);
|
||||||
|
@ -36,10 +36,10 @@ declare
|
|||||||
begin
|
begin
|
||||||
call enterTriggerForObjectUuid(NEW.uuid);
|
call enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office_relation WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
|
SELECT * FROM hs_office_relation AS r WHERE r.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 WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
|
SELECT * FROM hs_office_partner_details AS d WHERE d.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 WHERE uuid = OLD.partnerRelUuid INTO oldPartnerRel;
|
SELECT * FROM hs_office_relation AS r WHERE r.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 WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
|
SELECT * FROM hs_office_relation AS r WHERE r.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 WHERE uuid = OLD.detailsUuid INTO oldPartnerDetails;
|
SELECT * FROM hs_office_partner_details AS d WHERE d.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 WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
|
SELECT * FROM hs_office_partner_details AS d WHERE d.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);
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,17 +57,17 @@ begin
|
|||||||
hsOfficeSepaMandateAgent(NEW),
|
hsOfficeSepaMandateAgent(NEW),
|
||||||
incomingSuperRoles => array[hsOfficeSepaMandateAdmin(NEW)],
|
incomingSuperRoles => array[hsOfficeSepaMandateAdmin(NEW)],
|
||||||
outgoingSubRoles => array[
|
outgoingSubRoles => array[
|
||||||
hsOfficeBankAccountReferrer(newBankAccount),
|
hsOfficeRelationAgent(newDebitorRel),
|
||||||
hsOfficeRelationAgent(newDebitorRel)]
|
hsOfficeBankAccountReferrer(newBankAccount)]
|
||||||
);
|
);
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficeSepaMandateReferrer(NEW),
|
hsOfficeSepaMandateReferrer(NEW),
|
||||||
permissions => array['SELECT'],
|
permissions => array['SELECT'],
|
||||||
incomingSuperRoles => array[
|
incomingSuperRoles => array[
|
||||||
hsOfficeBankAccountAdmin(newBankAccount),
|
hsOfficeSepaMandateAgent(NEW),
|
||||||
hsOfficeRelationAgent(newDebitorRel),
|
hsOfficeRelationAgent(newDebitorRel),
|
||||||
hsOfficeSepaMandateAgent(NEW)],
|
hsOfficeBankAccountAdmin(newBankAccount)],
|
||||||
outgoingSubRoles => array[hsOfficeRelationTenant(newDebitorRel)]
|
outgoingSubRoles => array[hsOfficeRelationTenant(newDebitorRel)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -37,12 +37,21 @@ declare
|
|||||||
begin
|
begin
|
||||||
call enterTriggerForObjectUuid(NEW.uuid);
|
call enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
SELECT * FROM hs_office_relation WHERE uuid = NEW.partnerRelUuid INTO newPartnerRel;
|
SELECT *
|
||||||
|
FROM hs_office_relation AS partnerRel
|
||||||
|
WHERE ${debitorRel}.anchorUuid = partnerRel.holderUuid
|
||||||
|
INTO newPartnerRel;
|
||||||
|
|
||||||
SELECT * FROM hs_office_relation WHERE uuid = NEW.debitorRelUuid INTO newDebitorRel;
|
SELECT *
|
||||||
|
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 * FROM hs_office_bankaccount WHERE uuid = NEW.refundBankAccountUuid INTO newRefundBankAccount;
|
SELECT *
|
||||||
|
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));
|
||||||
|
@ -4,9 +4,8 @@ spring:
|
|||||||
platform: postgres
|
platform: postgres
|
||||||
|
|
||||||
datasource:
|
datasource:
|
||||||
url-tc: jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers
|
url: 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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user