Compare commits

..

No commits in common. "e272b5b2aeacd87386c37228f4000233f7264917" and "370c00923cc27d71695544eed0f30f9bfb9e5404" have entirely different histories.

23 changed files with 64 additions and 162 deletions

View File

@ -95,7 +95,7 @@ public class RbacGrantController implements RbacGrantsApi {
return ResponseEntity.noContent().build();
}
// TODO: implement an endpoint to create a Mermaid flowchart with all grants of a given user
// @GetMapping(
// path = "/api/rbac/users/{userUuid}/grants",
// produces = {"text/vnd.mermaid"})

View File

@ -5,6 +5,7 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.UUID;
public interface RbacGrantRepository extends Repository<RbacGrantEntity, RbacGrantId> {

View File

@ -102,3 +102,4 @@ public class RbacUserController implements RbacUsersApi {
RbacUserPermissionResource.class));
}
}

View File

@ -471,13 +471,12 @@ $$;
create table RbacGrants
(
uuid uuid primary key default uuid_generate_v4(),
grantedByTriggerOf uuid references RbacObject (uuid) on delete cascade initially deferred ,
grantedByRoleUuid uuid references RbacRole (uuid),
ascendantUuid uuid references RbacReference (uuid),
descendantUuid uuid references RbacReference (uuid),
assumed boolean not null default true, -- auto assumed (true) vs. needs assumeRoles (false)
unique (ascendantUuid, descendantUuid),
constraint rbacGrant_createdBy check ( grantedByRoleUuid is null or grantedByTriggerOf is null) );
unique (ascendantUuid, descendantUuid)
);
create index on RbacGrants (ascendantUuid);
create index on RbacGrants (descendantUuid);
@ -581,8 +580,8 @@ begin
perform assertReferenceType('permissionId (descendant)', permissionIds[i], 'RbacPermission');
insert
into RbacGrants (grantedByTriggerOf, ascendantUuid, descendantUuid, assumed)
values (currentTriggerObjectUuid(), roleUuid, permissionIds[i], true)
into RbacGrants (ascendantUuid, descendantUuid, assumed)
values (roleUuid, permissionIds[i], true)
on conflict do nothing; -- allow granting multiple times
end loop;
end;
@ -599,8 +598,8 @@ begin
end if;
insert
into RbacGrants (grantedByTriggerOf, ascendantuuid, descendantUuid, assumed)
values (currentTriggerObjectUuid(), superRoleId, subRoleId, doAssume)
into RbacGrants (ascendantuuid, descendantUuid, assumed)
values (superRoleId, subRoleId, doAssume)
on conflict do nothing; -- allow granting multiple times
end; $$;
@ -622,8 +621,8 @@ begin
end if;
insert
into RbacGrants (grantedByTriggerOf, ascendantuuid, descendantUuid, assumed)
values (currentTriggerObjectUuid(), superRoleId, subRoleId, doAssume)
into RbacGrants (ascendantuuid, descendantUuid, assumed)
values (superRoleId, subRoleId, doAssume)
on conflict do nothing; -- allow granting multiple times
end; $$;
@ -645,8 +644,8 @@ begin
end if;
insert
into RbacGrants (grantedByTriggerOf, ascendantuuid, descendantUuid, assumed)
values (currentTriggerObjectUuid(), superRoleId, subRoleId, doAssume)
into RbacGrants (ascendantuuid, descendantUuid, assumed)
values (superRoleId, subRoleId, doAssume)
on conflict do nothing; -- allow granting multiple times
end; $$;

View File

