WIP for fixing debitor RBAC definition + related references

This commit is contained in:
Michael Hoennig 2024-02-21 13:01:10 +01:00
parent 032ce6d16e
commit 8111e092ee
9 changed files with 149 additions and 122 deletions

View File

@ -27,8 +27,8 @@ create or replace function hsOfficeRelationshipRbacRolesTrigger()
language plpgsql
strict as $$
declare
newAnchorPerson hs_office_person;
newHolderPerson hs_office_person;
newAnchorPerson hs_office_person;
newHolderPerson hs_office_person;
oldContact hs_office_contact;
newContact hs_office_contact;
begin

View File

@ -11,7 +11,7 @@
create or replace procedure createHsOfficeRelationshipTestData(
holderPersonName varchar,
relationshipType HsOfficeRelationshipType,
anchorPersonTradeName varchar,
anchorPersonName varchar,
contactLabel varchar,
mark varchar default null)
language plpgsql as $$
@ -23,24 +23,28 @@ declare
contact hs_office_contact;
begin
idName := cleanIdentifier( anchorPersonTradeName || '-' || holderPersonName);
idName := cleanIdentifier( anchorPersonName || '-' || holderPersonName);
currentTask := 'creating relationship test-data ' || idName;
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin');
execute format('set local hsadminng.currentTask to %L', currentTask);
select p.* from hs_office_person p where p.tradeName = anchorPersonTradeName into anchorPerson;
select p.*
into anchorPerson
from hs_office_person p
where p.tradeName = anchorPersonName or p.familyName = anchorPersonName;
if anchorPerson is null then
raise exception 'anchorPerson "%" not found', anchorPersonTradeName;
raise exception 'anchorPerson "%" not found', anchorPersonName;
end if;
select p.* from hs_office_person p
where p.tradeName = holderPersonName or p.familyName = holderPersonName
into holderPerson;
select p.*
into holderPerson
from hs_office_person p
where p.tradeName = holderPersonName or p.familyName = holderPersonName;
if holderPerson is null then
raise exception 'holderPerson "%" not found', holderPersonName;
end if;
select c.* from hs_office_contact c where c.label = contactLabel into contact;
select c.* into contact from hs_office_contact c where c.label = contactLabel;
if contact is null then
raise exception 'contact "%" not found', contactLabel;
end if;
@ -87,17 +91,22 @@ do language plpgsql $$
begin
call createHsOfficeRelationshipTestData('First GmbH', 'PARTNER', 'Hostsharing eG', 'first contact');
call createHsOfficeRelationshipTestData('Firby', 'REPRESENTATIVE', 'First GmbH', 'first contact');
call createHsOfficeRelationshipTestData('First GmbH', 'ACCOUNTING', 'First GmbH', 'first contact');
call createHsOfficeRelationshipTestData('Second e.K.', 'PARTNER', 'Hostsharing eG', 'second contact');
call createHsOfficeRelationshipTestData('Smith', 'REPRESENTATIVE', 'Second e.K.', 'second contact');
call createHsOfficeRelationshipTestData('Second e.K.', 'ACCOUNTING', 'Second e.K.', 'second contact');
call createHsOfficeRelationshipTestData('Third OHG', 'PARTNER', 'Hostsharing eG', 'third contact');
call createHsOfficeRelationshipTestData('Tucker', 'REPRESENTATIVE', 'Third OHG', 'third contact');
call createHsOfficeRelationshipTestData('Third OHG', 'ACCOUNTING', 'Third OHG', 'third contact');
call createHsOfficeRelationshipTestData('Fourth eG', 'PARTNER', 'Hostsharing eG', 'fourth contact');
call createHsOfficeRelationshipTestData('Fouler', 'REPRESENTATIVE', 'Third OHG', 'third contact');
call createHsOfficeRelationshipTestData('Third OHG', 'ACCOUNTING', 'Third OHG', 'third contact');
call createHsOfficeRelationshipTestData('Smith', 'PARTNER', 'Hostsharing eG', 'sixth contact');
call createHsOfficeRelationshipTestData('Smith', 'ACCOUNTING', 'Smith', 'third contact', 'members-announce');
call createHsOfficeRelationshipTestData('Smith', 'SUBSCRIBER', 'Third OHG', 'third contact', 'members-announce');
end;
$$;

