assume with table#uuid:roletype

This commit is contained in:
Michael Hoennig 2024-12-28 16:07:02 +01:00
parent 1f14c370f7
commit 44951f439a
23 changed files with 179 additions and 150 deletions

View File

@ -58,7 +58,7 @@ public class Context {
cast(:currentTask as varchar(127)), cast(:currentTask as varchar(127)),
cast(:currentRequest as text), cast(:currentRequest as text),
cast(:currentSubject as varchar(63)), cast(:currentSubject as varchar(63)),
cast(:assumedRoles as varchar(1023))); cast(:assumedRoles as text));
"""); """);
query.setParameter("currentTask", shortenToMaxLength(currentTask, 127)); query.setParameter("currentTask", shortenToMaxLength(currentTask, 127));
query.setParameter("currentRequest", currentRequest); query.setParameter("currentRequest", currentRequest);

View File

@ -42,7 +42,7 @@ public interface HsOfficeRelationRbacRepository extends Repository<HsOfficeRelat
toSqlLikeOperand(mark), toSqlLikeOperand(personData), toSqlLikeOperand(contactData)); toSqlLikeOperand(mark), toSqlLikeOperand(personData), toSqlLikeOperand(contactData));
} }
// TODO: use ELIKE instead of lower(...) LIKE ...? Or use jsonb_path with RegEx like emailAddressRegEx in ContactRepo? // TODO: Or use jsonb_path with RegEx like emailAddressRegEx in ContactRepo?
@Query(value = """ @Query(value = """
SELECT rel FROM HsOfficeRelationRbacEntity AS rel SELECT rel FROM HsOfficeRelationRbacEntity AS rel
WHERE (:relationType IS NULL OR CAST(rel.type AS String) = :relationType) WHERE (:relationType IS NULL OR CAST(rel.type AS String) = :relationType)

View File

@ -14,24 +14,58 @@ public interface HsOfficeRelationRealRepository extends Repository<HsOfficeRelat
@Timed("app.repo.relations.findByUuid.real") @Timed("app.repo.relations.findByUuid.real")
Optional<HsOfficeRelationRealEntity> findByUuid(UUID id); Optional<HsOfficeRelationRealEntity> findByUuid(UUID id);
default List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuidAndRelationType(@NotNull UUID personUuid, HsOfficeRelationType relationType) {
return findRelationRelatedToPersonUuidAndRelationTypeString(personUuid, relationType == null ? null : relationType.toString());
}
@Query(value = """ @Query(value = """
SELECT p.* FROM hs_office.relation AS p SELECT p.* FROM hs_office.relation AS p
WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid
""", nativeQuery = true) """, nativeQuery = true)
@Timed("app.repo.relations.findRelationRelatedToPersonUuid.real") @Timed("app.repo.relations.findRelationRelatedToPersonUuid.real")
List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid); List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
/**
* Finds relations by a conjunction of optional criteria, including anchorPerson, holderPerson and contact data.
* *
* @param personUuid the optional UUID of the anchorPerson or holderPerson
* @param relationType the type of the relation
* @param mark the mark (use '%' for wildcard), case ignored
* @param personData a string to match the persons tradeName, familyName or givenName (use '%' for wildcard), case ignored
* @param contactData a string to match the contacts caption, postalAddress, emailAddresses or phoneNumbers (use '%' for wildcard), case ignored
* @return a list of (accessible) relations which match all given criteria
*/
default List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(
final UUID personUuid,
final HsOfficeRelationType relationType,
final String mark,
final String personData,
final String contactData) {
return findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl(
personUuid, toStringOrNull(relationType),
toSqlLikeOperand(mark), toSqlLikeOperand(personData), toSqlLikeOperand(contactData));
}
// TODO: Or use jsonb_path with RegEx like emailAddressRegEx in ContactRepo?
@Query(value = """ @Query(value = """
SELECT p.* FROM hs_office.relation AS p SELECT rel FROM HsOfficeRelationRealEntity AS rel
WHERE (:relationType IS NULL OR p.type = cast(:relationType AS hs_office.RelationType)) WHERE (:relationType IS NULL OR CAST(rel.type AS String) = :relationType)
AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid) AND ( :personUuid IS NULL
""", nativeQuery = true) OR rel.anchor.uuid = :personUuid OR rel.holder.uuid = :personUuid )
@Timed("app.repo.relations.findRelationRelatedToPersonUuidAndRelationTypeString.real") AND ( :mark IS NULL OR lower(rel.mark) LIKE :mark )
List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuidAndRelationTypeString(@NotNull UUID personUuid, String relationType); AND ( :personData IS NULL
OR lower(rel.anchor.tradeName) LIKE :personData OR lower(rel.holder.tradeName) LIKE :personData
OR lower(rel.anchor.familyName) LIKE :personData OR lower(rel.holder.familyName) LIKE :personData
OR lower(rel.anchor.givenName) LIKE :personData OR lower(rel.holder.givenName) LIKE :personData )
AND ( :contactData IS NULL
OR lower(rel.contact.caption) LIKE :contactData
OR lower(CAST(rel.contact.postalAddress AS String)) LIKE :contactData
OR lower(CAST(rel.contact.emailAddresses AS String)) LIKE :contactData
OR lower(CAST(rel.contact.phoneNumbers AS String)) LIKE :contactData )
""")
@Timed("app.office.relations.repo.findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl.real")
List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl(
final UUID personUuid,
final String relationType,
final String mark,
final String personData,
final String contactData);
@Timed("app.repo.relations.save.real") @Timed("app.repo.relations.save.real")
HsOfficeRelationRealEntity save(final HsOfficeRelationRealEntity entity); HsOfficeRelationRealEntity save(final HsOfficeRelationRealEntity entity);
@ -41,4 +75,11 @@ public interface HsOfficeRelationRealRepository extends Repository<HsOfficeRelat
@Timed("app.repo.relations.deleteByUuid.real") @Timed("app.repo.relations.deleteByUuid.real")
int deleteByUuid(UUID uuid); int deleteByUuid(UUID uuid);
private static String toSqlLikeOperand(final String text) {
return text == null ? null : ("%" + text.toLowerCase() + "%");
}
private static String toStringOrNull(final HsOfficeRelationType relationType) {
return relationType == null ? null : relationType.name();
}
} }

