From 1dd63161ab2d1efbaac50db4feccd7bcfdddace6 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Thu, 15 Sep 2022 13:32:01 +0200 Subject: [PATCH] properly implement update for hs_office_partner_rv --- .../resources/db/changelog/050-rbac-base.sql | 49 +++++- .../208-hs-office-contact-test-data.sql | 8 + .../changelog/213-hs-office-person-rbac.sql | 4 +- .../changelog/223-hs-office-partner-rbac.sql | 161 ++++++++++++----- ...OfficePartnerControllerAcceptanceTest.java | 1 + ...fficePartnerRepositoryIntegrationTest.java | 166 +++++++++++++++--- 6 files changed, 318 insertions(+), 71 deletions(-) diff --git a/src/main/resources/db/changelog/050-rbac-base.sql b/src/main/resources/db/changelog/050-rbac-base.sql index 8196a40a..16a00197 100644 --- a/src/main/resources/db/changelog/050-rbac-base.sql +++ b/src/main/resources/db/changelog/050-rbac-base.sql @@ -614,17 +614,64 @@ begin on conflict do nothing; -- allow granting multiple times end; $$; + +create or replace procedure grantRoleToRole(subRole RbacRoleDescriptor, superRole RbacRoleDescriptor, doAssume bool = true) + language plpgsql as $$ +declare + superRoleId uuid; + subRoleId uuid; +begin + superRoleId := findRoleId(superRole); + subRoleId := findRoleId(subRole); + + perform assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole'); + perform assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole'); + + if isGranted(subRoleId, superRoleId) then + raise exception '[400] Cyclic role grant detected between % and %', subRoleId, superRoleId; + end if; + + insert + into RbacGrants (ascendantuuid, descendantUuid, assumed) + values (superRoleId, subRoleId, doAssume) + on conflict do nothing; -- allow granting multiple times + delete from RbacGrants where ascendantUuid = superRoleId and descendantUuid = subRoleId; + insert + into RbacGrants (ascendantuuid, descendantUuid, assumed) + values (superRoleId, subRoleId, doAssume); -- allow granting multiple times +end; $$; + create or replace procedure revokeRoleFromRole(subRoleId uuid, superRoleId uuid) language plpgsql as $$ begin perform assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole'); perform assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole'); - if (isGranted(subRoleId, superRoleId)) then + if (isGranted(superRoleId, subRoleId)) then delete from RbacGrants where ascendantUuid = superRoleId and descendantUuid = subRoleId; end if; end; $$; +create or replace procedure revokeRoleFromRole(subRole RbacRoleDescriptor, superRole RbacRoleDescriptor) + language plpgsql as $$ +declare + superRoleId uuid; + subRoleId uuid; +begin + superRoleId := findRoleId(superRole); + subRoleId := findRoleId(subRole); + + perform assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole'); + perform assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole'); + + if (isGranted(superRoleId, subRoleId)) then + delete from RbacGrants where ascendantUuid = superRoleId and descendantUuid = subRoleId; + else + raise exception 'cannot revoke role % (%) from % (% because it is not granted', + subRole, subRoleId, superRole, superRoleId; + end if; +end; $$; + -- ============================================================================ --changeset rbac-base-QUERY-ACCESSIBLE-OBJECT-UUIDS:1 endDelimiter:--// -- ---------------------------------------------------------------------------- diff --git a/src/main/resources/db/changelog/208-hs-office-contact-test-data.sql b/src/main/resources/db/changelog/208-hs-office-contact-test-data.sql index 4451ad94..2d843611 100644 --- a/src/main/resources/db/changelog/208-hs-office-contact-test-data.sql +++ b/src/main/resources/db/changelog/208-hs-office-contact-test-data.sql @@ -57,10 +57,18 @@ end; $$; do language plpgsql $$ begin + -- TODO: use better names call createHsOfficeContactTestData('first contact'); call createHsOfficeContactTestData('second contact'); call createHsOfficeContactTestData('third contact'); call createHsOfficeContactTestData('forth contact'); + call createHsOfficeContactTestData('fifth contact'); + call createHsOfficeContactTestData('sixth contact'); + call createHsOfficeContactTestData('eighth contact'); + call createHsOfficeContactTestData('ninth contact'); + call createHsOfficeContactTestData('tenth contact'); + call createHsOfficeContactTestData('eleventh contact'); + call createHsOfficeContactTestData('twelfth contact'); end; $$; --// 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 e2c1736a..ccf37673 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 @@ -114,11 +114,11 @@ grant all privileges on hs_office_person_iv to restricted; /* Returns the objectUuid for a given identifying name (in this case the prefix). */ -create or replace function hsOfficePersonUuidByIdName(idName varchar) +create or replace function hs_office_personUuidByIdName(idName varchar) returns uuid language sql strict as $$ -select uuid from hs_office_person_iv iv where iv.idName = hsOfficePersonUuidByIdName.idName; +select uuid from hs_office_person_iv iv where iv.idName = hs_office_personUuidByIdName.idName; $$; /* diff --git a/src/main/resources/db/changelog/223-hs-office-partner-rbac.sql b/src/main/resources/db/changelog/223-hs-office-partner-rbac.sql index 9f683d70..a71331db 100644 --- a/src/main/resources/db/changelog/223-hs-office-partner-rbac.sql +++ b/src/main/resources/db/changelog/223-hs-office-partner-rbac.sql @@ -11,7 +11,7 @@ call generateRelatedRbacObject('hs_office_partner'); --changeset hs-office-partner-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--// -- ---------------------------------------------------------------------------- -create or replace function HsOfficePartnerOwner(partner hs_office_partner) +create or replace function hsOfficePartnerOwner(partner hs_office_partner) returns RbacRoleDescriptor language plpgsql strict as $$ @@ -19,7 +19,7 @@ begin return roleDescriptor('hs_office_partner', partner.uuid, 'owner'); end; $$; -create or replace function HsOfficePartnerAdmin(partner hs_office_partner) +create or replace function hsOfficePartnerAdmin(partner hs_office_partner) returns RbacRoleDescriptor language plpgsql strict as $$ @@ -27,7 +27,7 @@ begin return roleDescriptor('hs_office_partner', partner.uuid, 'admin'); end; $$; -create or replace function HsOfficePartnerTenant(partner hs_office_partner) +create or replace function hsOfficePartnerTenant(partner hs_office_partner) returns RbacRoleDescriptor language plpgsql strict as $$ @@ -42,60 +42,97 @@ end; $$; -- ---------------------------------------------------------------------------- /* - Creates the roles and their assignments for a new partner for the AFTER INSERT TRIGGER. + Creates and updates the roles and their assignments for partner entities. */ -create or replace function createRbacRolesForHsOfficePartner() +create or replace function hsOfficePartnerRbacRolesTrigger() returns trigger language plpgsql strict as $$ declare - ownerRole uuid; - adminRole uuid; - person hs_office_person; - contact hs_office_contact; + hsOfficePartnerTenant RbacRoleDescriptor; + ownerRole uuid; + adminRole uuid; + oldPerson hs_office_person; + newPerson hs_office_person; + oldContact hs_office_contact; + newContact hs_office_contact; begin - if TG_OP <> 'INSERT' then - raise exception 'invalid usage of TRIGGER AFTER INSERT'; + + hsOfficePartnerTenant := hsOfficePartnerTenant(NEW); + + select * from hs_office_person as p where p.uuid = NEW.personUuid into newPerson; + select * from hs_office_contact as c where c.uuid = NEW.contactUuid into newContact; + + if TG_OP = 'INSERT' then + + -- the owner role with full access for the global admins + ownerRole = createRole( + hsOfficePartnerOwner(NEW), + grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['*']), + beneathRole(globalAdmin()) + ); + + -- the admin role with full access for the global admins + adminRole = createRole( + hsOfficePartnerAdmin(NEW), + grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['edit']), + beneathRole(ownerRole) + ); + + -- the tenant role for those related users who can view the data + perform createRole( + hsOfficePartnerTenant, + grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['view']), + beneathRoles(array[hsOfficePartnerAdmin(NEW), hsOfficePersonAdmin(newPerson), hsOfficeContactAdmin(newContact)]), + withSubRoles(array[hsOfficePersonTenant(newPerson), hsOfficeContactTenant(newContact)]) + ); + + elsif TG_OP = 'UPDATE' then + + if OLD.personUuid <> NEW.personUuid then + select * from hs_office_person as p where p.uuid = OLD.personUuid into oldPerson; + + call revokeRoleFromRole( hsOfficePartnerTenant, hsOfficePersonAdmin(oldPerson) ); + call grantRoleToRole( hsOfficePartnerTenant, hsOfficePersonAdmin(newPerson) ); + + call revokeRoleFromRole( hsOfficePersonTenant(oldPerson), hsOfficePartnerTenant ); + call grantRoleToRole( hsOfficePersonTenant(newPerson), hsOfficePartnerTenant ); + end if; + + if OLD.contactUuid <> NEW.contactUuid then + select * from hs_office_contact as c where c.uuid = OLD.contactUuid into oldContact; + + call revokeRoleFromRole( hsOfficePartnerTenant, hsOfficeContactAdmin(oldContact) ); + call grantRoleToRole( hsOfficePartnerTenant, hsOfficeContactAdmin(newContact) ); + + call revokeRoleFromRole( hsOfficeContactTenant(oldContact), hsOfficePartnerTenant ); + call grantRoleToRole( hsOfficeContactTenant(newContact), hsOfficePartnerTenant ); + end if; + else + raise exception 'invalid usage of TRIGGER'; end if; - select * from hs_office_person as p where p.uuid = NEW.personUuid into person; - select * from hs_office_contact as c where c.uuid = NEW.contactUuid into contact; - - -- the owner role with full access for the global admins - ownerRole = createRole( - HsOfficePartnerOwner(NEW), - grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['*']), - beneathRole(globalAdmin()) - ); - - -- the admin role with full access for the global admins - adminRole = createRole( - HsOfficePartnerAdmin(NEW), - grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['edit']), - beneathRole(ownerRole) - ); - - -- the tenant role for those related users who can view the data - perform createRole( - HsOfficePartnerTenant(NEW), - grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['view']), - beneathRoles(array[HsOfficePartnerAdmin(NEW), hsOfficePersonAdmin(person), hsOfficeContactAdmin(contact)]), - withSubRoles(array[hsOfficePersonTenant(person), hsOfficeContactTenant(contact)]) - ); - return NEW; end; $$; /* An AFTER INSERT TRIGGER which creates the role structure for a new customer. */ - create trigger createRbacRolesForHsOfficePartner_Trigger after insert on hs_office_partner for each row -execute procedure createRbacRolesForHsOfficePartner(); +execute procedure hsOfficePartnerRbacRolesTrigger(); + +/* + An AFTER UPDATE TRIGGER which updates the role structure of a customer. + */ +create trigger updateRbacRolesForHsOfficePartner_Trigger + after update + on hs_office_partner + for each row +execute procedure hsOfficePartnerRbacRolesTrigger(); --// @@ -189,6 +226,7 @@ create trigger insertHsOfficePartner_Trigger execute function insertHsOfficePartner(); --// + -- ============================================================================ --changeset hs-office-partner-rbac-INSTEAD-OF-DELETE-TRIGGER:1 endDelimiter:--// -- ---------------------------------------------------------------------------- @@ -202,12 +240,11 @@ create or replace function deleteHsOfficePartner() returns trigger language plpgsql as $$ begin - if hasGlobalRoleGranted(currentUserUuid()) or - old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('delete', 'hs_office_partner', currentSubjectsUuids())) then - delete from hs_office_partner c where c.uuid = old.uuid; + if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('delete', 'hs_office_partner', currentSubjectsUuids())) then + delete from hs_office_partner p where p.uuid = old.uuid; return old; end if; - raise exception '[403] User % not allowed to delete partner uuid %', currentUser(), old.uuid; + raise exception '[403] Subject % is not allowed to delete partner uuid %', currentSubjectsUuids(), old.uuid; end; $$; /* @@ -220,6 +257,46 @@ create trigger deleteHsOfficePartner_Trigger execute function deleteHsOfficePartner(); --/ + +-- ============================================================================ +--changeset hs-office-partner-rbac-INSTEAD-OF-UPDATE-TRIGGER:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- + +/** + Instead of update trigger function for hs_office_partner_rv. + + Checks if the current subject (user / assumed role) has the permission to update the row. + */ +create or replace function updateHsOfficePartner() + returns trigger + language plpgsql as $$ +begin + if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('edit', 'hs_office_partner', currentSubjectsUuids())) then + update hs_office_partner + set personUuid = new.personUuid, + contactUuid = new.contactUuid, + registrationOffice = new.registrationOffice, + registrationNumber = new.registrationNumber, + birthday = new.birthday, + birthName = new.birthName, + dateOfDeath = new.dateOfDeath + where uuid = old.uuid; + return old; + end if; + raise exception '[403] Subject % is not allowed to update partner uuid %', currentSubjectsUuids(), old.uuid; +end; $$; + +/* + Creates an instead of delete trigger for the hs_office_partner_rv view. + */ +create trigger updateHsOfficePartner_Trigger + instead of update + on hs_office_partner_rv + for each row +execute function updateHsOfficePartner(); +--/ + + -- ============================================================================ --changeset hs-office-partner-rbac-NEW-CONTACT:1 endDelimiter:--// -- ---------------------------------------------------------------------------- diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java index 31efb062..92177242 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java @@ -300,6 +300,7 @@ class HsOfficePartnerControllerAcceptanceTest { // @formatter:on // finally, the partner is actually updated + context.define("superuser-alex@hostsharing.net"); assertThat(partnerRepo.findByUuid(givenPartner.getUuid())).isPresent().get() .matches(person -> { assertThat(person.getPerson().getTradeName()).isEqualTo("Ostfriesische Kuhhandel OHG"); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java index 462ddc11..b1d42ef2 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java @@ -3,7 +3,6 @@ package net.hostsharing.hsadminng.hs.office.partner; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.ContextBasedTest; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository; -import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository; import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository; import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository; @@ -21,6 +20,7 @@ import org.springframework.test.annotation.DirtiesContext; import javax.persistence.EntityManager; import javax.servlet.http.HttpServletRequest; +import java.time.LocalDate; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -76,11 +76,11 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { // when final var result = attempt(em, () -> { - final var newPartner = HsOfficePartnerEntity.builder() + final var newPartner = toCleanup(HsOfficePartnerEntity.builder() .uuid(UUID.randomUUID()) .person(givenPerson) .contact(givenContact) - .build(); + .build()); return partnerRepo.save(newPartner); }); @@ -102,11 +102,11 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { attempt(em, () -> { final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0); - final var newPartner = HsOfficePartnerEntity.builder() + final var newPartner = toCleanup(HsOfficePartnerEntity.builder() .uuid(UUID.randomUUID()) .person(givenPerson) .contact(givenContact) - .build(); + .build()); return partnerRepo.save(newPartner); }); @@ -148,7 +148,11 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { final var result = partnerRepo.findPartnerByOptionalNameLike(null); // then - allThesePartnersAreReturned(result, "First Impressions GmbH", "Ostfriesische Kuhhandel OHG", "Rockshop e.K."); + allThesePartnersAreReturned( + result, + "partner(Ostfriesische Kuhhandel OHG, third contact)", + "partner(Rockshop e.K., second contact)", + "partner(First Impressions GmbH, first contact)"); } @Test @@ -160,7 +164,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { final var result = partnerRepo.findPartnerByOptionalNameLike(null); // then: - exactlyThesePartnersAreReturned(result, "First Impressions GmbH"); + exactlyThesePartnersAreReturned(result, "partner(First Impressions GmbH, first contact)"); } } @@ -173,10 +177,119 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { context("superuser-alex@hostsharing.net"); // when - final var result = partnerRepo.findPartnerByOptionalNameLike("Ostfriesische"); + final var result = partnerRepo.findPartnerByOptionalNameLike("third contact"); // then - exactlyThesePartnersAreReturned(result, "Ostfriesische Kuhhandel OHG"); + exactlyThesePartnersAreReturned(result, "partner(Ostfriesische Kuhhandel OHG, third contact)"); + } + } + + @Nested + class UpdatePartner { + + @Test + public void hostsharingAdmin_withoutAssumedRole_canUpdateArbitraryPartner() { + // given + context("superuser-alex@hostsharing.net"); + final var givenPartner = givenSomeTemporaryPartnerBessler("fifth contact"); + assertThatPartnerIsVisibleForUserWithRole( + givenPartner, + "hs_office_person#ErbenBesslerMelBessler.admin"); + assertThatPartnerActuallyInDatabase(givenPartner); + context("superuser-alex@hostsharing.net"); + final var givenNewPerson = personRepo.findPersonByOptionalNameLike("Ostfriesische Kuhhandel OHG").get(0); + final var givenNewContact = contactRepo.findContactByOptionalLabelLike("sixth contact").get(0); + + // when + final var result = jpaAttempt.transacted(() -> { + context("superuser-alex@hostsharing.net"); + givenPartner.setContact(givenNewContact); + givenPartner.setPerson(givenNewPerson); + givenPartner.setDateOfDeath(LocalDate.parse("2022-09-15")); + return toCleanup(partnerRepo.save(givenPartner)); + }); + + // then + result.assertSuccessful(); + assertThatPartnerIsVisibleForUserWithRole( + result.returnedValue(), + "global#global.admin"); + assertThatPartnerIsVisibleForUserWithRole( + result.returnedValue(), + "hs_office_person#OstfriesischeKuhhandelOHG.admin"); + assertThatPartnerIsNotVisibleForUserWithRole( + result.returnedValue(), + "hs_office_person#ErbenBesslerMelBessler.admin"); + + partnerRepo.deleteByUuid(givenPartner.getUuid()); + } + + @Test + public void personAdmin_canNotUpdateRelatedPartner() { + // given + context("superuser-alex@hostsharing.net"); + final var givenPartner = givenSomeTemporaryPartnerBessler("eighth"); + assertThatPartnerIsVisibleForUserWithRole( + givenPartner, + "hs_office_person#ErbenBesslerMelBessler.admin"); + assertThatPartnerActuallyInDatabase(givenPartner); + + // when + final var result = jpaAttempt.transacted(() -> { + context("superuser-alex@hostsharing.net", "hs_office_person#ErbenBesslerMelBessler.admin"); + givenPartner.setDateOfDeath(LocalDate.parse("2022-09-15")); + return partnerRepo.save(givenPartner); + }); + + // then + result.assertExceptionWithRootCauseMessage(JpaSystemException.class, + "[403] Subject ", " is not allowed to update partner uuid"); + } + + @Test + public void contactAdmin_canNotUpdateRelatedPartner() { + // given + context("superuser-alex@hostsharing.net"); + final var givenPartner = givenSomeTemporaryPartnerBessler("ninth"); + assertThatPartnerIsVisibleForUserWithRole( + givenPartner, + "hs_office_contact#ninthcontact.admin"); + assertThatPartnerActuallyInDatabase(givenPartner); + + // when + final var result = jpaAttempt.transacted(() -> { + context("superuser-alex@hostsharing.net", "hs_office_contact#ninthcontact.admin"); + givenPartner.setDateOfDeath(LocalDate.parse("2022-09-15")); + return partnerRepo.save(givenPartner); + }); + + // then + result.assertExceptionWithRootCauseMessage(JpaSystemException.class, + "[403] Subject ", " is not allowed to update partner uuid"); + } + + private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) { + final var found = partnerRepo.findByUuid(saved.getUuid()); + assertThat(found).isNotEmpty().get().isNotSameAs(saved).usingRecursiveComparison().isEqualTo(saved); + } + + private void assertThatPartnerIsVisibleForUserWithRole( + final HsOfficePartnerEntity entity, + final String assumedRoles) { + jpaAttempt.transacted(() -> { + context("superuser-alex@hostsharing.net", assumedRoles); + assertThatPartnerActuallyInDatabase(entity); + }).assertSuccessful(); + } + + private void assertThatPartnerIsNotVisibleForUserWithRole( + final HsOfficePartnerEntity entity, + final String assumedRoles) { + jpaAttempt.transacted(() -> { + context("superuser-alex@hostsharing.net", assumedRoles); + final var found = partnerRepo.findByUuid(entity.getUuid()); + assertThat(found).isEmpty(); + }).assertSuccessful(); } } @@ -187,7 +300,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { public void globalAdmin_withoutAssumedRole_canDeleteAnyPartner() { // given context("superuser-alex@hostsharing.net", null); - final var givenPartner = givenSomeTemporaryPartnerBessler(); + final var givenPartner = givenSomeTemporaryPartnerBessler("tenth"); // when final var result = jpaAttempt.transacted(() -> { @@ -207,7 +320,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { public void nonGlobalAdmin_canNotDeleteTheirRelatedPartner() { // given context("superuser-alex@hostsharing.net", null); - final var givenPartner = toCleanup(givenSomeTemporaryPartnerBessler()); + final var givenPartner = givenSomeTemporaryPartnerBessler("eleventh"); // when final var result = jpaAttempt.transacted(() -> { @@ -220,7 +333,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { // then result.assertExceptionWithRootCauseMessage( JpaSystemException.class, - "[403] User person-ErbenBesslerMelBessler@example.com not allowed to delete partner"); + "[403] Subject ", " not allowed to delete partner"); assertThat(jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net"); return partnerRepo.findByUuid(givenPartner.getUuid()); @@ -233,7 +346,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { context("superuser-alex@hostsharing.net"); final var initialRoleNames = Array.from(roleNamesOf(rawRoleRepo.findAll())); final var initialGrantNames = Array.from(grantDisplaysOf(rawGrantRepo.findAll())); - final var givenPartner = givenSomeTemporaryPartnerBessler(); + final var givenPartner = givenSomeTemporaryPartnerBessler("twelfth"); assumeThat(rawRoleRepo.findAll().size()).as("unexpected number of roles created") .isEqualTo(initialRoleNames.length + 3); assumeThat(rawGrantRepo.findAll().size()).as("unexpected number of grants created") @@ -253,17 +366,19 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { } } - private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler() { + private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler(final String contact) { return jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net"); final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); - final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0); + final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0); final var newPartner = HsOfficePartnerEntity.builder() .uuid(UUID.randomUUID()) .person(givenPerson) .contact(givenContact) .build(); + toCleanup(newPartner); + return partnerRepo.save(newPartner); }).assertSuccessful().returnedValue(); } @@ -278,23 +393,22 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { context("superuser-alex@hostsharing.net", null); tempPartners.forEach(tempPartner -> { System.out.println("DELETING temporary partner: " + tempPartner.getDisplayName()); - final var count = partnerRepo.deleteByUuid(tempPartner.getUuid()); - assertThat(count).isGreaterThan(0); + if ( tempPartner.getContact().getLabel().equals("sixth contact")) { + toString(); + } + partnerRepo.deleteByUuid(tempPartner.getUuid()); }); } - void exactlyThesePartnersAreReturned(final List actualResult, final String... partnerTradeNames) { + void exactlyThesePartnersAreReturned(final List actualResult, final String... partnerNames) { assertThat(actualResult) - .hasSize(partnerTradeNames.length) - .extracting(HsOfficePartnerEntity::getPerson) - .extracting(HsOfficePersonEntity::getTradeName) - .containsExactlyInAnyOrder(partnerTradeNames); + .extracting(HsOfficePartnerEntity::getDisplayName) + .containsExactlyInAnyOrder(partnerNames); } - void allThesePartnersAreReturned(final List actualResult, final String... partnerTradeNames) { + void allThesePartnersAreReturned(final List actualResult, final String... partnerNames) { assertThat(actualResult) - .extracting(HsOfficePartnerEntity::getPerson) - .extracting(HsOfficePersonEntity::getTradeName) - .contains(partnerTradeNames); + .extracting(HsOfficePartnerEntity::getDisplayName) + .contains(partnerNames); } }