View File

@ -3,38 +3,48 @@
```mermaid
flowchart TB
%%% RbacEntity.builder().forEntity(HsOfficeBankAccountEntity.class)
%%% .alias("bankAccount")
%% the global subgraph would get imported implicitly by later usage
subgraph global
style hsOfficeBankAccount fill: #e9f7ef
style global fill: #eee
role:global.admin[global.admin]
end
subgraph hsOfficeBankAccount
direction TB
style hsOfficeBankAccount fill: #e9f7ef
user:hsOfficeBankAccount.creator([bankAccount.creator])
%%% .createRole(OWNER)
role:hsOfficeBankAccount.owner[[bankAccount.owner]]
%%% .withPermission(ALL)
%% permissions
role:hsOfficeBankAccount.owner --> perm:hsOfficeBankAccount.*{{hsOfficeBankAccount.delete}}
role:hsOfficeBankAccount.owner --> perm:hsOfficeBankAccount.*{{hsOfficeBankAccount.*}}
%% incoming
role:global.admin --> role:hsOfficeBankAccount.owner
%%% .withCreatorAsOwningUser()
user:hsOfficeBankAccount.creator ---> role:hsOfficeBankAccount.owner
%%% .withIncomingSuperRole(GlobalEntity.class, ADMIN)
role:global.admin --> role:hsOfficeBankAccount.owner
%%% .createSubRole(ADMIN)
role:hsOfficeBankAccount.admin[[bankAccount.admin]]
%% permissions
%%% .withPermission(EDIT)
role:hsOfficeBankAccount.admin --> perm:hsOfficeBankAccount.edit{{hsOfficeBankAccount.edit}}
%% incoming
role:hsOfficeBankAccount.owner ---> role:hsOfficeBankAccount.admin
role:hsOfficeBankAccount.tenant[[bankAccount.tenant]]
%% incoming
role:hsOfficeBankAccount.admin ---> role:hsOfficeBankAccount.tenant
role:hsOfficeBankAccount.guest[[bankAccount.guest]]
%%% .createSubRole(REFERRER)
role:hsOfficeBankAccount.referrer[[bankAccount.referrer]]
%% permissions
role:hsOfficeBankAccount.guest --> perm:hsOfficeBankAccount.view{{hsOfficeBankAccount.view}}
%%% .withPermission(VIEW)
role:hsOfficeBankAccount.referrer --> perm:hsOfficeBankAccount.view{{hsOfficeBankAccount.view}}
%% incoming
role:hsOfficeBankAccount.tenant ---> role:hsOfficeBankAccount.guest
role:hsOfficeBankAccount.admin ---> role:hsOfficeBankAccount.referrer
end
```

View File

@ -75,7 +75,7 @@ execute procedure createRbacRolesForHsOfficeBankAccount();
-- ----------------------------------------------------------------------------
call generateRbacIdentityView('hs_office_bankaccount', $idName$
target.holder
target.iban || ':' || target.holder
$idName$);
--//

View File

