generate indirect permission by indirect foreign key depending on directlyFetchedByDependsOnColumn vs. fetchedBySql
This commit is contained in:
parent
e6ef5b59c7
commit
29c7708188
@ -25,6 +25,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||
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.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.stringify.Stringify.stringify;
|
||||
@ -161,11 +162,7 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
||||
|
||||
.importEntityAlias("refundBankAccount", HsOfficeBankAccountEntity.class,
|
||||
dependsOnColumn("refundBankAccountUuid"),
|
||||
fetchedBySql("""
|
||||
SELECT *
|
||||
FROM hs_office_bankaccount AS b
|
||||
WHERE b.uuid = ${REF}.refundBankAccountUuid
|
||||
"""),
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
NULLABLE)
|
||||
.toRole("refundBankAccount", ADMIN).grantRole("debitorRel", AGENT)
|
||||
.toRole("debitorRel", AGENT).grantRole("refundBankAccount", REFERRER)
|
||||
|
@ -115,7 +115,7 @@ public class HsOfficeSepaMandateEntity implements Stringifyable, HasUuid {
|
||||
NOT_NULL)
|
||||
.importEntityAlias("bankAccount", HsOfficeBankAccountEntity.class,
|
||||
dependsOnColumn("bankAccountUuid"),
|
||||
autoFetched(),
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
NOT_NULL)
|
||||
|
||||
.createRole(OWNER, (with) -> {
|
||||
|
@ -115,14 +115,11 @@ public class InsertTriggerGenerator {
|
||||
}
|
||||
} else {
|
||||
final var superRoleEntityAlias = g.getSuperRoleDef().getEntityAlias();
|
||||
if (superRoleEntityAlias.fetchSql().part == RbacView.SQL.Part.AUTO_FETCH) {
|
||||
|
||||
// TODO: Maybe this should depend on the indirection degree of the fetchSql?
|
||||
// Maybe we need a separate fetchedBy method for all the simple, direct cases?
|
||||
if (superRoleEntityAlias.fetchSql().sql.contains("JOIN ")) {
|
||||
generateInsertPermissionTriggerAllowByRoleOfIndirectForeignKey(plPgSql, g);
|
||||
} else {
|
||||
generateInsertPermissionTriggerAllowByRoleOfDirectForeignKey(plPgSql, g);
|
||||
|
||||
} else {
|
||||
generateInsertPermissionTriggerAllowByRoleOfIndirectForeignKey(plPgSql, g);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -34,7 +34,7 @@ import static java.util.Arrays.stream;
|
||||
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.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;
|
||||
|
||||
@Getter
|
||||
@ -343,7 +343,7 @@ public class RbacView {
|
||||
public RbacView importEntityAlias(
|
||||
final String aliasName, final Class<? extends HasUuid> entityClass,
|
||||
final Column dependsOnColum) {
|
||||
importEntityAliasImpl(aliasName, entityClass, autoFetched(), dependsOnColum, false, null);
|
||||
importEntityAliasImpl(aliasName, entityClass, directlyFetchedByDependsOnColumn(), dependsOnColum, false, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -928,7 +928,7 @@ public class RbacView {
|
||||
*
|
||||
* @return the wrapped SQL definition object
|
||||
*/
|
||||
public static SQL autoFetched() {
|
||||
public static SQL directlyFetchedByDependsOnColumn() {
|
||||
return new SQL(null, Part.AUTO_FETCH);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnCo
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||
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.SQL.fetchedBySql;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@ -50,10 +50,7 @@ public class TestDomainEntity implements HasUuid {
|
||||
|
||||
.importEntityAlias("package", TestPackageEntity.class,
|
||||
dependsOnColumn("packageUuid"),
|
||||
fetchedBySql("""
|
||||
SELECT * FROM test_package p
|
||||
WHERE p.uuid= ${ref}.packageUuid
|
||||
"""),
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
NOT_NULL)
|
||||
.toRole("package", ADMIN).grantPermission(INSERT)
|
||||
|
||||
|
@ -51,10 +51,7 @@ public class TestPackageEntity implements HasUuid {
|
||||
|
||||
.importEntityAlias("customer", TestCustomerEntity.class,
|
||||
dependsOnColumn("customerUuid"),
|
||||
fetchedBySql("""
|
||||
SELECT * FROM test_customer c
|
||||
WHERE c.uuid= ${ref}.customerUuid
|
||||
"""),
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
NOT_NULL)
|
||||
.toRole("customer", ADMIN).grantPermission(INSERT)
|
||||
|
||||
|
@ -35,9 +35,7 @@ declare
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM test_customer c
|
||||
WHERE c.uuid= NEW.customerUuid
|
||||
INTO newCustomer;
|
||||
SELECT * FROM test_customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
||||
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s', NEW.customerUuid);
|
||||
|
||||
|
||||
@ -103,14 +101,10 @@ declare
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM test_customer c
|
||||
WHERE c.uuid= OLD.customerUuid
|
||||
INTO oldCustomer;
|
||||
SELECT * FROM test_customer WHERE uuid = OLD.customerUuid INTO oldCustomer;
|
||||
assert oldCustomer.uuid is not null, format('oldCustomer must not be null for OLD.customerUuid = %s', OLD.customerUuid);
|
||||
|
||||
SELECT * FROM test_customer c
|
||||
WHERE c.uuid= NEW.customerUuid
|
||||
INTO newCustomer;
|
||||
SELECT * FROM test_customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
||||
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,
|
||||
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()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into test_package not allowed for current subjects % (%)',
|
||||
if ( not hasInsertPermission(
|
||||
( 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; $$;
|
||||
|
||||
create trigger test_package_insert_permission_check_tg
|
||||
before insert on test_package
|
||||
for each row
|
||||
when ( not hasInsertPermission(NEW.customerUuid, 'INSERT', 'test_package') )
|
||||
execute procedure test_package_insert_permission_missing_tf();
|
||||
--//
|
||||
|
||||
|
@ -35,9 +35,7 @@ declare
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM test_package p
|
||||
WHERE p.uuid= NEW.packageUuid
|
||||
INTO newPackage;
|
||||
SELECT * FROM test_package WHERE uuid = NEW.packageUuid INTO newPackage;
|
||||
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s', NEW.packageUuid);
|
||||
|
||||
|
||||
@ -99,14 +97,10 @@ declare
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM test_package p
|
||||
WHERE p.uuid= OLD.packageUuid
|
||||
INTO oldPackage;
|
||||
SELECT * FROM test_package WHERE uuid = OLD.packageUuid INTO oldPackage;
|
||||
assert oldPackage.uuid is not null, format('oldPackage must not be null for OLD.packageUuid = %s', OLD.packageUuid);
|
||||
|
||||
SELECT * FROM test_package p
|
||||
WHERE p.uuid= NEW.packageUuid
|
||||
INTO newPackage;
|
||||
SELECT * FROM test_package WHERE uuid = NEW.packageUuid INTO newPackage;
|
||||
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s', NEW.packageUuid);
|
||||
|
||||
|
||||
@ -194,22 +188,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,
|
||||
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()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into test_domain not allowed for current subjects % (%)',
|
||||
if ( not hasInsertPermission(
|
||||
( 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; $$;
|
||||
|
||||
create trigger test_domain_insert_permission_check_tg
|
||||
before insert on test_domain
|
||||
for each row
|
||||
when ( not hasInsertPermission(NEW.packageUuid, 'INSERT', 'test_domain') )
|
||||
execute procedure test_domain_insert_permission_missing_tf();
|
||||
--//
|
||||
|
||||
|
@ -58,8 +58,8 @@ begin
|
||||
hsOfficeRelationAdmin(NEW),
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[
|
||||
hsOfficeRelationOwner(NEW),
|
||||
hsOfficePersonAdmin(newAnchorPerson)]
|
||||
hsOfficePersonAdmin(newAnchorPerson),
|
||||
hsOfficeRelationOwner(NEW)]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
@ -73,13 +73,13 @@ begin
|
||||
hsOfficeRelationTenant(NEW),
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[
|
||||
hsOfficeRelationAgent(NEW),
|
||||
hsOfficePersonAdmin(newHolderPerson),
|
||||
hsOfficeContactAdmin(newContact),
|
||||
hsOfficeRelationAgent(NEW)],
|
||||
hsOfficeContactAdmin(newContact)],
|
||||
outgoingSubRoles => array[
|
||||
hsOfficePersonReferrer(newHolderPerson),
|
||||
hsOfficePersonReferrer(newAnchorPerson),
|
||||
hsOfficeContactReferrer(newContact)]
|
||||
hsOfficeContactReferrer(newContact),
|
||||
hsOfficePersonReferrer(newHolderPerson)]
|
||||
);
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
@ -228,22 +228,30 @@ execute procedure hs_office_relation_hs_office_person_insert_tf();
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_relation,
|
||||
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 hs_office_relation_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into hs_office_relation not allowed for current subjects % (%)',
|
||||
if ( not hasInsertPermission(
|
||||
( SELECT anchorPerson.uuid FROM
|
||||
|
||||
(select * from hs_office_person as p where p.uuid = NEW.anchorUuid) AS anchorPerson
|
||||
|
||||
), 'INSERT', 'hs_office_relation') ) then
|
||||
raise exception
|
||||
'[403] insert into hs_office_relation not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end if;
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_relation_insert_permission_check_tg
|
||||
before insert on hs_office_relation
|
||||
for each row
|
||||
when ( not hasInsertPermission(NEW.anchorUuid, 'INSERT', 'hs_office_relation') )
|
||||
execute procedure hs_office_relation_insert_permission_missing_tf();
|
||||
--//
|
||||
|
||||
|
@ -72,9 +72,9 @@ begin
|
||||
hsOfficeSepaMandateReferrer(NEW),
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[
|
||||
hsOfficeRelationAgent(newDebitorRel),
|
||||
hsOfficeSepaMandateAgent(NEW),
|
||||
hsOfficeBankAccountAdmin(newBankAccount),
|
||||
hsOfficeRelationAgent(newDebitorRel)],
|
||||
hsOfficeBankAccountAdmin(newBankAccount)],
|
||||
outgoingSubRoles => array[hsOfficeRelationTenant(newDebitorRel)]
|
||||
);
|
||||
|
||||
|
@ -52,10 +52,7 @@ begin
|
||||
INTO newDebitorRel;
|
||||
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorRelUuid = %s', NEW.debitorRelUuid);
|
||||
|
||||
SELECT *
|
||||
FROM hs_office_bankaccount AS b
|
||||
WHERE b.uuid = NEW.refundBankAccountUuid
|
||||
INTO newRefundBankAccount;
|
||||
SELECT * FROM hs_office_bankaccount WHERE uuid = NEW.refundBankAccountUuid INTO newRefundBankAccount;
|
||||
|
||||
call grantRoleToRole(hsOfficeBankAccountReferrer(newRefundBankAccount), hsOfficeRelationAgent(newDebitorRel));
|
||||
call grantRoleToRole(hsOfficeRelationAdmin(newDebitorRel), hsOfficeRelationAdmin(newPartnerRel));
|
||||
|
Loading…
Reference in New Issue
Block a user