View File

@ -13,7 +13,7 @@ create procedure base.contextDefined(
currentTask varchar(127), currentTask varchar(127),
currentRequest text, currentRequest text,
currentSubject varchar(63), currentSubject varchar(63),
assumedRoles varchar(1023) assumedRoles varchar(4096)
) )
language plpgsql as $$ language plpgsql as $$
begin begin
@ -26,7 +26,7 @@ create or replace procedure base.defineContext(
currentTask varchar(127), currentTask varchar(127),
currentRequest text = null, currentRequest text = null,
currentSubject varchar(63) = null, currentSubject varchar(63) = null,
assumedRoles varchar(1023) = null assumedRoles text = null
) )
language plpgsql as $$ language plpgsql as $$
begin begin
@ -43,7 +43,7 @@ begin
execute format('set local hsadminng.currentSubject to %L', currentSubject); execute format('set local hsadminng.currentSubject to %L', currentSubject);
assumedRoles := coalesce(assumedRoles, ''); assumedRoles := coalesce(assumedRoles, '');
assert length(assumedRoles) <= 1023, FORMAT('assumedRoles must not be longer than 1023 characters: "%s"', assumedRoles); assert length(assumedRoles) <= 4096, FORMAT('assumedRoles must not be longer than 4096 characters: "%s"', assumedRoles);
execute format('set local hsadminng.assumedRoles to %L', assumedRoles); execute format('set local hsadminng.assumedRoles to %L', assumedRoles);
call base.contextDefined(currentTask, currentRequest, currentSubject, assumedRoles); call base.contextDefined(currentTask, currentRequest, currentSubject, assumedRoles);

View File

@ -23,7 +23,7 @@ begin
return currentSubjectUuid; return currentSubjectUuid;
end; $$; end; $$;
create or replace function rbac.determinecurrentsubjectorassumedrolesuuids(currentSubjectOrAssumedRolesUuids uuid, assumedRoles varchar) create or replace function rbac.determinecurrentsubjectorassumedrolesuuids(currentSubjectOrAssumedRolesUuids uuid, assumedRoles text)
returns uuid[] returns uuid[]
stable -- leakproof stable -- leakproof
language plpgsql as $$ language plpgsql as $$
@ -31,7 +31,7 @@ declare
roleName text; roleName text;
roleNameParts text; roleNameParts text;
objectTableToAssume varchar(63); objectTableToAssume varchar(63);
objectNameToAssume varchar(1024); -- FIXME: find sensible limit objectNameToAssume varchar(1024); -- e.g. for relation: 2*(96+48+48)+length('-with-REPRESENTATIVE-') = 405
objectUuidToAssume uuid; objectUuidToAssume uuid;
roleTypeToAssume rbac.RoleType; roleTypeToAssume rbac.RoleType;
roleIdsToAssume uuid[]; roleIdsToAssume uuid[];
@ -55,7 +55,12 @@ begin
objectNameToAssume = split_part(roleNameParts, '#', 2); objectNameToAssume = split_part(roleNameParts, '#', 2);
roleTypeToAssume = split_part(roleNameParts, '#', 3); roleTypeToAssume = split_part(roleNameParts, '#', 3);
objectUuidToAssume = rbac.findObjectUuidByIdName(objectTableToAssume, objectNameToAssume); begin
objectUuidToAssume = objectNameToAssume::uuid;
exception when invalid_text_representation then
objectUuidToAssume = rbac.findObjectUuidByIdName(objectTableToAssume, objectNameToAssume);
end;
if objectUuidToAssume is null then if objectUuidToAssume is null then
raise exception '[401] object % cannot be found in table % (from roleNameParts=%)', objectNameToAssume, objectTableToAssume, roleNameParts; raise exception '[401] object % cannot be found in table % (from roleNameParts=%)', objectNameToAssume, objectTableToAssume, roleNameParts;
end if; end if;
@ -88,7 +93,7 @@ create or replace procedure base.contextDefined(
currentTask varchar(127), currentTask varchar(127),
currentRequest text, currentRequest text,
currentSubject varchar(63), currentSubject varchar(63),
assumedRoles varchar(1023) assumedRoles varchar(4096)
) )
language plpgsql as $$ language plpgsql as $$
declare declare
@ -103,7 +108,7 @@ begin
execute format('set local hsadminng.currentSubjectUuid to %L', coalesce(currentSubjectUuid::text, '')); execute format('set local hsadminng.currentSubjectUuid to %L', coalesce(currentSubjectUuid::text, ''));
execute format('set local hsadminng.assumedRoles to %L', assumedRoles); execute format('set local hsadminng.assumedRoles to %L', assumedRoles);
execute format('set local hsadminng.currentSubjectOrAssumedRolesUuids to %L', execute format('set local hsadminng.currentSubjectOrAssumedRolesUuids to %L', -- FIXME: can this be removed?
(select array_to_string(rbac.determinecurrentsubjectorassumedrolesuuids(currentSubjectUuid, assumedRoles), ';'))); (select array_to_string(rbac.determinecurrentsubjectorassumedrolesuuids(currentSubjectUuid, assumedRoles), ';')));
raise notice 'Context defined as: %, %, %, [%]', currentTask, currentRequest, currentSubject, assumedRoles; raise notice 'Context defined as: %, %, %, [%]', currentTask, currentRequest, currentSubject, assumedRoles;