@ -15,19 +15,17 @@ subgraph hsOfficeBankAccount
role:hsOfficeBankAccount.owner[bankAccount.owner]
--> role:hsOfficeBankAccount.admin[bankAccount.admin]
--> role:hsOfficeBankAccount.tenant[bankAccount.tenant]
--> role:hsOfficeBankAccount.guest[bankAccount.guest]
--> role:hsOfficeBankAccount.referrer[bankAccount.referrer]
end
subgraph hsOfficeDebitor
subgraph hsOfficeRelationship:DEBITOR
direction TB
style hsOfficeDebitor fill:#eee
style hsOfficeRelationship:DEBITOR fill:#eee
role:hsOfficeDebitor.owner[debitor.admin]
--> role:hsOfficeDebitor.admin[debitor.admin]
--> role:hsOfficeDebitor.agent[debitor.agent]
--> role:hsOfficeDebitor.tenant[debitor.tenant]
--> role:hsOfficeDebitor.guest[debitor.guest]
role:hsOfficeRelationship:DEBITOR.owner[debitorRel.owner]
--> role:hsOfficeRelationship:DEBITOR.admin[debitorRel.admin]
--> role:hsOfficeRelationship:DEBITOR.agent[debitorRel.agent]
--> role:hsOfficeRelationship:DEBITOR.tenant[debitorRel.tenant]
end
subgraph hsOfficeSepaMandate
@ -47,24 +45,17 @@ subgraph hsOfficeSepaMandate
role:hsOfficeSepaMandate.agent[sepaMandate.agent]
%% incoming
role:hsOfficeSepaMandate.admin ---> role:hsOfficeSepaMandate.agent
role:hsOfficeDebitor.admin --> role:hsOfficeSepaMandate.agent
role:hsOfficeRelationship:DEBITOR.admin --> role:hsOfficeSepaMandate.agent
role:hsOfficeBankAccount.admin --> role:hsOfficeSepaMandate.agent
%% outgoing
role:hsOfficeSepaMandate.agent --> role:hsOfficeDebitor.tenant
role:hsOfficeSepaMandate.admin --> role:hsOfficeBankAccount.tenant
role:hsOfficeSepaMandate.admin --> role:hsOfficeBankAccount.referrer
role:hsOfficeSepaMandate.agent --> role:hsOfficeRelationship:DEBITOR.tenant
role:hsOfficeSepaMandate.agent --> role:hsOfficeBankAccount.referrer
role:hsOfficeSepaMandate.tenant[sepaMandate.tenant]
%% incoming
role:hsOfficeSepaMandate.agent --> role:hsOfficeSepaMandate.tenant
%% outgoing
role:hsOfficeSepaMandate.tenant --> role:hsOfficeDebitor.guest
role:hsOfficeSepaMandate.tenant --> role:hsOfficeBankAccount.guest
role:hsOfficeSepaMandate.guest[sepaMandate.guest]
%% permissions
role:hsOfficeSepaMandate.guest --> perm:hsOfficeSepaMandate.view{{sepaMandate.view}}
%% incoming
role:hsOfficeSepaMandate.tenant --> role:hsOfficeSepaMandate.guest
end

View File

