From fa06062dcd9f90db2c71e99e42bcda07cb07f8f8 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Fri, 27 Dec 2024 09:04:18 +0100 Subject: [PATCH 01/13] cas-curl to support assume --- bin/cas-curl | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/bin/cas-curl b/bin/cas-curl index 41427a41..6bf351e0 100755 --- a/bin/cas-curl +++ b/bin/cas-curl @@ -11,13 +11,23 @@ EOF exit fi +export HSADMINNG_CAS_ASSUME_HEADER +if [ -f ~/.cas-curl-assume ]; then + HSADMINNG_CAS_ASSUME="$(cat ~/.cas-curl-assume)" +else + HSADMINNG_CAS_ASSUME= +fi + if [ "$1" == "--trace" ]; then function trace() { echo "$*" >&2 } function doCurl() { set -x - curl --fail-with-body --header "Authorization: $HSADMINNG_CAS_TICKET" "$@" + curl --fail-with-body \ + --header "Authorization: $HSADMINNG_CAS_TICKET" \ + --header "assumed-roles: $HSADMINNG_CAS_ASSUME" \ + "$@" set +x } shift @@ -76,6 +86,7 @@ function casLogin() { if [ -z "$HSADMINNG_CAS_TGT" ]; then echo "ERROR: could not get ticket granting ticket" >&2 cat ~/.cas-login-tgt.response >&2 + exit 1 fi echo "$HSADMINNG_CAS_TGT" >~/.cas-login-tgt trace "$HSADMINNG_CAS_TGT" @@ -121,6 +132,14 @@ case "${1,,}" in export HSADMINNG_CAS_PASSWORD= casLogin ;; + "assume") # assumes the given comma-separated roles + shift + if [ -z "$1" ]; then + rm ~/.cas-curl-assume + else + echo "$1" >~/.cas-curl-assume + fi + ;; "logout") # logout, deleting ticket granting ticket casLogout ;; -- 2.39.5 From 5e74431d3380900dee5306b6063dad3b2abb8ea8 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Fri, 27 Dec 2024 09:05:04 +0100 Subject: [PATCH 02/13] improved error messages in findObjectUuidByIdName+findIdNameByObjectUuid --- .../resources/db/changelog/1-rbac/1050-rbac-base.sql | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/resources/db/changelog/1-rbac/1050-rbac-base.sql b/src/main/resources/db/changelog/1-rbac/1050-rbac-base.sql index 82c43238..e9ae48c4 100644 --- a/src/main/resources/db/changelog/1-rbac/1050-rbac-base.sql +++ b/src/main/resources/db/changelog/1-rbac/1050-rbac-base.sql @@ -251,9 +251,14 @@ begin execute sql into uuid; exception when others then - raise exception 'function %_uuid_by_id_name(...) not found, add identity view support for table %', objectTable, objectTable; + raise exception 'function %_uuid_by_id_name(''%'') failed: %, SQLSTATE: %. If it could not be found, add identity view support to %\nSQL:%', + objectTable, objectIdName, SQLERRM, SQLSTATE, objectTable, sql; end; - return uuid; + if uuid is null then + raise exception 'SQL returned null: %', sql; + else + return uuid; + end if; end ; $$; create or replace function rbac.findIdNameByObjectUuid(objectTable varchar, objectUuid uuid) @@ -270,7 +275,8 @@ begin execute sql into idName; exception when others then - raise exception 'function %_id_name_by_uuid(...) not found, add identity view support for table %', objectTable, objectTable; + raise exception 'function %_id_name_by_uuid(''%'') failed: %, SQLSTATE: %. If it could not be found, add identity view support to %', + objectTable, objectUuid, SQLERRM, SQLSTATE, objectTable; end; return idName; end ; $$; -- 2.39.5 From 1f14c370f7e4bfcbaf0c05a33b9754cf618b72e1 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Fri, 27 Dec 2024 09:06:17 +0100 Subject: [PATCH 03/13] temporarily set length of objectNameToAssume to 1024 --- src/main/resources/db/changelog/1-rbac/1054-rbac-context.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/changelog/1-rbac/1054-rbac-context.sql b/src/main/resources/db/changelog/1-rbac/1054-rbac-context.sql index 892b5933..ba50fbc3 100644 --- a/src/main/resources/db/changelog/1-rbac/1054-rbac-context.sql +++ b/src/main/resources/db/changelog/1-rbac/1054-rbac-context.sql @@ -31,7 +31,7 @@ declare roleName text; roleNameParts text; objectTableToAssume varchar(63); - objectNameToAssume varchar(63); + objectNameToAssume varchar(1024); -- FIXME: find sensible limit objectUuidToAssume uuid; roleTypeToAssume rbac.RoleType; roleIdsToAssume uuid[]; -- 2.39.5 From 44951f439ab76585c8df326e66382e032d7374fb Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Sat, 28 Dec 2024 16:07:02 +0100 Subject: [PATCH 04/13] assume with table#uuid:roletype --- .../hsadminng/context/Context.java | 2 +- .../HsOfficeRelationRbacRepository.java | 2 +- .../HsOfficeRelationRealRepository.java | 63 +++++++-- .../db/changelog/0-base/010-context.sql | 6 +- .../db/changelog/1-rbac/1054-rbac-context.sql | 15 +- .../5028-hs-office-person-test-data.sql | 3 +- .../5038-hs-office-relation-test-data.sql | 6 +- .../5048-hs-office-partner-test-data.sql | 2 +- .../5058-hs-office-bankaccount-test-data.sql | 4 +- .../5068-hs-office-debitor-test-data.sql | 2 +- ...ceBankAccountControllerAcceptanceTest.java | 2 +- ...eBankAccountRepositoryIntegrationTest.java | 2 +- ...OfficeDebitorControllerAcceptanceTest.java | 15 +- ...fficeDebitorRepositoryIntegrationTest.java | 2 +- ...OfficePartnerControllerAcceptanceTest.java | 2 +- ...fficePartnerRepositoryIntegrationTest.java | 2 +- ...cePersonRbacRepositoryIntegrationTest.java | 35 +---- ...cePersonRealRepositoryIntegrationTest.java | 22 +-- ...RealRelationRepositoryIntegrationTest.java | 8 +- ...fficeRelationControllerAcceptanceTest.java | 2 +- ...ficeRelationRepositoryIntegrationTest.java | 128 ++++++++++++------ ...ceSepaMandateControllerAcceptanceTest.java | 2 +- .../RbacRoleRepositoryIntegrationTest.java | 2 +- 23 files changed, 179 insertions(+), 150 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/context/Context.java b/src/main/java/net/hostsharing/hsadminng/context/Context.java index 6ceed023..c3b27126 100644 --- a/src/main/java/net/hostsharing/hsadminng/context/Context.java +++ b/src/main/java/net/hostsharing/hsadminng/context/Context.java @@ -58,7 +58,7 @@ public class Context { cast(:currentTask as varchar(127)), cast(:currentRequest as text), cast(:currentSubject as varchar(63)), - cast(:assumedRoles as varchar(1023))); + cast(:assumedRoles as text)); """); query.setParameter("currentTask", shortenToMaxLength(currentTask, 127)); query.setParameter("currentRequest", currentRequest); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRbacRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRbacRepository.java index 82e245ae..e687bdcb 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRbacRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRbacRepository.java @@ -42,7 +42,7 @@ public interface HsOfficeRelationRbacRepository extends Repository findByUuid(UUID id); - default List findRelationRelatedToPersonUuidAndRelationType(@NotNull UUID personUuid, HsOfficeRelationType relationType) { - return findRelationRelatedToPersonUuidAndRelationTypeString(personUuid, relationType == null ? null : relationType.toString()); - } - @Query(value = """ SELECT p.* FROM hs_office.relation AS p WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid - """, nativeQuery = true) + """, nativeQuery = true) @Timed("app.repo.relations.findRelationRelatedToPersonUuid.real") List 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 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 = """ - SELECT p.* FROM hs_office.relation AS p - WHERE (:relationType IS NULL OR p.type = cast(:relationType AS hs_office.RelationType)) - AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid) - """, nativeQuery = true) - @Timed("app.repo.relations.findRelationRelatedToPersonUuidAndRelationTypeString.real") - List findRelationRelatedToPersonUuidAndRelationTypeString(@NotNull UUID personUuid, String relationType); + SELECT rel FROM HsOfficeRelationRealEntity AS rel + WHERE (:relationType IS NULL OR CAST(rel.type AS String) = :relationType) + AND ( :personUuid IS NULL + OR rel.anchor.uuid = :personUuid OR rel.holder.uuid = :personUuid ) + AND ( :mark IS NULL OR lower(rel.mark) LIKE :mark ) + 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 findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl( + final UUID personUuid, + final String relationType, + final String mark, + final String personData, + final String contactData); @Timed("app.repo.relations.save.real") HsOfficeRelationRealEntity save(final HsOfficeRelationRealEntity entity); @@ -41,4 +75,11 @@ public interface HsOfficeRelationRealRepository extends Repository p.getPersonType() == UNINCORPORATED_FIRM) @@ -71,20 +100,21 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Paul").stream() .filter(p -> p.getPersonType() == NATURAL_PERSON) .findFirst().orElseThrow(); - final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth contact").stream() + final var givenContact = contactRealRepo.findContactByOptionalCaptionLike("fourth contact").stream() .findFirst().orElseThrow(); // when - final var result = attempt(em, () -> { - final var newRelation = HsOfficeRelationRbacEntity.builder() - .anchor(givenAnchorPerson) - .holder(givenHolderPerson) - .type(HsOfficeRelationType.SUBSCRIBER) - .mark("operations-announce") - .contact(givenContact) - .build(); - return toCleanup(relationRbacRepo.save(newRelation)); - }); + final var result = attempt( + em, () -> { + final var newRelation = HsOfficeRelationRbacEntity.builder() + .anchor(givenAnchorPerson) + .holder(givenHolderPerson) + .type(HsOfficeRelationType.SUBSCRIBER) + .mark("operations-announce") + .contact(givenContact) + .build(); + return toCleanup(relationRbacRepo.save(newRelation)); + }); // then result.assertSuccessful(); @@ -93,7 +123,8 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea assertThat(relationRbacRepo.count()).isEqualTo(count + 1); final var stored = relationRbacRepo.findByUuid(result.returnedValue().getUuid()); 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 @@ -104,23 +135,24 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll()); // 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 = contactrealRepo.findContactByOptionalCaptionLike("fourth contact").stream() - .findFirst().orElseThrow(); - final var newRelation = HsOfficeRelationRbacEntity.builder() - .anchor(givenAnchorPerson) - .holder(givenHolderPerson) - .type(HsOfficeRelationType.REPRESENTATIVE) - .contact(givenContact) - .build(); - return toCleanup(relationRbacRepo.save(newRelation)); - }); + 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 = contactRealRepo.findContactByOptionalCaptionLike("fourth contact").stream() + .findFirst().orElseThrow(); + final var newRelation = HsOfficeRelationRbacEntity.builder() + .anchor(givenAnchorPerson) + .holder(givenHolderPerson) + .type(HsOfficeRelationType.REPRESENTATIVE) + .contact(givenContact) + .build(); + return toCleanup(relationRbacRepo.save(newRelation)); + }); // then assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from( @@ -180,7 +212,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea allTheseRelationsAreReturned( result, "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')"); } @@ -193,12 +225,17 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea .findFirst().orElseThrow(); // when: - final var result = relationRbacRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(person.getUuid(), null, null, null, null); + final var result = relationRbacRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData( + person.getUuid(), + null, + null, + null, + null); // then: exactlyTheseRelationsAreReturned( 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='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')"); @@ -219,7 +256,10 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea givenRelation, "hs_office.person#ErbenBesslerMelBessler:ADMIN"); 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 final var result = jpaAttempt.transacted(() -> { @@ -258,13 +298,16 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea // when 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); return relationRbacRepo.save(givenRelation); }); // then - result.assertExceptionWithRootCauseMessage(JpaSystemException.class, + result.assertExceptionWithRootCauseMessage( + JpaSystemException.class, "[403] Subject ", " is not allowed to update hs_office.relation uuid"); } @@ -287,7 +330,8 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea }); // then - result.assertExceptionWithRootCauseMessage(JpaSystemException.class, + result.assertExceptionWithRootCauseMessage( + JpaSystemException.class, "[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' from base.tx_journal_v where targettable = 'hs_office.relation'; - """); + """); // when @SuppressWarnings("unchecked") final List customerLogEntries = query.getResultList(); @@ -412,7 +456,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea context("superuser-alex@hostsharing.net"); final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").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() .type(HsOfficeRelationType.REPRESENTATIVE) .anchor(givenAnchorPerson) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java index ef334b0a..eabde5a7 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateControllerAcceptanceTest.java @@ -83,7 +83,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl }, { "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", "validFrom": "2022-10-01", "validTo": "2026-12-31" diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleRepositoryIntegrationTest.java index 7540777a..98495e81 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/role/RbacRoleRepositoryIntegrationTest.java @@ -68,7 +68,7 @@ class RbacRoleRepositoryIntegrationTest { } @Test - public void globalAdmin_withAssumedglobalAdminRole_canViewAllRbacRoles() { + public void globalAdmin_withAssumedGlobalAdminRole_canViewAllRbacRoles() { given: context.define("superuser-alex@hostsharing.net", "rbac.global#global:ADMIN"); -- 2.39.5 From 8789adf03ed08bc1cccc1c4c9cf59e1cb89408fb Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Sat, 28 Dec 2024 17:34:54 +0100 Subject: [PATCH 05/13] fix failing tests --- .../HsOfficeDebitorControllerAcceptanceTest.java | 13 +++++++++++++ .../hsadminng/rbac/context/ContextUnitTest.java | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java index fd46f721..81d40a0d 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java @@ -228,6 +228,19 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu { "debitorRel": { "anchor": {"tradeName": "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K."}, + "holder": {"tradeName": "Peter Smith - The Second Hand and Thrift Stores-n-Shipping 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": "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K."}, "type": "PARTNER", "contact": { "emailAddresses": { "main": "contact-admin@secondcontact.example.com" } diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextUnitTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextUnitTest.java index 6a6d690f..9546c434 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/context/ContextUnitTest.java @@ -32,7 +32,7 @@ class ContextUnitTest { cast(:currentTask as varchar(127)), cast(:currentRequest as text), cast(:currentSubject as varchar(63)), - cast(:assumedRoles as varchar(1023))); + cast(:assumedRoles as text)); """; @Nested -- 2.39.5 From d66e9b2d542cbfe4d4e3f38f1aaaace9b72b149e Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Sun, 29 Dec 2024 09:43:17 +0100 Subject: [PATCH 06/13] use ILIKE in Relation-queries --- .../relation/HsOfficeRelationRbacRepository.java | 16 ++++++++-------- .../relation/HsOfficeRelationRealRepository.java | 16 ++++++++-------- ...sOfficeRelationRepositoryIntegrationTest.java | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRbacRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRbacRepository.java index e687bdcb..f45fce1a 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRbacRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRbacRepository.java @@ -48,16 +48,16 @@ public interface HsOfficeRelationRbacRepository extends Repository findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl( diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRealRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRealRepository.java index 5a2249d7..8d2e7e90 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRealRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRealRepository.java @@ -48,16 +48,16 @@ public interface HsOfficeRelationRealRepository extends Repository findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl( diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRepositoryIntegrationTest.java index 580bd1a8..aec09e1d 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRepositoryIntegrationTest.java @@ -78,7 +78,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea @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) + null, HsOfficeRelationType.PARTNER, null, "%Second%", null) .stream().reduce(Reducer::toSingleElement).orElseThrow().getUuid(); context("superuser-alex@hostsharing.net", "hs_office.relation#" + relationUuid + ":AGENT"); -- 2.39.5 From b0bfb0683317f81fa20a9e8e6357478a5c899cf5 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Sun, 29 Dec 2024 11:09:05 +0100 Subject: [PATCH 07/13] improve cas-curl, especially help texts with examples --- bin/cas-curl | 93 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 74 insertions(+), 19 deletions(-) diff --git a/bin/cas-curl b/bin/cas-curl index 6bf351e0..9f6edb87 100755 --- a/bin/cas-curl +++ b/bin/cas-curl @@ -3,19 +3,21 @@ if [ "$#" -eq 0 ] || [ "$1" == "help" ] || [ "$1" == "--help" ] || [ "$1" == "-h" ]; then cat <> [parameters] + usage: $0 [--trace] [--show-password] <> [parameters] commands: EOF - grep '") ''# ' $0 + # filters out help texts (marked with ## and following lines with #) from the commands itself + # (the '' makes sure that this line is not found, just the lines with actual help texts) + sed -n '/#''#/ {s/#''#//; p; :a; n; /^[[:space:]]*#/!b; s/^[[:space:]]*#//; p; ba}' $0 exit fi -export HSADMINNG_CAS_ASSUME_HEADER -if [ -f ~/.cas-curl-assume ]; then - HSADMINNG_CAS_ASSUME="$(cat ~/.cas-curl-assume)" +if [ "$2" == "--show-password" ]; then + HSADMINNG_CAS_SHOW_PASSWORD=yes + shift else - HSADMINNG_CAS_ASSUME= + HSADMINNG_CAS_SHOW_PASSWORD= fi if [ "$1" == "--trace" ]; then @@ -40,6 +42,13 @@ else } fi +export HSADMINNG_CAS_ASSUME_HEADER +if [ -f ~/.cas-curl-assume ]; then + HSADMINNG_CAS_ASSUME="$(cat ~/.cas-curl-assume)" +else + HSADMINNG_CAS_ASSUME= +fi + if [ -z "$HSADMINNG_CAS_LOGIN" ] || [ -z "$HSADMINNG_CAS_VALIDATE" ] || \ [ -z "$HSADMINNG_CAS_SERVICE_ID" ]; then cat >&2 <>\" \ + -d \"username=$HSADMINNG_CAS_USERNAME&password=$HSADMINNG_CAS_PASSWORD_DISPLAY\" \ $HSADMINNG_CAS_LOGIN -o ~/.cas-login-tgt.response -D -" HSADMINNG_CAS_TGT=`curl --fail-with-body -s -i -X POST \ -H 'Content-Type: application/x-www-form-urlencoded' \ @@ -126,45 +141,85 @@ function casValidate() { } case "${1,,}" in - "login") # reads username+password and fetches ticket granting ticket (bypasses HSADMINNG_CAS_USERNAME+HSADMINNG_CAS_PASSWORD) + + # -- generic commands -------------------------------------------------------------------------- + + "env") ## prints all related HSADMINNG_CAS_... environment variables; use '--show-password' to show the password as well + # example: cas-curl env --show-password + echo "HSADMINNG_CAS_LOGIN: $HSADMINNG_CAS_LOGIN" + echo "HSADMINNG_CAS_VALIDATE: $HSADMINNG_CAS_VALIDATE" + echo "HSADMINNG_CAS_USERNAME: $HSADMINNG_CAS_USERNAME" + if [ "$2" == "--show-password" ]; then + echo "HSADMINNG_CAS_PASSWORD: $HSADMINNG_CAS_PASSWORD" + elif [ -z "$HSADMINNG_CAS_PASSWORD" ]; then + echo "HSADMINNG_CAS_PASSWORD: <>" + else + echo "HSADMINNG_CAS_PASSWORD: <