View File

@ -45,7 +45,8 @@ do language plpgsql $$
call hs_office.person_create_test_data('NP', null, 'Smith', 'Peter'); call hs_office.person_create_test_data('NP', null, 'Smith', 'Peter');
call hs_office.person_create_test_data('NP', null, 'Tucker', 'Jack'); call hs_office.person_create_test_data('NP', null, 'Tucker', 'Jack');
call hs_office.person_create_test_data('NP', null, 'Fouler', 'Ellie'); call hs_office.person_create_test_data('NP', null, 'Fouler', 'Ellie');
call hs_office.person_create_test_data('LP', 'Second e.K.', 'Smith', 'Peter'); -- the next tradeName is deliberately 63 chars in length, the max length for that field, also to test long rbac-role names
call hs_office.person_create_test_data('LP', 'Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'Smith', 'Peter');
call hs_office.person_create_test_data('IF', 'Third OHG'); call hs_office.person_create_test_data('IF', 'Third OHG');
call hs_office.person_create_test_data('LP', 'Fourth eG'); call hs_office.person_create_test_data('LP', 'Fourth eG');
call hs_office.person_create_test_data('UF', 'Erben Bessler', 'Mel', 'Bessler'); call hs_office.person_create_test_data('UF', 'Erben Bessler', 'Mel', 'Bessler');

View File

@ -91,9 +91,9 @@ do language plpgsql $$
call hs_office.relation_create_test_data('Firby', 'REPRESENTATIVE', 'First GmbH', 'first contact'); call hs_office.relation_create_test_data('Firby', 'REPRESENTATIVE', 'First GmbH', 'first contact');
call hs_office.relation_create_test_data('First GmbH', 'DEBITOR', 'First GmbH', 'first contact'); call hs_office.relation_create_test_data('First GmbH', 'DEBITOR', 'First GmbH', 'first contact');
call hs_office.relation_create_test_data('Second e.K.', 'PARTNER', 'Hostsharing eG', 'second contact'); call hs_office.relation_create_test_data('Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'PARTNER', 'Hostsharing eG', 'second contact');
call hs_office.relation_create_test_data('Smith', 'REPRESENTATIVE', 'Second e.K.', 'second contact'); call hs_office.relation_create_test_data('Smith', 'REPRESENTATIVE', 'Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'second contact');
call hs_office.relation_create_test_data('Second e.K.', 'DEBITOR', 'Second e.K.', 'second contact'); call hs_office.relation_create_test_data('Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'DEBITOR', 'Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'second contact');
call hs_office.relation_create_test_data('Third OHG', 'PARTNER', 'Hostsharing eG', 'third contact'); call hs_office.relation_create_test_data('Third OHG', 'PARTNER', 'Hostsharing eG', 'third contact');
call hs_office.relation_create_test_data('Tucker', 'REPRESENTATIVE', 'Third OHG', 'third contact'); call hs_office.relation_create_test_data('Tucker', 'REPRESENTATIVE', 'Third OHG', 'third contact');

View File

@ -74,7 +74,7 @@ do language plpgsql $$
call base.defineContext('creating partner test-data ', null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN'); call base.defineContext('creating partner test-data ', null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
call hs_office.partner_create_test_data('Hostsharing eG', 10001, 'First GmbH', 'first contact'); call hs_office.partner_create_test_data('Hostsharing eG', 10001, 'First GmbH', 'first contact');
call hs_office.partner_create_test_data('Hostsharing eG', 10002, 'Second e.K.', 'second contact'); call hs_office.partner_create_test_data('Hostsharing eG', 10002, 'Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'second contact');
call hs_office.partner_create_test_data('Hostsharing eG', 10003, 'Third OHG', 'third contact'); call hs_office.partner_create_test_data('Hostsharing eG', 10003, 'Third OHG', 'third contact');
call hs_office.partner_create_test_data('Hostsharing eG', 10004, 'Fourth eG', 'fourth contact'); call hs_office.partner_create_test_data('Hostsharing eG', 10004, 'Fourth eG', 'fourth contact');
call hs_office.partner_create_test_data('Hostsharing eG', 10010, 'Smith', 'fifth contact'); call hs_office.partner_create_test_data('Hostsharing eG', 10010, 'Smith', 'fifth contact');

View File

@ -13,7 +13,7 @@ create or replace procedure hs_office.bankaccount_create_test_data(givenHolder v
declare declare
emailAddr varchar; emailAddr varchar;
begin begin
emailAddr = 'bankaccount-admin@' || base.cleanIdentifier(givenHolder) || '.example.com'; emailAddr = 'bankaccount-admin@' || TRIM(SUBSTRING(base.cleanIdentifier(givenHolder) FOR 32)) || '.example.com';
perform rbac.create_subject(emailAddr); perform rbac.create_subject(emailAddr);
call base.defineContext('creating bankaccount test-data', null, emailAddr); call base.defineContext('creating bankaccount test-data', null, emailAddr);
@ -36,7 +36,7 @@ do language plpgsql $$
-- IBANs+BICs taken from https://ibanvalidieren.de/beispiele.html -- IBANs+BICs taken from https://ibanvalidieren.de/beispiele.html
call hs_office.bankaccount_create_test_data('First GmbH', 'DE02120300000000202051', 'BYLADEM1001'); call hs_office.bankaccount_create_test_data('First GmbH', 'DE02120300000000202051', 'BYLADEM1001');
call hs_office.bankaccount_create_test_data('Peter Smith', 'DE02500105170137075030', 'INGDDEFF'); call hs_office.bankaccount_create_test_data('Peter Smith', 'DE02500105170137075030', 'INGDDEFF');
call hs_office.bankaccount_create_test_data('Second e.K.', 'DE02100500000054540402', 'BELADEBE'); call hs_office.bankaccount_create_test_data('Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'DE02100500000054540402', 'BELADEBE');
call hs_office.bankaccount_create_test_data('Third OHG', 'DE02300209000106531065', 'CMCIDEDD'); call hs_office.bankaccount_create_test_data('Third OHG', 'DE02300209000106531065', 'CMCIDEDD');
call hs_office.bankaccount_create_test_data('Fourth eG', 'DE02200505501015871393', 'HASPDEHH'); call hs_office.bankaccount_create_test_data('Fourth eG', 'DE02200505501015871393', 'HASPDEHH');
call hs_office.bankaccount_create_test_data('Mel Bessler', 'DE02100100100006820101', 'PBNKDEFF'); call hs_office.bankaccount_create_test_data('Mel Bessler', 'DE02100100100006820101', 'PBNKDEFF');

View File

@ -53,7 +53,7 @@ do language plpgsql $$
call base.defineContext('creating debitor test-data', null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN'); call base.defineContext('creating debitor test-data', null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
call hs_office.debitor_create_test_data(11, 'First GmbH', 'first contact', 'fir'); call hs_office.debitor_create_test_data(11, 'First GmbH', 'first contact', 'fir');
call hs_office.debitor_create_test_data(12, 'Second e.K.', 'second contact', 'sec'); call hs_office.debitor_create_test_data(12, 'Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'second contact', 'sec');
call hs_office.debitor_create_test_data(13, 'Third OHG', 'third contact', 'thi'); call hs_office.debitor_create_test_data(13, 'Third OHG', 'third contact', 'thi');
end; end;
$$; $$;

View File

@ -97,7 +97,7 @@ class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCl
"bic": "INGDDEFF" "bic": "INGDDEFF"
}, },
{ {
"holder": "Second e.K.", "holder": "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.",
"iban": "DE02100500000054540402", "iban": "DE02100500000054540402",
"bic": "BELADEBE" "bic": "BELADEBE"
}, },

View File

@ -147,7 +147,7 @@ class HsOfficeBankAccountRepositoryIntegrationTest extends ContextBasedTestWithC
"Mel Bessler", "Mel Bessler",
"Paul Winkler", "Paul Winkler",
"Peter Smith", "Peter Smith",
"Second e.K.", "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.",
"Third OHG"); "Third OHG");
} }

View File

@ -227,20 +227,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
}, },
{ {
"debitorRel": { "debitorRel": {
"anchor": {"tradeName": "Second e.K."}, "anchor": {"tradeName": "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K."},
"holder": {"tradeName": "Second e.K."},
"type": "DEBITOR",
"contact": {
"emailAddresses": { "main": "contact-admin@secondcontact.example.com" }
}
},
"debitorNumber": "D-1000212",
"debitorNumberSuffix": "12",
"partner": {
"partnerNumber": "P-10002",
"partnerRel": {
"anchor": {"tradeName": "Hostsharing eG"},
"holder": {"tradeName": "Second e.K."},
"type": "PARTNER", "type": "PARTNER",
"contact": { "contact": {
"emailAddresses": { "main": "contact-admin@secondcontact.example.com" } "emailAddresses": { "main": "contact-admin@secondcontact.example.com" }

View File

@ -240,7 +240,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
allTheseDebitorsAreReturned( allTheseDebitorsAreReturned(
result, result,
"debitor(D-1000111: rel(anchor='LP First GmbH', type='DEBITOR', holder='LP First GmbH'), fir)", "debitor(D-1000111: rel(anchor='LP First GmbH', type='DEBITOR', holder='LP First GmbH'), fir)",
"debitor(D-1000212: rel(anchor='LP Second e.K.', type='DEBITOR', holder='LP Second e.K.'), sec)", "debitor(D-1000212: rel(anchor='LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', type='DEBITOR', holder='LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.'), sec)",
"debitor(D-1000313: rel(anchor='IF Third OHG', type='DEBITOR', holder='IF Third OHG'), thi)"); "debitor(D-1000313: rel(anchor='IF Third OHG', type='DEBITOR', holder='IF Third OHG'), thi)");
} }

View File

@ -411,7 +411,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
// and an ex-partner-relation got created // and an ex-partner-relation got created
final var anchorpartnerPersonUUid = givenPartner.getPartnerRel().getAnchor().getUuid(); final var anchorpartnerPersonUUid = givenPartner.getPartnerRel().getAnchor().getUuid();
assertThat(relationRepo.findRelationRelatedToPersonUuidAndRelationType(anchorpartnerPersonUUid, EX_PARTNER)) assertThat(relationRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(anchorpartnerPersonUUid, EX_PARTNER, null, null, null))
.map(HsOfficeRelation::toShortString) .map(HsOfficeRelation::toShortString)
.contains("rel(anchor='LP Hostsharing eG', type='EX_PARTNER', holder='UF Erben Bessler')"); .contains("rel(anchor='LP Hostsharing eG', type='EX_PARTNER', holder='UF Erben Bessler')");
} }

View File

@ -199,7 +199,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
allThesePartnersAreReturned( allThesePartnersAreReturned(
result, result,
"partner(P-10001: LP First GmbH, first contact)", "partner(P-10001: LP First GmbH, first contact)",
"partner(P-10002: LP Second e.K., second contact)", "partner(P-10002: LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K., second contact)",
"partner(P-10003: IF Third OHG, third contact)", "partner(P-10003: IF Third OHG, third contact)",
"partner(P-10004: LP Fourth eG, fourth contact)", "partner(P-10004: LP Fourth eG, fourth contact)",
"partner(P-10010: NP Smith, Peter, sixth contact)"); "partner(P-10010: NP Smith, Peter, sixth contact)");

View File

@ -143,38 +143,7 @@ class HsOfficePersonRbacRepositoryIntegrationTest extends ContextBasedTestWithCl
allThesePersonsAreReturned( allThesePersonsAreReturned(
result, result,
"NP Smith, Peter", "NP Smith, Peter",
"LP Second e.K.", "LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.");
"IF Third OHG",
"UF Erben Bessler");
}
@Test
public void arbitraryUser_canViewOnlyItsOwnPerson() {
// given:
final var givenPerson = givenSomeTemporaryPerson("pac-admin-zzz00@zzz.example.com");
// when:
context("pac-admin-zzz00@zzz.example.com");
final var result = personRbacRepo.findPersonByOptionalNameLike(null);
// then:
exactlyThesePersonsAreReturned(result, givenPerson.getTradeName());
}
}
@Nested
class FindByCaptionLike {
@Test
public void globalAdmin_withoutAssumedRole_canViewAllPersons() {
// given
context("superuser-alex@hostsharing.net", null);
// when
final var result = personRbacRepo.findPersonByOptionalNameLike("Second");
// then
exactlyThesePersonsAreReturned(result, "Second e.K.");
} }
@Test @Test
@ -272,7 +241,7 @@ class HsOfficePersonRbacRepositoryIntegrationTest extends ContextBasedTestWithCl
assertThat(customerLogEntries).map(Arrays::toString).contains( assertThat(customerLogEntries).map(Arrays::toString).contains(
"[creating person test-data, hs_office.person, INSERT, Hostsharing eG, null]", "[creating person test-data, hs_office.person, INSERT, Hostsharing eG, null]",
"[creating person test-data, hs_office.person, INSERT, First GmbH, null]", "[creating person test-data, hs_office.person, INSERT, First GmbH, null]",
"[creating person test-data, hs_office.person, INSERT, Second e.K., null]", "[creating person test-data, hs_office.person, INSERT, Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K., null]",
"[creating person test-data, hs_office.person, INSERT, Third OHG, null]"); "[creating person test-data, hs_office.person, INSERT, Third OHG, null]");
} }