@ -56,7 +56,6 @@ drop view if exists rbacgrants_ev;
create or replace view rbacgrants_ev as
-- @formatter:off
select x.grantUuid as uuid,
x.grantedByTriggerOf as grantedByTriggerOf,
go.objectTable || '#' || findIdNameByObjectUuid(go.objectTable, go.uuid) || '.' || r.roletype as grantedByRoleIdName,
x.ascendingIdName as ascendantIdName,
x.descendingIdName as descendantIdName,
@ -66,7 +65,6 @@ create or replace view rbacgrants_ev as
x.assumed
from (
select g.uuid as grantUuid,
g.grantedbytriggerof as grantedbytriggerof,
g.grantedbyroleuuid, g.ascendantuuid, g.descendantuuid, g.assumed,
coalesce(

View File

@ -1,61 +0,0 @@
--liquibase formatted sql
-- ============================================================================
--changeset rbac-trigger-context-ENTER:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
create or replace procedure enterTriggerForObjectUuid(currentObjectUuid uuid)
language plpgsql as $$
declare
existingObjectUuid text;
begin
existingObjectUuid = current_setting('hsadminng.currentObjectUuid', true);
if (existingObjectUuid > '' ) then
raise exception '[500] currentObjectUuid already defined, already in trigger of "%"', existingObjectUuid;
end if;
execute format('set local hsadminng.currentObjectUuid to %L', currentObjectUuid);
end; $$;
-- ============================================================================
--changeset rbac-trigger-context-CURRENT-ID:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Returns the uuid of the object uuid whose trigger is currently executed as set via `enterTriggerForObjectUuid(...)`.
*/
create or replace function currentTriggerObjectUuid()
returns uuid
stable -- leakproof
language plpgsql as $$
declare
currentObjectUuid uuid;
begin
begin
currentObjectUuid = current_setting('hsadminng.currentObjectUuid')::uuid;
return currentObjectUuid;
exception
when others then
return null::uuid;
end;
end; $$;
--//
-- ============================================================================
--changeset rbac-trigger-context-LEAVE:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
create or replace procedure leaveTriggerForObjectUuid(currentObjectUuid uuid)
language plpgsql as $$
declare
existingObjectUuid uuid;
begin
existingObjectUuid = current_setting('hsadminng.currentObjectUuid', true);
if ( existingObjectUuid <> currentObjectUuid ) then
raise exception '[500] currentObjectUuid does not match: "%"', existingObjectUuid;
end if;
execute format('reset hsadminng.currentObjectUuid');
end; $$;

View File

@ -34,8 +34,6 @@ begin
raise exception 'invalid usage of TRIGGER AFTER INSERT';
end if;
call enterTriggerForObjectUuid(NEW.uuid);
-- the owner role with full access for Hostsharing administrators
testCustomerOwnerUuid = createRoleWithGrants(
testCustomerOwner(NEW),
@ -61,7 +59,6 @@ begin
permissions => array['view']
);
call leaveTriggerForObjectUuid(NEW.uuid);
return NEW;
end; $$;

View File

@ -26,13 +26,13 @@ create or replace function createRbacRolesForTestPackage()
strict as $$
declare
parentCustomer test_customer;
packageOwnerRoleUuid uuid;
packageAdminRoleUuid uuid;
begin
if TG_OP <> 'INSERT' then
raise exception 'invalid usage of TRIGGER AFTER INSERT';
end if;
call enterTriggerForObjectUuid(NEW.uuid);
select * from test_customer as c where c.uuid = NEW.customerUuid into parentCustomer;
-- an owner role is created and assigned to the customer's admin role
@ -57,7 +57,6 @@ begin
outgoingSubRoles => array[testCustomerTenant(parentCustomer)]
);
call leaveTriggerForObjectUuid(NEW.uuid);
return NEW;
end; $$;

View File

@ -53,8 +53,6 @@ begin
raise exception 'invalid usage of TRIGGER AFTER INSERT';
end if;
call enterTriggerForObjectUuid(NEW.uuid);
select * from test_package where uuid = NEW.packageUuid into parentPackage;
-- an owner role is created and assigned to the package's admin group
@ -74,7 +72,6 @@ begin
-- a tenent role is only created on demand
call leaveTriggerForObjectUuid(NEW.uuid);
return NEW;
end; $$;

View File

@ -70,7 +70,6 @@ do language plpgsql $$
call createHsOfficePersonTestData('LP', 'Fourth eG');
call createHsOfficePersonTestData('UF', 'Erben Bessler', 'Mel', 'Bessler');
call createHsOfficePersonTestData('NP', null, 'Bessler', 'Anita');
call createHsOfficePersonTestData('NP', null, 'Bessler', 'Bert');
call createHsOfficePersonTestData('NP', null, 'Winkler', 'Paul');
end;
$$;

View File

@ -32,7 +32,6 @@ declare
oldContact hs_office_contact;
newContact hs_office_contact;
begin
call enterTriggerForObjectUuid(NEW.uuid);
select * from hs_office_person as p where p.uuid = NEW.relAnchorUuid into newAnchorPerson;
select * from hs_office_person as p where p.uuid = NEW.relHolderUuid into newHolderPerson;
@ -93,17 +92,16 @@ begin
select * from hs_office_contact as c where c.uuid = OLD.contactUuid into oldContact;
call revokeRoleFromRole( hsOfficeContactReferrer(oldContact), hsOfficeRelationshipTenant(NEW) );
call grantRoleToRole( hsOfficeContactReferrer(newContact), hsOfficeRelationshipTenant(NEW) );
call revokeRoleFromRole( hsOfficeRelationshipTenant(NEW), hsOfficeContactAdmin(oldContact) );
call grantRoleToRole( hsOfficeRelationshipTenant(NEW), hsOfficeContactAdmin(newContact) );
call revokeRoleFromRole( hsOfficeRelationshipAgent(NEW), hsOfficeContactAdmin(oldContact) );
call grantRoleToRole( hsOfficeRelationshipAgent(NEW), hsOfficeContactAdmin(newContact) );
call revokeRoleFromRole( hsOfficeContactAdmin(oldContact), hsOfficeRelationshipAgent(NEW) );
call grantRoleToRole( hsOfficeContactAdmin(newContact), hsOfficeRelationshipAgent(NEW) );
end if;
else
raise exception 'invalid usage of TRIGGER';
end if;
call leaveTriggerForObjectUuid(NEW.uuid);
return NEW;
end; $$;

View File

@ -24,8 +24,6 @@ declare
newPartnerRole hs_office_relationship;
begin
call enterTriggerForObjectUuid(NEW.uuid);
select * from hs_office_relationship as r where r.uuid = NEW.partnerroleuuid into newPartnerRole;
if TG_OP = 'INSERT' then
@ -120,7 +118,6 @@ begin
raise exception 'invalid usage of TRIGGER';
end if;
call leaveTriggerForObjectUuid(NEW.uuid);
return NEW;
end; $$;

View File

@ -30,7 +30,6 @@ declare
newHsOfficeDebitor hs_office_debitor;
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_bankAccount as c where c.uuid = NEW.bankAccountUuid into newHsOfficeBankAccount;
@ -76,7 +75,6 @@ begin
raise exception 'invalid usage of TRIGGER';
end if;
call leaveTriggerForObjectUuid(NEW.uuid);
return NEW;
end; $$;

View File

@ -37,7 +37,6 @@ declare
newBankAccount hs_office_bankaccount;
oldBankAccount hs_office_bankaccount;
begin
call enterTriggerForObjectUuid(NEW.uuid);
hsOfficeDebitorTenant := hsOfficeDebitorTenant(NEW);
@ -148,7 +147,6 @@ begin
raise exception 'invalid usage of TRIGGER';
end if;
call leaveTriggerForObjectUuid(NEW.uuid);
return NEW;
end; $$;

View File

@ -31,7 +31,6 @@ declare
newHsOfficePartnerRel hs_office_relationship;
newHsOfficeDebitor hs_office_debitor;
begin
call enterTriggerForObjectUuid(NEW.uuid);
select * from hs_office_partner as p where p.uuid = NEW.partnerUuid into newHsOfficePartner;
select * from hs_office_relationship as r where r.relType = 'PARTNER' and r.relHolderUuid = NEW.partnerUuid into newHsOfficePartnerRel;
@ -77,7 +76,6 @@ begin
raise exception 'invalid usage of TRIGGER';
end if;
call leaveTriggerForObjectUuid(NEW.uuid);
return NEW;
end; $$;

View File

@ -29,7 +29,6 @@ create or replace function hsOfficeCoopSharesTransactionRbacRolesTrigger()
declare
newHsOfficeMembership hs_office_membership;
begin
call enterTriggerForObjectUuid(NEW.uuid);
select * from hs_office_membership as p where p.uuid = NEW.membershipUuid into newHsOfficeMembership;
@ -50,7 +49,6 @@ begin
raise exception 'invalid usage of TRIGGER';
end if;
call leaveTriggerForObjectUuid(NEW.uuid);
return NEW;
end; $$;

View File

@ -29,7 +29,6 @@ create or replace function hsOfficeCoopAssetsTransactionRbacRolesTrigger()
declare
newHsOfficeMembership hs_office_membership;
begin
call enterTriggerForObjectUuid(NEW.uuid);
select * from hs_office_membership as p where p.uuid = NEW.membershipUuid into newHsOfficeMembership;
@ -50,7 +49,6 @@ begin
raise exception 'invalid usage of TRIGGER';
end if;
call leaveTriggerForObjectUuid(NEW.uuid);
return NEW;
end; $$;

View File

@ -25,8 +25,6 @@ databaseChangeLog:
file: db/changelog/054-rbac-context.sql
- include:
file: db/changelog/055-rbac-views.sql
- include:
file: db/changelog/056-rbac-trigger-context.sql
- include:
file: db/changelog/057-rbac-role-builder.sql
- include:

View File

@ -105,15 +105,18 @@ class HsOfficeContactRepositoryIntegrationTest extends ContextBasedTestWithClean
initialRoleNames,
"hs_office_contact#anothernewcontact.owner",
"hs_office_contact#anothernewcontact.admin",
"hs_office_contact#anothernewcontact.referrer"
"hs_office_contact#anothernewcontact.tenant",
"hs_office_contact#anothernewcontact.guest"
));
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.from(
initialGrantNames,
"{ grant role hs_office_contact#anothernewcontact.owner to role global#global.admin by system and assume }",
"{ grant perm edit on hs_office_contact#anothernewcontact to role hs_office_contact#anothernewcontact.admin by system and assume }",
"{ grant role hs_office_contact#anothernewcontact.tenant to role hs_office_contact#anothernewcontact.admin by system and assume }",
"{ grant perm * on hs_office_contact#anothernewcontact to role hs_office_contact#anothernewcontact.owner by system and assume }",
"{ grant role hs_office_contact#anothernewcontact.admin to role hs_office_contact#anothernewcontact.owner by system and assume }",
"{ grant perm view on hs_office_contact#anothernewcontact to role hs_office_contact#anothernewcontact.referrer by system and assume }",
"{ grant perm view on hs_office_contact#anothernewcontact to role hs_office_contact#anothernewcontact.guest by system and assume }",
"{ grant role hs_office_contact#anothernewcontact.guest to role hs_office_contact#anothernewcontact.tenant by system and assume }",
"{ grant role hs_office_contact#anothernewcontact.owner to user selfregistered-user-drew@hostsharing.org by global#global.admin and assume }"
));
}

