From 443b9b4b8a8ef3d0b553bfde8a6d10148bfe9c75 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Thu, 8 Feb 2024 17:36:49 +0100 Subject: [PATCH] fix relationship-related grants (WIP) --- .../hsadminng/rbac/rbacrole/RbacRoleType.java | 2 +- .../api-definition/rbac/rbac-role-schemas.yaml | 1 + .../resources/db/changelog/050-rbac-base.sql | 2 +- .../db/changelog/051-rbac-user-grant.sql | 4 +++- .../resources/db/changelog/054-rbac-context.sql | 1 + .../db/changelog/203-hs-office-contact-rbac.sql | 9 ++------- .../db/changelog/213-hs-office-person-rbac.sql | 9 ++------- .../changelog/218-hs-office-person-test-data.sql | 2 +- .../223-hs-office-relationship-rbac.sql | 10 +++++----- .../db/changelog/273-hs-office-debitor-rbac.sql | 6 +++--- .../hs/office/migration/ImportOfficeData.java | 1 + ...iceRelationshipRepositoryIntegrationTest.java | 16 +++++++++++----- 12 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleType.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleType.java index 153344fa..fa5b16aa 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleType.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleType.java @@ -1,5 +1,5 @@ package net.hostsharing.hsadminng.rbac.rbacrole; public enum RbacRoleType { - owner, admin, agent, tenant, guest + owner, admin, agent, tenant, guest, referrer } diff --git a/src/main/resources/api-definition/rbac/rbac-role-schemas.yaml b/src/main/resources/api-definition/rbac/rbac-role-schemas.yaml index 589c00b8..ff0e18e4 100644 --- a/src/main/resources/api-definition/rbac/rbac-role-schemas.yaml +++ b/src/main/resources/api-definition/rbac/rbac-role-schemas.yaml @@ -22,5 +22,6 @@ components: - owner - admin - tenant + - referrer roleName: type: string diff --git a/src/main/resources/db/changelog/050-rbac-base.sql b/src/main/resources/db/changelog/050-rbac-base.sql index 80a74a20..95fa2ea6 100644 --- a/src/main/resources/db/changelog/050-rbac-base.sql +++ b/src/main/resources/db/changelog/050-rbac-base.sql @@ -187,7 +187,7 @@ end; $$; */ -create type RbacRoleType as enum ('owner', 'admin', 'agent', 'tenant', 'guest'); +create type RbacRoleType as enum ('owner', 'admin', 'agent', 'tenant', 'guest', 'referrer'); create table RbacRole ( diff --git a/src/main/resources/db/changelog/051-rbac-user-grant.sql b/src/main/resources/db/changelog/051-rbac-user-grant.sql index 23dcbdd4..bce83b2e 100644 --- a/src/main/resources/db/changelog/051-rbac-user-grant.sql +++ b/src/main/resources/db/changelog/051-rbac-user-grant.sql @@ -27,10 +27,12 @@ begin perform assertReferenceType('roleId (descendant)', roleUuid, 'RbacRole'); perform assertReferenceType('userId (ascendant)', userUuid, 'RbacUser'); + raise notice 'role % grants role % to user %, assumed=%', grantedByRoleUuid, roleUuid, userUuid, doAssume; + insert into RbacGrants (grantedByRoleUuid, ascendantUuid, descendantUuid, assumed) values (grantedByRoleUuid, userUuid, roleUuid, doAssume); - -- TODO.spec: What should happen on mupltiple grants? What if options (doAssume) are not the same? + -- TODO.spec: What should happen on multiple grants? What if options (doAssume) are not the same? -- Most powerful or latest grant wins? What about managed? -- on conflict do nothing; -- allow granting multiple times end; $$; diff --git a/src/main/resources/db/changelog/054-rbac-context.sql b/src/main/resources/db/changelog/054-rbac-context.sql index ede86057..6b26bb50 100644 --- a/src/main/resources/db/changelog/054-rbac-context.sql +++ b/src/main/resources/db/changelog/054-rbac-context.sql @@ -136,6 +136,7 @@ begin raise exception '[401] currentUserUuid cannot be determined, please call `defineContext(...)` first;"'; end if; end if; + raise notice 'currentUserUuid %', currentUserUuid; return currentUserUuid::uuid; end; $$; --// diff --git a/src/main/resources/db/changelog/203-hs-office-contact-rbac.sql b/src/main/resources/db/changelog/203-hs-office-contact-rbac.sql index 7ba7891b..9165c985 100644 --- a/src/main/resources/db/changelog/203-hs-office-contact-rbac.sql +++ b/src/main/resources/db/changelog/203-hs-office-contact-rbac.sql @@ -46,14 +46,9 @@ begin ); perform createRoleWithGrants( - hsOfficeContactTenant(NEW), - incomingSuperRoles => array[hsOfficeContactAdmin(NEW)] - ); - - perform createRoleWithGrants( - hsOfficeContactGuest(NEW), + hsOfficeContactReferrer(NEW), permissions => array['view'], - incomingSuperRoles => array[hsOfficeContactTenant(NEW)] + incomingSuperRoles => array[hsOfficeContactAdmin(NEW)] ); return NEW; diff --git a/src/main/resources/db/changelog/213-hs-office-person-rbac.sql b/src/main/resources/db/changelog/213-hs-office-person-rbac.sql index 42eacf2f..f064a145 100644 --- a/src/main/resources/db/changelog/213-hs-office-person-rbac.sql +++ b/src/main/resources/db/changelog/213-hs-office-person-rbac.sql @@ -45,14 +45,9 @@ begin ); perform createRoleWithGrants( - hsOfficePersonTenant(NEW), - incomingSuperRoles => array[hsOfficePersonAdmin(NEW)] - ); - - perform createRoleWithGrants( - hsOfficePersonGuest(NEW), + hsOfficePersonReferrer(NEW), permissions => array['view'], - incomingSuperRoles => array[hsOfficePersonTenant(NEW)] + incomingSuperRoles => array[hsOfficePersonAdmin(NEW)] ); return NEW; diff --git a/src/main/resources/db/changelog/218-hs-office-person-test-data.sql b/src/main/resources/db/changelog/218-hs-office-person-test-data.sql index bc5e32b6..d8d8ed60 100644 --- a/src/main/resources/db/changelog/218-hs-office-person-test-data.sql +++ b/src/main/resources/db/changelog/218-hs-office-person-test-data.sql @@ -28,7 +28,7 @@ begin call defineContext(currentTask, null, emailAddr); execute format('set local hsadminng.currentTask to %L', currentTask); - raise notice 'creating test person: %', fullName; + raise notice 'creating test person: % by %', fullName, emailAddr; insert into hs_office_person (persontype, tradename, givenname, familyname) values (newPersonType, newTradeName, newGivenName, newFamilyName); diff --git a/src/main/resources/db/changelog/223-hs-office-relationship-rbac.sql b/src/main/resources/db/changelog/223-hs-office-relationship-rbac.sql index ddf0080b..1af38798 100644 --- a/src/main/resources/db/changelog/223-hs-office-relationship-rbac.sql +++ b/src/main/resources/db/changelog/223-hs-office-relationship-rbac.sql @@ -74,9 +74,9 @@ begin hsOfficeRelationshipAdmin(NEW) ], outgoingSubRoles => array[ --- hsOfficePersonAdmin(newAnchorPerson), --- hsOfficePersonAdmin(newHolderPerson), - hsOfficeContactAdmin(newContact) + hsOfficePersonReferrer(newAnchorPerson), + hsOfficePersonReferrer(newHolderPerson), + hsOfficeContactReferrer(newContact) ] ); @@ -91,8 +91,8 @@ begin call revokeRoleFromRole( hsOfficeRelationshipTenant(NEW), hsOfficeContactAdmin(oldContact) ); call grantRoleToRole( hsOfficeRelationshipTenant(NEW), hsOfficeContactAdmin(newContact) ); - call revokeRoleFromRole( hsOfficeContactTenant(oldContact), hsOfficeRelationshipAgent(NEW) ); - call grantRoleToRole( hsOfficeContactTenant(newContact), hsOfficeRelationshipAgent(NEW) ); + call revokeRoleFromRole( hsOfficeContactAdmin(oldContact), hsOfficeRelationshipAgent(NEW) ); + call grantRoleToRole( hsOfficeContactAdmin(newContact), hsOfficeRelationshipAgent(NEW) ); end if; else raise exception 'invalid usage of TRIGGER'; diff --git a/src/main/resources/db/changelog/273-hs-office-debitor-rbac.sql b/src/main/resources/db/changelog/273-hs-office-debitor-rbac.sql index 5acf78a3..3bc145d6 100644 --- a/src/main/resources/db/changelog/273-hs-office-debitor-rbac.sql +++ b/src/main/resources/db/changelog/273-hs-office-debitor-rbac.sql @@ -79,7 +79,7 @@ begin hsOfficeBankAccountAdmin(newBankaccount)], outgoingSubRoles => array[ hsOfficeRelationshipTenant(newPartnerRel), - hsOfficeContactGuest(newContact), + hsOfficeContactReferrer(newContact), hsOfficeBankAccountGuest(newBankaccount)] ); @@ -112,8 +112,8 @@ begin call revokeRoleFromRole(hsOfficeDebitorAgent(OLD), hsOfficeContactAdmin(oldContact)); call grantRoleToRole(hsOfficeDebitorAgent(NEW), hsOfficeContactAdmin(newContact)); - call revokeRoleFromRole(hsOfficeContactGuest(oldContact), hsOfficeDebitorTenant(OLD)); - call grantRoleToRole(hsOfficeContactGuest(newContact), hsOfficeDebitorTenant(NEW)); + call revokeRoleFromRole(hsOfficeContactReferrer(oldContact), hsOfficeDebitorTenant(OLD)); + call grantRoleToRole(hsOfficeContactReferrer(newContact), hsOfficeDebitorTenant(NEW)); end if; if (OLD.refundBankAccountUuid is not null or NEW.refundBankAccountUuid is not null) and diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/migration/ImportOfficeData.java b/src/test/java/net/hostsharing/hsadminng/hs/office/migration/ImportOfficeData.java index e22b4e6f..79e63b10 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/migration/ImportOfficeData.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/migration/ImportOfficeData.java @@ -456,6 +456,7 @@ public class ImportOfficeData extends ContextBasedTest { } @Test + @Disabled @Order(3000) @Commit void persistEntities() { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipRepositoryIntegrationTest.java index 8b732d66..aea62a9b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/relationship/HsOfficeRelationshipRepositoryIntegrationTest.java @@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.relationship; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository; +import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType; import net.hostsharing.hsadminng.hs.office.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository; import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository; @@ -146,7 +147,9 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith public void globalAdmin_withoutAssumedRole_canViewAllRelationshipsOfArbitraryPerson() { // given context("superuser-alex@hostsharing.net"); - final var person = personRepo.findPersonByOptionalNameLike("Second e.K.").stream().findFirst().orElseThrow(); + final var person = personRepo.findPersonByOptionalNameLike("Smith").stream() + .filter(p -> p.getPersonType() == HsOfficePersonType.NATURAL_PERSON) + .findFirst().orElseThrow(); // when final var result = relationshipRepo.findRelationshipRelatedToPersonUuid(person.getUuid()); @@ -154,15 +157,18 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith // then allTheseRelationshipsAreReturned( result, - "rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='LP Second e.K.', contact='second contact')", - "rel(relAnchor='LP Second e.K.', relType='REPRESENTATIVE', relHolder='NP Smith, Peter', contact='second contact')"); + "rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='NP Smith, Peter', contact='sixth contact')", + "rel(relAnchor='LP Second e.K.', relType='REPRESENTATIVE', relHolder='NP Smith, Peter', contact='second contact')", + "rel(relAnchor='IF Third OHG', relType='SUBSCRIBER', relMark='members-announce', relHolder='NP Smith, Peter', contact='third contact')"); } @Test public void normalUser_canViewRelationshipsOfOwnedPersons() { // given: - context("person-FirstGmbH@example.com"); - final var person = personRepo.findPersonByOptionalNameLike("First").stream().findFirst().orElseThrow(); + context("person-SmithPeter@example.com"); + final var person = personRepo.findPersonByOptionalNameLike("Smith").stream() + .filter(p -> p.getPersonType() == HsOfficePersonType.NATURAL_PERSON) + .findFirst().orElseThrow(); // when: final var result = relationshipRepo.findRelationshipRelatedToPersonUuid(person.getUuid());