View File

@ -126,25 +126,7 @@ class HsOfficePersonRealRepositoryIntegrationTest extends ContextBasedTestWithCl
allThesePersonsAreReturned( allThesePersonsAreReturned(
result, result,
"NP Smith, Peter", "NP Smith, Peter",
"LP Second e.K.", "LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.");
"IF Third OHG",
"UF Erben Bessler");
}
}
@Nested
class FindByCaptionLike {
@Test
public void arbitraryUser_canViewAllPersons() {
// given
context("selfregistered-user-drew@hostsharing.org");
// when
final var result = personRealRepo.findPersonByOptionalNameLike("Second");
// then
exactlyThesePersonsAreReturned(result, "Second e.K.");
} }
} }
@ -164,7 +146,7 @@ class HsOfficePersonRealRepositoryIntegrationTest extends ContextBasedTestWithCl
assertThat(customerLogEntries).map(Arrays::toString).contains( assertThat(customerLogEntries).map(Arrays::toString).contains(
"[creating person test-data, hs_office.person, INSERT, Hostsharing eG, null]", "[creating person test-data, hs_office.person, INSERT, Hostsharing eG, null]",
"[creating person test-data, hs_office.person, INSERT, First GmbH, null]", "[creating person test-data, hs_office.person, INSERT, First GmbH, null]",
"[creating person test-data, hs_office.person, INSERT, Second e.K., null]", "[creating person test-data, hs_office.person, INSERT, Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K., null]",
"[creating person test-data, hs_office.person, INSERT, Third OHG, null]"); "[creating person test-data, hs_office.person, INSERT, Third OHG, null]");
} }