View File

@ -600,7 +600,6 @@ public class ImportOfficeData extends ContextBasedTest {
Map<Integer, E> entities,
final String legacyIdTable,
final String legacyIdColumn) {
em.flush();
entities.forEach((id, entity) -> em.createNativeQuery("""
UPDATE ${legacyIdTable}
SET ${legacyIdColumn} = :legacyId
@ -880,13 +879,13 @@ public class ImportOfficeData extends ContextBasedTest {
partners.forEach( (id, partner) -> {
final var partnerPerson = partner.getPartnerRole().getRelHolder();
if (relationships.values().stream()
.filter(rel -> rel.getRelAnchor() == partnerPerson && rel.getRelType() == HsOfficeRelationshipType.REPRESENTATIVE)
.filter(rel -> rel.getRelHolder() == partnerPerson && rel.getRelType() == HsOfficeRelationshipType.REPRESENTATIVE)
.findFirst().isEmpty()) {
//addRelationship(partnerPerson, partnerPerson, partner.getPartnerRole().getContact(), HsOfficeRelationshipType.REPRESENTATIVE);
addRelationship(partnerPerson, partnerPerson, partner.getPartnerRole().getContact(), HsOfficeRelationshipType.REPRESENTATIVE);
contractualMissing.add(partner.getPartnerNumber());
}
});
//assertThat(contractualMissing).isEmpty(); // comment out if we do want to allow missing contractual contact
// assertThat(contractualMissing).isEmpty(); uncomment if we don't want allow missing contractual contact
}
private static boolean containsRole(final Record rec, final String role) {
final var roles = rec.getString("roles");

View File

@ -14,6 +14,7 @@ import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
import net.hostsharing.test.Array;
import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

View File

@ -106,20 +106,20 @@ class HsOfficePersonRepositoryIntegrationTest extends ContextBasedTestWithCleanu
initialRoleNames,
"hs_office_person#anothernewperson.owner",
"hs_office_person#anothernewperson.admin",
"hs_office_person#anothernewperson.referrer"
"hs_office_person#anothernewperson.tenant",
"hs_office_person#anothernewperson.guest"
));
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(
Array.from(
initialGrantNames,
"{ grant perm * on hs_office_person#anothernewperson to role hs_office_person#anothernewperson.owner by system and assume }",
"{ grant role hs_office_person#anothernewperson.owner to user selfregistered-user-drew@hostsharing.org by global#global.admin and assume }",
"{ grant role hs_office_person#anothernewperson.owner to role global#global.admin by system and assume }",
"{ grant perm edit on hs_office_person#anothernewperson to role hs_office_person#anothernewperson.admin by system and assume }",
"{ grant role hs_office_person#anothernewperson.tenant to role hs_office_person#anothernewperson.admin by system and assume }",
"{ grant perm * on hs_office_person#anothernewperson to role hs_office_person#anothernewperson.owner by system and assume }",
"{ grant role hs_office_person#anothernewperson.admin to role hs_office_person#anothernewperson.owner by system and assume }",
"{ grant perm view on hs_office_person#anothernewperson to role hs_office_person#anothernewperson.referrer by system and assume }",
"{ grant role hs_office_person#anothernewperson.referrer to role hs_office_person#anothernewperson.admin by system and assume }"
"{ grant perm view on hs_office_person#anothernewperson to role hs_office_person#anothernewperson.guest by system and assume }",
"{ grant role hs_office_person#anothernewperson.guest to role hs_office_person#anothernewperson.tenant by system and assume }",
"{ grant role hs_office_person#anothernewperson.owner to user selfregistered-user-drew@hostsharing.org by global#global.admin and assume }"
));
}

View File

@ -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;
@ -25,8 +26,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.NATURAL_PERSON;
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.UNINCORPORATED_FIRM;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.distinctRoleNamesOf;
import static net.hostsharing.test.JpaAttempt.attempt;
@ -68,14 +67,9 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith
// given
context("superuser-alex@hostsharing.net");
final var count = relationshipRepo.count();
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").stream()
.filter(p -> p.getPersonType() == UNINCORPORATED_FIRM)
.findFirst().orElseThrow();
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Paul").stream()
.filter(p -> p.getPersonType() == NATURAL_PERSON)
.findFirst().orElseThrow();
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").stream()
.findFirst().orElseThrow();
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").get(0);
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Anita").get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
// when
final var result = attempt(em, () -> {
@ -104,14 +98,9 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith
// when
attempt(em, () -> {
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").stream()
.filter(p -> p.getPersonType() == UNINCORPORATED_FIRM)
.findFirst().orElseThrow();
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Bert").stream()
.filter(p -> p.getPersonType() == NATURAL_PERSON)
.findFirst().orElseThrow();
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").stream()
.findFirst().orElseThrow();
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").get(0);
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Anita").get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
final var newRelationship = HsOfficeRelationshipEntity.builder()
.relAnchor(givenAnchorPerson)
.relHolder(givenHolderPerson)
@ -124,33 +113,26 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith
// then
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
initialRoleNames,
"hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.owner",
"hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.admin",
"hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.agent",
"hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant"));
"hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin",
"hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner",
"hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant"));
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted(
initialGrantNames,
"{ grant perm * on hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert to role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.owner by system and assume }",
"{ grant role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.owner to role global#global.admin by system and assume }",
"{ grant perm * on hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner to role global#global.admin by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner to role hs_office_person#BesslerAnita.admin by system and assume }",
"{ grant perm edit on hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert to role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.admin by system and assume }",
"{ grant role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.admin to role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.owner by system and assume }",
"{ grant role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.admin to role hs_office_person#ErbenBesslerMelBessler.admin by system and assume }",
"{ grant perm edit on hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner by system and assume }",
"{ grant role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.agent to role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.admin by system and assume }",
"{ grant role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.agent to role hs_office_contact#fourthcontact.admin by system and assume }",
"{ grant role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.agent to role hs_office_person#BesslerBert.admin by system and assume }",
"{ grant perm view on hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert to role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant by system and assume }",
"{ grant role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant to role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.agent by system and assume }",
"{ grant role hs_office_person#BesslerBert.referrer to role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant by system and assume }",
"{ grant role hs_office_person#ErbenBesslerMelBessler.referrer to role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant by system and assume }",
"{ grant role hs_office_contact#fourthcontact.referrer to role hs_office_relationship#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant by system and assume }",
// REPRESENTATIVE holder person -> (represented) anchor person
"{ grant role hs_office_person#BesslerBert.admin to role hs_office_person#ErbenBesslerMelBessler.admin by system and assume }",
"{ grant perm view on hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_contact#fourthcontact.admin by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_person#BesslerAnita.admin by system and assume }",
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin by system and assume }",
"{ grant role hs_office_contact#fourthcontact.tenant to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
"{ grant role hs_office_person#BesslerAnita.tenant to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
null)
);
}
@ -169,7 +151,7 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith
// given
context("superuser-alex@hostsharing.net");
final var person = personRepo.findPersonByOptionalNameLike("Smith").stream()
.filter(p -> p.getPersonType() == NATURAL_PERSON)
.filter(p -> p.getPersonType() == HsOfficePersonType.NATURAL_PERSON)
.findFirst().orElseThrow();
// when
@ -188,7 +170,7 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith
// given:
context("person-SmithPeter@example.com");
final var person = personRepo.findPersonByOptionalNameLike("Smith").stream()
.filter(p -> p.getPersonType() == NATURAL_PERSON)
.filter(p -> p.getPersonType() == HsOfficePersonType.NATURAL_PERSON)
.findFirst().orElseThrow();
// when:
@ -242,13 +224,13 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith
// given
context("superuser-alex@hostsharing.net");
final var givenRelationship = givenSomeTemporaryRelationshipBessler(
"Bert", "fifth contact");
"Anita", "fifth contact");
assertThatRelationshipIsVisibleForUserWithRole(
givenRelationship,
"hs_office_person#ErbenBesslerMelBessler.admin");
assertThatRelationshipActuallyInDatabase(givenRelationship);
context("superuser-alex@hostsharing.net");
final var givenContact = contactRepo.findContactByOptionalLabelLike("sixth contact").stream().findFirst().orElseThrow();
final var givenContact = contactRepo.findContactByOptionalLabelLike("sixth contact").get(0);
// when
final var result = jpaAttempt.transacted(() -> {
@ -401,6 +383,10 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith
final var initialGrantNames = Array.from(distinctGrantDisplaysOf(rawGrantRepo.findAll()));
final var givenRelationship = givenSomeTemporaryRelationshipBessler(
"Anita", "twelfth");
// assertThat(distinctRoleNamesOf(rawRoleRepo.findAll()).size()).as("unexpected number of roles created")
// .isEqualTo(initialRoleNames.length + 3);
// assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll()).size()).as("unexpected number of grants created")
// .isEqualTo(initialGrantNames.length + 13);
// when
final var result = jpaAttempt.transacted(() -> {