@ -28,11 +28,13 @@ create or replace function hsOfficeSepaMandateRbacRolesTrigger()
strict as $$
declare
newHsOfficeDebitor hs_office_debitor;
newhsOfficeRelationship:DEBITOR hs_office_relationship;
newHsOfficeBankAccount hs_office_bankAccount;
begin
call enterTriggerForObjectUuid(NEW.uuid);
select * from hs_office_debitor as p where p.uuid = NEW.debitorUuid into newHsOfficeDebitor;
select * from hs_office_relationship as r where r.uuid = newHsOfficeDebitor.debitorRelUuid into newhsOfficeRelationship:DEBITOR;
select * from hs_office_bankAccount as c where c.uuid = NEW.bankAccountUuid into newHsOfficeBankAccount;
if TG_OP = 'INSERT' then
@ -48,20 +50,28 @@ begin
perform createRoleWithGrants(
hsOfficeSepaMandateAdmin(NEW),
permissions => array['edit'],
incomingSuperRoles => array[hsOfficeSepaMandateOwner(NEW)],
outgoingSubRoles => array[hsOfficeBankAccountTenant(newHsOfficeBankAccount)]
incomingSuperRoles => array[
hsOfficeSepaMandateOwner(NEW)],
outgoingSubRoles => array[
hsOfficeBankAccountTenant(newHsOfficeBankAccount)]
);
perform createRoleWithGrants(
hsOfficeSepaMandateAgent(NEW),
incomingSuperRoles => array[hsOfficeSepaMandateAdmin(NEW), hsOfficeDebitorAdmin(newHsOfficeDebitor), hsOfficeBankAccountAdmin(newHsOfficeBankAccount)],
outgoingSubRoles => array[hsOfficeDebitorTenant(newHsOfficeDebitor)]
incomingSuperRoles => array[
hsOfficeSepaMandateAdmin(NEW),
hsOfficeRelationshipAdmin(newhsOfficeRelationship:DEBITOR),
hsOfficeBankAccountAdmin(newHsOfficeBankAccount)],
outgoingSubRoles => array[
hsOfficeRelationshipTenant(newhsOfficeRelationship:DEBITOR)]
);
perform createRoleWithGrants(
hsOfficeSepaMandateTenant(NEW),
incomingSuperRoles => array[hsOfficeSepaMandateAgent(NEW)],
outgoingSubRoles => array[hsOfficeDebitorGuest(newHsOfficeDebitor), hsOfficeBankAccountGuest(newHsOfficeBankAccount)]
outgoingSubRoles => array[
hsOfficeRelationshipReferrer(newhsOfficeRelationship:DEBITOR),
hsOfficeBankAccountGuest(newHsOfficeBankAccount)]
);
perform createRoleWithGrants(

View File

@ -23,12 +23,14 @@ begin
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin');
execute format('set local hsadminng.currentTask to %L', currentTask);
select debitor.*
select debitor.* into relatedDebitor
from hs_office_debitor debitor
left join hs_office_partner partner on debitor.partneruuid = partner.uuid
where partner.partnerNumber = forPartnerNumber and debitor.debitorNumberSuffix = forDebitorSuffix
into relatedDebitor;
select b.* from hs_office_bankAccount b where b.iban = forIban into relatedBankAccount;
join hs_office_relationship debitorRel on debitorRel.uuid = debitor.debitorRelUuid
join hs_office_relationship partnerRel on partnerRel.relHolderUuid = debitorRel.relAnchorUuid
join hs_office_partner partner on partner.partnerRoleUuid = partnerRel.uuid
where partner.partnerNumber = forPartnerNumber and debitor.debitorNumberSuffix = forDebitorSuffix;
select b.* into relatedBankAccount
from hs_office_bankAccount b where b.iban = forIban;
raise notice 'creating test SEPA-mandate: %', forPartnerNumber::text || forDebitorSuffix::text;
raise notice '- using debitor (%): %', relatedDebitor.uuid, relatedDebitor;

View File

@ -36,71 +36,70 @@ begin
debitorUuid := NEW.uuid;
select * into newDebitorRel
from hs_office_relationship as r where r.relType = 'DEBITOR' and r.relHolderUuid = NEW.debitorRelUuid;
from hs_office_relationship as r where r.relType = 'ACCOUNTING' and r.relHolderUuid = NEW.debitorRelUuid;
select * into newPartnerRel
from hs_office_relationship as r
join hs_office_partner as p on p.partnerRoleUuid = r.uuid
where r.relType = 'PARTNER' and r.relHolderUuid = newPartnerRel;
from hs_office_relationship as partnerRel
where newDebitorRel.relAnchorUuid = partnerRel.relHolderUuid;
select * from hs_office_bankaccount as b where b.uuid = NEW.refundBankAccountUuid
into newBankAccount;
select * into newBankAccount
from hs_office_bankaccount as b where b.uuid = NEW.refundBankAccountUuid;
if TG_OP = 'INSERT' then
-- Permissions and Grants for Debitor
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipOwner(newDebitorRel), 'fail'),
createPermissions(partnerUuid, array ['*'])
);
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipAdmin(newDebitorRel), 'fail'),
createPermissions(partnerUuid, array ['edit'])
);
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipTenant(newDebitorRel), 'fail'),
createPermissions(partnerUuid, array ['view'])
);
-- call grantPermissionsToRole(
-- getRoleId(hsOfficeRelationshipOwner(newDebitorRel), 'fail'),
-- createPermissions(partnerUuid, array ['*'])
-- );
--
-- call grantPermissionsToRole(
-- getRoleId(hsOfficeRelationshipAdmin(newDebitorRel), 'fail'),
-- createPermissions(partnerUuid, array ['edit'])
-- );
--
-- call grantPermissionsToRole(
-- getRoleId(hsOfficeRelationshipTenant(newDebitorRel), 'fail'),
-- createPermissions(partnerUuid, array ['view'])
-- );
-- Grants to and from related Partner Relationship
call grantRoleToRole(hsOfficeRelationshipAdmin(newDebitorRel), hsOfficeRelationshipAdmin(newPartnerRel), true);
call grantRoleToRole(hsOfficeRelationshipAgent(newPartnerRel), hsOfficeRelationshipAdmin(newDebitorRel), true);
call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeRelationshipAgent(newPartnerRel), true);
call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRel), hsOfficeRelationshipAgent(newDebitorRel), true);
-- call grantRoleToRole(hsOfficeRelationshipAdmin(newDebitorRel), hsOfficeRelationshipAdmin(newPartnerRel), true);
-- call grantRoleToRole(hsOfficeRelationshipAgent(newPartnerRel), hsOfficeRelationshipAdmin(newDebitorRel), true);
--
-- call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeRelationshipAgent(newPartnerRel), true);
-- call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRel), hsOfficeRelationshipAgent(newDebitorRel), true);
-- Grants to and from refundBankAccount
if newBankAccount is not null then
call grantRoleToRole(hsOfficeBankAccountReferrer(newBankAccount), hsOfficeRelationshipAgent(newDebitorRel), true);
call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeBankAccountAdmin(newBankAccount), true);
end if;
-- if newBankAccount is not null then
-- call grantRoleToRole(hsOfficeBankAccountReferrer(newBankAccount), hsOfficeRelationshipAgent(newDebitorRel), true);
-- call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeBankAccountAdmin(newBankAccount), true);
-- end if;
elsif TG_OP = 'UPDATE' then
if OLD.debitorRelUuid is distinct from NEW.debitorRelUuid then
select * into oldDebitorRel
from hs_office_relationship as r where r.relType = 'DEBITOR' and r.relHolderUuid = NEW.debitorRelUuid;
from hs_office_relationship as r where r.relType = 'ACCOUNTING' and r.relHolderUuid = NEW.debitorRelUuid;
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipOwner(newDebitorRel), 'fail'),
createPermissions(partnerUuid, array ['*'])
);
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipAdmin(newDebitorRel), 'fail'),
createPermissions(partnerUuid, array ['edit'])
);
call grantPermissionsToRole(
getRoleId(hsOfficeRelationshipTenant(newDebitorRel), 'fail'),
createPermissions(partnerUuid, array ['view'])
);
-- call grantPermissionsToRole(
-- getRoleId(hsOfficeRelationshipOwner(newDebitorRel), 'fail'),
-- createPermissions(partnerUuid, array ['*'])
-- );
--
-- call grantPermissionsToRole(
-- getRoleId(hsOfficeRelationshipAdmin(newDebitorRel), 'fail'),
-- createPermissions(partnerUuid, array ['edit'])
-- );
--
-- call grantPermissionsToRole(
-- getRoleId(hsOfficeRelationshipTenant(newDebitorRel), 'fail'),
-- createPermissions(partnerUuid, array ['view'])
-- );
end if;
@ -182,10 +181,13 @@ execute procedure hsOfficeDebitorPartnerRelRbacRolesTrigger();
--changeset hs-office-debitor-rbac-IDENTITY-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call generateRbacIdentityView('hs_office_debitor', $idName$
'#' ||
(select partnerNumber from hs_office_partner p where p.uuid = target.partnerUuid) ||
to_char(debitorNumberSuffix, 'fm00') ||
':' || (select split_part(idName, ':', 2) from hs_office_partner_iv pi where pi.uuid = target.partnerUuid)
'#' || (select partner.partnerNumber
from hs_office_partner partner
join hs_office_relationship partnerRel on partnerRel.uuid = partner.partnerRoleUUid and partnerRel.relType = 'PARTNER'
join hs_office_relationship debitorRel on debitorRel.relAnchorUuid = partnerRel.relHolderUuid and partnerRel.relType = 'ACCOUNTING'
where debitorRel.uuid = target.debitorRelUuid)
|| to_char(debitorNumberSuffix, 'fm00')
|| ':' || (select split_part(idName, ':', 2) from hs_office_relationship_iv ri where ri.uuid = target.debitorRelUuid)
$idName$);
--//
@ -195,10 +197,9 @@ call generateRbacIdentityView('hs_office_debitor', $idName$
-- ----------------------------------------------------------------------------
call generateRbacRestrictedView('hs_office_debitor', 'target.debitorNumberSuffix',
$updates$
partnerUuid = new.partnerUuid, -- TODO: remove? should never do anything
debitorRel = new.debitorRel,
billable = new.billable,
billingContactUuid = new.billingContactUuid,
debitorNumberSuffix = new.debitorNumberSuffix, -- TODO: Should it be allowed to updated this value?
refundBankAccountUuid = new.refundBankAccountUuid,
vatId = new.vatId,
vatCountryCode = new.vatCountryCode,

View File

@ -9,37 +9,41 @@
Creates a single debitor test record.
*/
create or replace procedure createHsOfficeDebitorTestData(
debitorNumberSuffix numeric(5),
partnerTradeName varchar,
billingContactLabel varchar,
defaultPrefix varchar
withDebitorNumberSuffix numeric(5),
forPartnerPersonName varchar,
forBillingContactLabel varchar,
withDefaultPrefix varchar
)
language plpgsql as $$
declare
currentTask varchar;
idName varchar;
relatedPartner hs_office_partner;
relatedContact hs_office_contact;
relatedDebitorRelUuid uuid;
relatedBankAccountUuid uuid;
begin
idName := cleanIdentifier( partnerTradeName|| '-' || billingContactLabel);
idName := cleanIdentifier( forPartnerPersonName|| '-' || forBillingContactLabel);
currentTask := 'creating debitor test-data ' || idName;
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin');
execute format('set local hsadminng.currentTask to %L', currentTask);
select partner.* from hs_office_partner partner
join hs_office_relationship rel on rel.uuid = partner.partnerRoleUuid
join hs_office_person person on person.uuid = rel.relHolderUuid
where person.tradeName = partnerTradeName into relatedPartner;
select c.* from hs_office_contact c where c.label = billingContactLabel into relatedContact;
select b.uuid from hs_office_bankaccount b where b.holder = partnerTradeName into relatedBankAccountUuid;
select debitorRel.uuid
into relatedDebitorRelUuid
from hs_office_relationship debitorRel
join hs_office_person person on person.uuid = debitorRel.relHolderUuid
and (person.tradeName = forPartnerPersonName or person.familyName = forPartnerPersonName)
where debitorRel.relType = 'ACCOUNTING';
raise notice 'creating test debitor: % (#%)', idName, debitorNumberSuffix;
raise notice '- using partner (%): %', relatedPartner.uuid, relatedPartner;
raise notice '- using billingContact (%): %', relatedContact.uuid, relatedContact;
select b.uuid
into relatedBankAccountUuid
from hs_office_bankaccount b
where b.holder = forPartnerPersonName;
raise notice 'creating test debitor: % (#%)', idName, withDebitorNumberSuffix;
-- raise exception 'creating test debitor: (uuid=%, debitorRelUuid=%, debitornumbersuffix=%, billable=%, vatbusiness=%, vatreversecharge=%, refundbankaccountuuid=%, defaultprefix=%)',
-- uuid_generate_v4(), relatedDebitorRelUuid, withDebitorNumberSuffix, true, true, false, relatedBankAccountUuid, withDefaultPrefix;
insert
into hs_office_debitor (uuid, partneruuid, debitornumbersuffix, billable, billingcontactuuid, vatbusiness, vatreversecharge, refundbankaccountuuid, defaultprefix)
values (uuid_generate_v4(), relatedPartner.uuid, debitorNumberSuffix, true, relatedContact.uuid, true, false, relatedBankAccountUuid, defaultPrefix);
into hs_office_debitor (uuid, debitorRelUuid, debitornumbersuffix, billable, vatbusiness, vatreversecharge, refundbankaccountuuid, defaultprefix)
values (uuid_generate_v4(), relatedDebitorRelUuid, withDebitorNumberSuffix, true, true, false, relatedBankAccountUuid, withDefaultPrefix);
end; $$;
--//