View File

@ -47,13 +47,13 @@ class HsOfficeRealRelationRepositoryIntegrationTest extends ContextBasedTestWith
final var personUuid = determinePersonUuid(NATURAL_PERSON, "Smith"); final var personUuid = determinePersonUuid(NATURAL_PERSON, "Smith");
// when // when
final var result = relationRealRepo.findRelationRelatedToPersonUuidAndRelationType(personUuid, null); final var result = relationRealRepo.findRelationRelatedToPersonUuid(personUuid);
// then // then
context("superuser-alex@hostsharing.net"); // just to be able to access RBAc-entities persons+contact context("superuser-alex@hostsharing.net"); // just to be able to access RBAc-entities persons+contact
exactlyTheseRelationsAreReturned( exactlyTheseRelationsAreReturned(
result, result,
"rel(anchor='LP Second e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')", "rel(anchor='LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')",
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Smith, Peter', contact='sixth contact')", "rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Smith, Peter', contact='sixth contact')",
"rel(anchor='NP Smith, Peter', type='DEBITOR', holder='NP Smith, Peter', contact='third contact')", "rel(anchor='NP Smith, Peter', type='DEBITOR', holder='NP Smith, Peter', contact='third contact')",
"rel(anchor='IF Third OHG', type='SUBSCRIBER', mark='members-announce', holder='NP Smith, Peter', contact='third contact')" "rel(anchor='IF Third OHG', type='SUBSCRIBER', mark='members-announce', holder='NP Smith, Peter', contact='third contact')"
@ -66,13 +66,13 @@ class HsOfficeRealRelationRepositoryIntegrationTest extends ContextBasedTestWith
final var personUuid = determinePersonUuid(NATURAL_PERSON, "Smith"); final var personUuid = determinePersonUuid(NATURAL_PERSON, "Smith");
// when: // when:
final var result = relationRealRepo.findRelationRelatedToPersonUuidAndRelationType(personUuid, REPRESENTATIVE); final var result = relationRealRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(personUuid, REPRESENTATIVE, null, null, null);
// then: // then:
context("superuser-alex@hostsharing.net"); // just to be able to access RBAc-entities persons+contact context("superuser-alex@hostsharing.net"); // just to be able to access RBAc-entities persons+contact
exactlyTheseRelationsAreReturned( exactlyTheseRelationsAreReturned(
result, result,
"rel(anchor='LP Second e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')" "rel(anchor='LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')"
); );
} }
} }

