1
0

RBAC generator with conditional grants used for REPRESENTATIVE-Relation (#33)

Co-authored-by: Michael Hoennig <michael@hoennig.de>
Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/33
Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
Michael Hoennig
2024-04-08 11:16:06 +02:00
parent 896968e110
commit 44ff30c54a
29 changed files with 567 additions and 375 deletions

View File

@ -0,0 +1,102 @@
### rbac relation inCaseOf:REPRESENTATIVE
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
```mermaid
%%{init:{'flowchart':{'htmlLabels':false}}}%%
flowchart TB
subgraph holderPerson["`**holderPerson**`"]
direction TB
style holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph holderPerson:roles[ ]
style holderPerson:roles fill:#99bcdb,stroke:white
role:holderPerson:OWNER[[holderPerson:OWNER]]
role:holderPerson:ADMIN[[holderPerson:ADMIN]]
role:holderPerson:REFERRER[[holderPerson:REFERRER]]
end
end
subgraph anchorPerson["`**anchorPerson**`"]
direction TB
style anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph anchorPerson:roles[ ]
style anchorPerson:roles fill:#99bcdb,stroke:white
role:anchorPerson:OWNER[[anchorPerson:OWNER]]
role:anchorPerson:ADMIN[[anchorPerson:ADMIN]]
role:anchorPerson:REFERRER[[anchorPerson:REFERRER]]
end
end
subgraph contact["`**contact**`"]
direction TB
style contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph contact:roles[ ]
style contact:roles fill:#99bcdb,stroke:white
role:contact:OWNER[[contact:OWNER]]
role:contact:ADMIN[[contact:ADMIN]]
role:contact:REFERRER[[contact:REFERRER]]
end
end
subgraph relation["`**relation**`"]
direction TB
style relation fill:#dd4901,stroke:#274d6e,stroke-width:8px
subgraph relation:roles[ ]
style relation:roles fill:#dd4901,stroke:white
role:relation:OWNER[[relation:OWNER]]
role:relation:ADMIN[[relation:ADMIN]]
role:relation:AGENT[[relation:AGENT]]
role:relation:TENANT[[relation:TENANT]]
end
subgraph relation:permissions[ ]
style relation:permissions fill:#dd4901,stroke:white
perm:relation:DELETE{{relation:DELETE}}
perm:relation:UPDATE{{relation:UPDATE}}
perm:relation:SELECT{{relation:SELECT}}
perm:relation:INSERT{{relation:INSERT}}
end
end
%% granting roles to users
user:creator ==> role:relation:OWNER
%% granting roles to roles
role:global:ADMIN -.-> role:anchorPerson:OWNER
role:anchorPerson:OWNER -.-> role:anchorPerson:ADMIN
role:anchorPerson:ADMIN -.-> role:anchorPerson:REFERRER
role:global:ADMIN -.-> role:holderPerson:OWNER
role:holderPerson:OWNER -.-> role:holderPerson:ADMIN
role:holderPerson:ADMIN -.-> role:holderPerson:REFERRER
role:global:ADMIN -.-> role:contact:OWNER
role:contact:OWNER -.-> role:contact:ADMIN
role:contact:ADMIN -.-> role:contact:REFERRER
role:global:ADMIN ==> role:relation:OWNER
role:holderPerson:ADMIN ==> role:relation:OWNER
role:relation:OWNER ==> role:relation:ADMIN
role:relation:ADMIN ==> role:anchorPerson:OWNER
role:relation:ADMIN ==> role:relation:AGENT
role:anchorPerson:ADMIN ==> role:relation:AGENT
role:relation:AGENT ==> role:relation:TENANT
role:contact:ADMIN ==> role:relation:TENANT
role:relation:TENANT ==> role:anchorPerson:REFERRER
role:relation:TENANT ==> role:holderPerson:REFERRER
role:relation:TENANT ==> role:contact:REFERRER
%% granting permissions to roles
role:relation:OWNER ==> perm:relation:DELETE
role:relation:ADMIN ==> perm:relation:UPDATE
role:relation:TENANT ==> perm:relation:SELECT
role:anchorPerson:ADMIN ==> perm:relation:INSERT
```

View File

@ -1,4 +1,4 @@
### rbac relation
### rbac relation inOtherCases
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
@ -83,15 +83,14 @@ role:contact:OWNER -.-> role:contact:ADMIN
role:contact:ADMIN -.-> role:contact:REFERRER
role:global:ADMIN ==> role:relation:OWNER
role:relation:OWNER ==> role:relation:ADMIN
role:anchorPerson:ADMIN ==> role:relation:ADMIN
role:relation:ADMIN ==> role:relation:AGENT
role:holderPerson:ADMIN ==> role:relation:AGENT
role:relation:AGENT ==> role:relation:TENANT
role:holderPerson:ADMIN ==> role:relation:TENANT
role:contact:ADMIN ==> role:relation:TENANT
role:relation:TENANT ==> role:anchorPerson:REFERRER
role:relation:TENANT ==> role:holderPerson:REFERRER
role:relation:TENANT ==> role:contact:REFERRER
role:anchorPerson:ADMIN ==> role:relation:OWNER
role:holderPerson:ADMIN ==> role:relation:AGENT
%% granting permissions to roles
role:relation:OWNER ==> perm:relation:DELETE

View File

@ -57,16 +57,12 @@ begin
perform createRoleWithGrants(
hsOfficeRelationADMIN(NEW),
permissions => array['UPDATE'],
incomingSuperRoles => array[
hsOfficePersonADMIN(newAnchorPerson),
hsOfficeRelationOWNER(NEW)]
incomingSuperRoles => array[hsOfficeRelationOWNER(NEW)]
);
perform createRoleWithGrants(
hsOfficeRelationAGENT(NEW),
incomingSuperRoles => array[
hsOfficePersonADMIN(newHolderPerson),
hsOfficeRelationADMIN(NEW)]
incomingSuperRoles => array[hsOfficeRelationADMIN(NEW)]
);
perform createRoleWithGrants(
@ -74,7 +70,6 @@ begin
permissions => array['SELECT'],
incomingSuperRoles => array[
hsOfficeContactADMIN(newContact),
hsOfficePersonADMIN(newHolderPerson),
hsOfficeRelationAGENT(NEW)],
outgoingSubRoles => array[
hsOfficeContactREFERRER(newContact),
@ -82,6 +77,15 @@ begin
hsOfficePersonREFERRER(newHolderPerson)]
);
IF NEW.type = 'REPRESENTATIVE' THEN
call grantRoleToRole(hsOfficePersonOWNER(newAnchorPerson), hsOfficeRelationADMIN(NEW));
call grantRoleToRole(hsOfficeRelationAGENT(NEW), hsOfficePersonADMIN(newAnchorPerson));
call grantRoleToRole(hsOfficeRelationOWNER(NEW), hsOfficePersonADMIN(newHolderPerson));
ELSE
call grantRoleToRole(hsOfficeRelationAGENT(NEW), hsOfficePersonADMIN(newHolderPerson));
call grantRoleToRole(hsOfficeRelationOWNER(NEW), hsOfficePersonADMIN(newAnchorPerson));
END IF;
call leaveTriggerForObjectUuid(NEW.uuid);
end; $$;
@ -118,48 +122,12 @@ create or replace procedure updateRbacRulesForHsOfficeRelation(
NEW hs_office_relation
)
language plpgsql as $$
declare
oldHolderPerson hs_office_person;
newHolderPerson hs_office_person;
oldAnchorPerson hs_office_person;
newAnchorPerson hs_office_person;
oldContact hs_office_contact;
newContact hs_office_contact;
begin
call enterTriggerForObjectUuid(NEW.uuid);
SELECT * FROM hs_office_person WHERE uuid = OLD.holderUuid INTO oldHolderPerson;
assert oldHolderPerson.uuid is not null, format('oldHolderPerson must not be null for OLD.holderUuid = %s', OLD.holderUuid);
SELECT * FROM hs_office_person WHERE uuid = NEW.holderUuid INTO newHolderPerson;
assert newHolderPerson.uuid is not null, format('newHolderPerson must not be null for NEW.holderUuid = %s', NEW.holderUuid);
SELECT * FROM hs_office_person WHERE uuid = OLD.anchorUuid INTO oldAnchorPerson;
assert oldAnchorPerson.uuid is not null, format('oldAnchorPerson must not be null for OLD.anchorUuid = %s', OLD.anchorUuid);
SELECT * FROM hs_office_person WHERE uuid = NEW.anchorUuid INTO newAnchorPerson;
assert newAnchorPerson.uuid is not null, format('newAnchorPerson must not be null for NEW.anchorUuid = %s', NEW.anchorUuid);
SELECT * FROM hs_office_contact WHERE uuid = OLD.contactUuid INTO oldContact;
assert oldContact.uuid is not null, format('oldContact must not be null for OLD.contactUuid = %s', OLD.contactUuid);
SELECT * FROM hs_office_contact WHERE uuid = NEW.contactUuid INTO newContact;
assert newContact.uuid is not null, format('newContact must not be null for NEW.contactUuid = %s', NEW.contactUuid);
if NEW.contactUuid <> OLD.contactUuid then
call revokeRoleFromRole(hsOfficeRelationTENANT(OLD), hsOfficeContactADMIN(oldContact));
call grantRoleToRole(hsOfficeRelationTENANT(NEW), hsOfficeContactADMIN(newContact));
call revokeRoleFromRole(hsOfficeContactREFERRER(oldContact), hsOfficeRelationTENANT(OLD));
call grantRoleToRole(hsOfficeContactREFERRER(newContact), hsOfficeRelationTENANT(NEW));
if NEW.contactUuid is distinct from OLD.contactUuid then
delete from rbacgrants g where g.grantedbytriggerof = OLD.uuid;
call buildRbacSystemForHsOfficeRelation(NEW);
end if;
call leaveTriggerForObjectUuid(NEW.uuid);
end; $$;
/*

View File

@ -98,22 +98,21 @@ role:partnerRel.contact:OWNER -.-> role:partnerRel.contact:ADMIN
role:partnerRel.contact:ADMIN -.-> role:partnerRel.contact:REFERRER
role:global:ADMIN -.-> role:partnerRel:OWNER
role:partnerRel:OWNER -.-> role:partnerRel:ADMIN
role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:ADMIN
role:partnerRel:ADMIN -.-> role:partnerRel:AGENT
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT
role:partnerRel:AGENT -.-> role:partnerRel:TENANT
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:TENANT
role:partnerRel.contact:ADMIN -.-> role:partnerRel:TENANT
role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER
role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER
role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER
role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:OWNER
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT
%% granting permissions to roles
role:global:ADMIN ==> perm:partner:INSERT
role:partnerRel:ADMIN ==> perm:partner:DELETE
role:partnerRel:AGENT ==> perm:partner:UPDATE
role:partnerRel:OWNER ==> perm:partner:DELETE
role:partnerRel:ADMIN ==> perm:partner:UPDATE
role:partnerRel:TENANT ==> perm:partner:SELECT
role:partnerRel:ADMIN ==> perm:partnerDetails:DELETE
role:partnerRel:OWNER ==> perm:partnerDetails:DELETE
role:partnerRel:AGENT ==> perm:partnerDetails:UPDATE
role:partnerRel:AGENT ==> perm:partnerDetails:SELECT

View File

@ -42,10 +42,10 @@ begin
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);
call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationADMIN(newPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationOWNER(newPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationTENANT(newPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationAGENT(newPartnerRel));
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'DELETE'), hsOfficeRelationADMIN(newPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationADMIN(newPartnerRel));
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'DELETE'), hsOfficeRelationOWNER(newPartnerRel));
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'SELECT'), hsOfficeRelationAGENT(newPartnerRel));
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAGENT(newPartnerRel));
@ -110,17 +110,17 @@ begin
if NEW.partnerRelUuid <> OLD.partnerRelUuid then
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'DELETE'), hsOfficeRelationADMIN(oldPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationADMIN(newPartnerRel));
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'DELETE'), hsOfficeRelationOWNER(oldPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationOWNER(newPartnerRel));
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'UPDATE'), hsOfficeRelationAGENT(oldPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationAGENT(newPartnerRel));
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'UPDATE'), hsOfficeRelationADMIN(oldPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationADMIN(newPartnerRel));
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'SELECT'), hsOfficeRelationTENANT(oldPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationTENANT(newPartnerRel));
call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'DELETE'), hsOfficeRelationADMIN(oldPartnerRel));
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'DELETE'), hsOfficeRelationADMIN(newPartnerRel));
call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'DELETE'), hsOfficeRelationOWNER(oldPartnerRel));
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'DELETE'), hsOfficeRelationOWNER(newPartnerRel));
call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAGENT(oldPartnerRel));
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAGENT(newPartnerRel));

View File

@ -151,15 +151,14 @@ role:debitorRel.contact:OWNER -.-> role:debitorRel.contact:ADMIN
role:debitorRel.contact:ADMIN -.-> role:debitorRel.contact:REFERRER
role:global:ADMIN -.-> role:debitorRel:OWNER
role:debitorRel:OWNER -.-> role:debitorRel:ADMIN
role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel:ADMIN
role:debitorRel:ADMIN -.-> role:debitorRel:AGENT
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:AGENT
role:debitorRel:AGENT -.-> role:debitorRel:TENANT
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:TENANT
role:debitorRel.contact:ADMIN -.-> role:debitorRel:TENANT
role:debitorRel:TENANT -.-> role:debitorRel.anchorPerson:REFERRER
role:debitorRel:TENANT -.-> role:debitorRel.holderPerson:REFERRER
role:debitorRel:TENANT -.-> role:debitorRel.contact:REFERRER
role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel:OWNER
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:AGENT
role:global:ADMIN -.-> role:refundBankAccount:OWNER
role:refundBankAccount:OWNER -.-> role:refundBankAccount:ADMIN
role:refundBankAccount:ADMIN -.-> role:refundBankAccount:REFERRER
@ -176,15 +175,14 @@ role:partnerRel.contact:OWNER -.-> role:partnerRel.contact:ADMIN
role:partnerRel.contact:ADMIN -.-> role:partnerRel.contact:REFERRER
role:global:ADMIN -.-> role:partnerRel:OWNER
role:partnerRel:OWNER -.-> role:partnerRel:ADMIN
role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:ADMIN
role:partnerRel:ADMIN -.-> role:partnerRel:AGENT
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT
role:partnerRel:AGENT -.-> role:partnerRel:TENANT
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:TENANT
role:partnerRel.contact:ADMIN -.-> role:partnerRel:TENANT
role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER
role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER
role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER
role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:OWNER
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT
role:partnerRel:ADMIN ==> role:debitorRel:ADMIN
role:partnerRel:AGENT ==> role:debitorRel:AGENT
role:debitorRel:AGENT ==> role:partnerRel:TENANT

View File

@ -110,15 +110,14 @@ role:debitorRel.contact:OWNER -.-> role:debitorRel.contact:ADMIN
role:debitorRel.contact:ADMIN -.-> role:debitorRel.contact:REFERRER
role:global:ADMIN -.-> role:debitorRel:OWNER
role:debitorRel:OWNER -.-> role:debitorRel:ADMIN
role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel:ADMIN
role:debitorRel:ADMIN -.-> role:debitorRel:AGENT
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:AGENT
role:debitorRel:AGENT -.-> role:debitorRel:TENANT
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:TENANT
role:debitorRel.contact:ADMIN -.-> role:debitorRel:TENANT
role:debitorRel:TENANT -.-> role:debitorRel.anchorPerson:REFERRER
role:debitorRel:TENANT -.-> role:debitorRel.holderPerson:REFERRER
role:debitorRel:TENANT -.-> role:debitorRel.contact:REFERRER
role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel:OWNER
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:AGENT
role:global:ADMIN -.-> role:bankAccount:OWNER
role:bankAccount:OWNER -.-> role:bankAccount:ADMIN
role:bankAccount:ADMIN -.-> role:bankAccount:REFERRER

View File

@ -96,15 +96,14 @@ role:partnerRel.contact:OWNER -.-> role:partnerRel.contact:ADMIN
role:partnerRel.contact:ADMIN -.-> role:partnerRel.contact:REFERRER
role:global:ADMIN -.-> role:partnerRel:OWNER
role:partnerRel:OWNER -.-> role:partnerRel:ADMIN
role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:ADMIN
role:partnerRel:ADMIN -.-> role:partnerRel:AGENT
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT
role:partnerRel:AGENT -.-> role:partnerRel:TENANT
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:TENANT
role:partnerRel.contact:ADMIN -.-> role:partnerRel:TENANT
role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER
role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER
role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER
role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:OWNER
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT
role:membership:OWNER ==> role:membership:ADMIN
role:partnerRel:ADMIN ==> role:membership:ADMIN
role:membership:ADMIN ==> role:membership:AGENT

View File

@ -97,15 +97,14 @@ role:membership.partnerRel.contact:OWNER -.-> role:membership.partnerRel.contact
role:membership.partnerRel.contact:ADMIN -.-> role:membership.partnerRel.contact:REFERRER
role:global:ADMIN -.-> role:membership.partnerRel:OWNER
role:membership.partnerRel:OWNER -.-> role:membership.partnerRel:ADMIN
role:membership.partnerRel.anchorPerson:ADMIN -.-> role:membership.partnerRel:ADMIN
role:membership.partnerRel:ADMIN -.-> role:membership.partnerRel:AGENT
role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel:AGENT
role:membership.partnerRel:AGENT -.-> role:membership.partnerRel:TENANT
role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel:TENANT
role:membership.partnerRel.contact:ADMIN -.-> role:membership.partnerRel:TENANT
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.anchorPerson:REFERRER
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.holderPerson:REFERRER
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.contact:REFERRER
role:membership.partnerRel.anchorPerson:ADMIN -.-> role:membership.partnerRel:OWNER
role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel:AGENT
role:membership:OWNER -.-> role:membership:ADMIN
role:membership.partnerRel:ADMIN -.-> role:membership:ADMIN
role:membership:ADMIN -.-> role:membership:AGENT

View File

@ -97,15 +97,14 @@ role:membership.partnerRel.contact:OWNER -.-> role:membership.partnerRel.contact
role:membership.partnerRel.contact:ADMIN -.-> role:membership.partnerRel.contact:REFERRER
role:global:ADMIN -.-> role:membership.partnerRel:OWNER
role:membership.partnerRel:OWNER -.-> role:membership.partnerRel:ADMIN
role:membership.partnerRel.anchorPerson:ADMIN -.-> role:membership.partnerRel:ADMIN
role:membership.partnerRel:ADMIN -.-> role:membership.partnerRel:AGENT
role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel:AGENT
role:membership.partnerRel:AGENT -.-> role:membership.partnerRel:TENANT
role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel:TENANT
role:membership.partnerRel.contact:ADMIN -.-> role:membership.partnerRel:TENANT
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.anchorPerson:REFERRER
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.holderPerson:REFERRER
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.contact:REFERRER
role:membership.partnerRel.anchorPerson:ADMIN -.-> role:membership.partnerRel:OWNER
role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel:AGENT
role:membership:OWNER -.-> role:membership:ADMIN
role:membership.partnerRel:ADMIN -.-> role:membership:ADMIN
role:membership:ADMIN -.-> role:membership:AGENT