View File

@ -90,7 +90,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
}, },
{ {
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" }, "anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
"holder": { "personType": "LEGAL_PERSON", "tradeName": "Second e.K.", "givenName": "Peter", "familyName": "Smith" }, "holder": { "personType": "LEGAL_PERSON", "tradeName": "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.", "givenName": "Peter", "familyName": "Smith" },
"type": "PARTNER", "type": "PARTNER",
"mark": null, "mark": null,
"contact": { "caption": "second contact" } "contact": { "caption": "second contact" }

View File

@ -3,10 +3,12 @@ package net.hostsharing.hsadminng.hs.office.relation;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.lambda.Reducer;
import net.hostsharing.hsadminng.mapper.Array;
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository; import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository; import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository;
import net.hostsharing.hsadminng.mapper.Array; import net.hostsharing.hsadminng.rbac.role.RbacRoleRepository;
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -30,17 +32,20 @@ import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@DataJpaTest @DataJpaTest
@Import( { Context.class, JpaAttempt.class }) @Import({ Context.class, JpaAttempt.class })
class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithCleanup { class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
@Autowired @Autowired
HsOfficeRelationRbacRepository relationRbacRepo; HsOfficeRelationRbacRepository relationRbacRepo;
@Autowired
HsOfficeRelationRealRepository relationRealRepo;
@Autowired @Autowired
HsOfficePersonRealRepository personRepo; HsOfficePersonRealRepository personRepo;
@Autowired @Autowired
HsOfficeContactRealRepository contactrealRepo; HsOfficeContactRealRepository contactRealRepo;
@Autowired @Autowired
RawRbacRoleRepository rawRoleRepo; RawRbacRoleRepository rawRoleRepo;
@ -57,6 +62,29 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
@MockBean @MockBean
HttpServletRequest request; HttpServletRequest request;
@Autowired
private RbacRoleRepository rbacRoleRepository;
@Nested
class AssumeRelationRole {
@Test
public void testHostsharingAdminCanAssumeRelationRoleWithLongIdName() {
context(
"superuser-alex@hostsharing.net",
"hs_office.relation#HostsharingeG-with-PARTNER-PeterSmith-TheSecondHandandThriftStores-n-Shippinge.K.SmithPeter:AGENT");
}
@Test
public void testHostsharingAdminCanAssumeRelationRoleWithUuid() {
final var relationUuid = relationRealRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(
null, HsOfficeRelationType.PARTNER, null, "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.", null)
.stream().reduce(Reducer::toSingleElement).orElseThrow().getUuid();
context("superuser-alex@hostsharing.net", "hs_office.relation#" + relationUuid + ":AGENT");
}
}
@Nested @Nested
class CreateRelation { class CreateRelation {
@ -64,6 +92,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewRelation() { public void testHostsharingAdmin_withoutAssumedRole_canCreateNewRelation() {
// given // given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var count = relationRbacRepo.count(); final var count = relationRbacRepo.count();
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").stream() final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").stream()
.filter(p -> p.getPersonType() == UNINCORPORATED_FIRM) .filter(p -> p.getPersonType() == UNINCORPORATED_FIRM)
@ -71,20 +100,21 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Paul").stream() final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Paul").stream()
.filter(p -> p.getPersonType() == NATURAL_PERSON) .filter(p -> p.getPersonType() == NATURAL_PERSON)
.findFirst().orElseThrow(); .findFirst().orElseThrow();
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth contact").stream() final var givenContact = contactRealRepo.findContactByOptionalCaptionLike("fourth contact").stream()
.findFirst().orElseThrow(); .findFirst().orElseThrow();
// when // when
final var result = attempt(em, () -> { final var result = attempt(
final var newRelation = HsOfficeRelationRbacEntity.builder() em, () -> {
.anchor(givenAnchorPerson) final var newRelation = HsOfficeRelationRbacEntity.builder()
.holder(givenHolderPerson) .anchor(givenAnchorPerson)
.type(HsOfficeRelationType.SUBSCRIBER) .holder(givenHolderPerson)
.mark("operations-announce") .type(HsOfficeRelationType.SUBSCRIBER)
.contact(givenContact) .mark("operations-announce")
.build(); .contact(givenContact)
return toCleanup(relationRbacRepo.save(newRelation)); .build();
}); return toCleanup(relationRbacRepo.save(newRelation));
});
// then // then
result.assertSuccessful(); result.assertSuccessful();
@ -93,7 +123,8 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
assertThat(relationRbacRepo.count()).isEqualTo(count + 1); assertThat(relationRbacRepo.count()).isEqualTo(count + 1);
final var stored = relationRbacRepo.findByUuid(result.returnedValue().getUuid()); final var stored = relationRbacRepo.findByUuid(result.returnedValue().getUuid());
assertThat(stored).isNotEmpty().map(HsOfficeRelation::toString).get() assertThat(stored).isNotEmpty().map(HsOfficeRelation::toString).get()
.isEqualTo("rel(anchor='UF Erben Bessler', type='SUBSCRIBER', mark='operations-announce', holder='NP Winkler, Paul', contact='fourth contact')"); .isEqualTo(
"rel(anchor='UF Erben Bessler', type='SUBSCRIBER', mark='operations-announce', holder='NP Winkler, Paul', contact='fourth contact')");
} }
@Test @Test
@ -104,23 +135,24 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll()); final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll());
// when // when
attempt(em, () -> { attempt(
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").stream() em, () -> {
.filter(p -> p.getPersonType() == UNINCORPORATED_FIRM) final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").stream()
.findFirst().orElseThrow(); .filter(p -> p.getPersonType() == UNINCORPORATED_FIRM)
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Bert").stream() .findFirst().orElseThrow();
.filter(p -> p.getPersonType() == NATURAL_PERSON) final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Bert").stream()
.findFirst().orElseThrow(); .filter(p -> p.getPersonType() == NATURAL_PERSON)
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth contact").stream() .findFirst().orElseThrow();
.findFirst().orElseThrow(); final var givenContact = contactRealRepo.findContactByOptionalCaptionLike("fourth contact").stream()
final var newRelation = HsOfficeRelationRbacEntity.builder() .findFirst().orElseThrow();
.anchor(givenAnchorPerson) final var newRelation = HsOfficeRelationRbacEntity.builder()
.holder(givenHolderPerson) .anchor(givenAnchorPerson)
.type(HsOfficeRelationType.REPRESENTATIVE) .holder(givenHolderPerson)
.contact(givenContact) .type(HsOfficeRelationType.REPRESENTATIVE)
.build(); .contact(givenContact)
return toCleanup(relationRbacRepo.save(newRelation)); .build();
}); return toCleanup(relationRbacRepo.save(newRelation));
});
// then // then
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from( assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
@ -180,7 +212,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
allTheseRelationsAreReturned( allTheseRelationsAreReturned(
result, result,
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Smith, Peter', contact='sixth contact')", "rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Smith, Peter', contact='sixth contact')",
"rel(anchor='LP Second e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')", "rel(anchor='LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')",
"rel(anchor='IF Third OHG', type='SUBSCRIBER', mark='members-announce', holder='NP Smith, Peter', contact='third contact')"); "rel(anchor='IF Third OHG', type='SUBSCRIBER', mark='members-announce', holder='NP Smith, Peter', contact='third contact')");
} }
@ -193,12 +225,17 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
.findFirst().orElseThrow(); .findFirst().orElseThrow();
// when: // when:
final var result = relationRbacRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(person.getUuid(), null, null, null, null); final var result = relationRbacRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(
person.getUuid(),
null,
null,
null,
null);
// then: // then:
exactlyTheseRelationsAreReturned( exactlyTheseRelationsAreReturned(
result, result,
"rel(anchor='LP Second e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')", "rel(anchor='LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')",
"rel(anchor='IF Third OHG', type='SUBSCRIBER', mark='members-announce', holder='NP Smith, Peter', contact='third contact')", "rel(anchor='IF Third OHG', type='SUBSCRIBER', mark='members-announce', holder='NP Smith, Peter', contact='third contact')",
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Smith, Peter', contact='sixth contact')", "rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Smith, Peter', contact='sixth contact')",
"rel(anchor='NP Smith, Peter', type='DEBITOR', holder='NP Smith, Peter', contact='third contact')"); "rel(anchor='NP Smith, Peter', type='DEBITOR', holder='NP Smith, Peter', contact='third contact')");
@ -219,7 +256,10 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
givenRelation, givenRelation,
"hs_office.person#ErbenBesslerMelBessler:ADMIN"); "hs_office.person#ErbenBesslerMelBessler:ADMIN");
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("sixth contact").stream().findFirst().orElseThrow(); final var givenContact = contactRealRepo.findContactByOptionalCaptionLike("sixth contact")
.stream()
.findFirst()
.orElseThrow();
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
@ -258,13 +298,16 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office.relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerAnita:AGENT"); context(
"superuser-alex@hostsharing.net",
"hs_office.relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerAnita:AGENT");
givenRelation.setContact(null); givenRelation.setContact(null);
return relationRbacRepo.save(givenRelation); return relationRbacRepo.save(givenRelation);
}); });
// then // then
result.assertExceptionWithRootCauseMessage(JpaSystemException.class, result.assertExceptionWithRootCauseMessage(
JpaSystemException.class,
"[403] Subject ", " is not allowed to update hs_office.relation uuid"); "[403] Subject ", " is not allowed to update hs_office.relation uuid");
} }
@ -287,7 +330,8 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
}); });
// then // then
result.assertExceptionWithRootCauseMessage(JpaSystemException.class, result.assertExceptionWithRootCauseMessage(
JpaSystemException.class,
"[403] Subject ", " is not allowed to update hs_office.relation uuid"); "[403] Subject ", " is not allowed to update hs_office.relation uuid");
} }
@ -397,7 +441,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
select currentTask, targetTable, targetOp, targetdelta->>'mark' select currentTask, targetTable, targetOp, targetdelta->>'mark'
from base.tx_journal_v from base.tx_journal_v
where targettable = 'hs_office.relation'; where targettable = 'hs_office.relation';
"""); """);
// when // when
@SuppressWarnings("unchecked") final List<Object[]> customerLogEntries = query.getResultList(); @SuppressWarnings("unchecked") final List<Object[]> customerLogEntries = query.getResultList();
@ -412,7 +456,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0); final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0);
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike(contact).get(0); final var givenContact = contactRealRepo.findContactByOptionalCaptionLike(contact).get(0);
final var newRelation = HsOfficeRelationRbacEntity.builder() final var newRelation = HsOfficeRelationRbacEntity.builder()
.type(HsOfficeRelationType.REPRESENTATIVE) .type(HsOfficeRelationType.REPRESENTATIVE)
.anchor(givenAnchorPerson) .anchor(givenAnchorPerson)

View File

@ -83,7 +83,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
}, },
{ {
"debitor": { "debitorNumber": "D-1000212" }, "debitor": { "debitorNumber": "D-1000212" },
"bankAccount": { "holder": "Second e.K." }, "bankAccount": { "holder": "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K." },
"reference": "ref-10002-12", "reference": "ref-10002-12",
"validFrom": "2022-10-01", "validFrom": "2022-10-01",
"validTo": "2026-12-31" "validTo": "2026-12-31"

View File

@ -68,7 +68,7 @@ class RbacRoleRepositoryIntegrationTest {
} }
@Test @Test
public void globalAdmin_withAssumedglobalAdminRole_canViewAllRbacRoles() { public void globalAdmin_withAssumedGlobalAdminRole_canViewAllRbacRoles() {
given: given:
context.define("superuser-alex@hostsharing.net", "rbac.global#global:ADMIN"); context.define("superuser-alex@hostsharing.net", "rbac.global#global:ADMIN");