revert updatable columns for relation and code-cleanup

This commit is contained in:
Michael Hoennig 2025-03-03 09:13:40 +01:00
parent 7a2b1b6280
commit 2a2398441d
4 changed files with 32 additions and 89 deletions

View File

@ -51,7 +51,7 @@ public class HsOfficeRelationRbacEntity extends HsOfficeRelation {
""")) """))
.withRestrictedViewOrderBy(SQL.expression( .withRestrictedViewOrderBy(SQL.expression(
"(select idName from hs_office.person_iv p where p.uuid = target.holderUuid)")) "(select idName from hs_office.person_iv p where p.uuid = target.holderUuid)"))
.withUpdatableColumns("anchorUuid", "holderUuid", "contactUuid") .withUpdatableColumns("contactUuid")
.importEntityAlias("anchorPerson", HsOfficePersonRbacEntity.class, usingDefaultCase(), .importEntityAlias("anchorPerson", HsOfficePersonRbacEntity.class, usingDefaultCase(),
dependsOnColumn("anchorUuid"), dependsOnColumn("anchorUuid"),
directlyFetchedByDependsOnColumn(), directlyFetchedByDependsOnColumn(),

View File

@ -124,9 +124,7 @@ create or replace procedure hs_office.relation_update_rbac_system(
language plpgsql as $$ language plpgsql as $$
begin begin
if NEW.holderUuid is distinct from OLD.holderUuid if NEW.contactUuid is distinct from OLD.contactUuid then
or NEW.anchorUuid is distinct from OLD.anchorUuid
or NEW.contactUuid is distinct from OLD.contactUuid then
delete from rbac.grant g where g.grantedbytriggerof = OLD.uuid; delete from rbac.grant g where g.grantedbytriggerof = OLD.uuid;
call hs_office.relation_build_rbac_system(NEW); call hs_office.relation_build_rbac_system(NEW);
end if; end if;
@ -250,8 +248,6 @@ call rbac.generateRbacRestrictedView('hs_office.relation',
(select idName from hs_office.person_iv p where p.uuid = target.holderUuid) (select idName from hs_office.person_iv p where p.uuid = target.holderUuid)
$orderBy$, $orderBy$,
$updates$ $updates$
anchorUuid = new.anchorUuid,
holderUuid = new.holderUuid,
contactUuid = new.contactUuid contactUuid = new.contactUuid
$updates$); $updates$);
--// --//
@ -309,17 +305,3 @@ END;
$$; $$;
--// --//
-- ============================================================================
--changeset RbacRbacSystemRebuildGenerator:hs-office-relation-rbac-actually-rebuild runOnChange:true validCheckSum:ANY endDelimiter:--//
-- ----------------------------------------------------------------------------
begin transaction;
call base.defineContext(
're-creating RBAC for table hs_office.relation',
null,
'superuser-alex@hostsharing.net' -- FIXME: use env-var
);
call hs_office.relation_rebuild_rbac_system();
commit;
--//

View File

@ -45,13 +45,13 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
Context context; Context context;
@Autowired @Autowired
HsOfficeRelationRealRepository relationrealRepo; HsOfficeRelationRealRepository realRelationRepo;
@Autowired @Autowired
HsOfficePersonRealRepository personRepo; HsOfficePersonRealRepository realPersonRepo;
@Autowired @Autowired
HsOfficeContactRealRepository contactrealRepo; HsOfficeContactRealRepository realContactRepo;
@Autowired @Autowired
JpaAttempt jpaAttempt; JpaAttempt jpaAttempt;
@ -64,7 +64,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
// given // given
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0); final var givenPerson = realPersonRepo.findPersonByOptionalNameLike("Hostsharing eG").getFirst();
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
@ -122,7 +122,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
// given // given
context.define("contact-admin@firstcontact.example.com"); context.define("contact-admin@firstcontact.example.com");
final var givenPerson = personRepo.findPersonByOptionalNameLike("First GmbH").get(0); final var givenPerson = realPersonRepo.findPersonByOptionalNameLike("First GmbH").getFirst();
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
@ -229,9 +229,9 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
void globalAdmin_withoutAssumedRole_canAddRelationWithHolderUuidAndContactUuid() { void globalAdmin_withoutAssumedRole_canAddRelationWithHolderUuidAndContactUuid() {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Third").get(0); final var givenAnchorPerson = realPersonRepo.findPersonByOptionalNameLike("Third").getFirst();
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Paul").get(0); final var givenHolderPerson = realPersonRepo.findPersonByOptionalNameLike("Paul").getFirst();
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("second").get(0); final var givenContact = realContactRepo.findContactByOptionalCaptionLike("second").getFirst();
final var location = RestAssured // @formatter:off final var location = RestAssured // @formatter:off
.given() .given()
@ -276,7 +276,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
void globalAdmin_withoutAssumedRole_canAddRelationWithHolderAndContactData() { void globalAdmin_withoutAssumedRole_canAddRelationWithHolderAndContactData() {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Third").get(0); final var givenAnchorPerson = realPersonRepo.findPersonByOptionalNameLike("Third").getFirst();
final var location = RestAssured // @formatter:off final var location = RestAssured // @formatter:off
.given() .given()
@ -343,8 +343,8 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenAnchorPersonUuid = GIVEN_NON_EXISTING_HOLDER_PERSON_UUID; final var givenAnchorPersonUuid = GIVEN_NON_EXISTING_HOLDER_PERSON_UUID;
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Smith").get(0); final var givenHolderPerson = realPersonRepo.findPersonByOptionalNameLike("Smith").getFirst();
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth").get(0); final var givenContact = realContactRepo.findContactByOptionalCaptionLike("fourth").getFirst();
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
@ -375,8 +375,8 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
void globalAdmin_canNotAddRelation_ifHolderPersonDoesNotExist() { void globalAdmin_canNotAddRelation_ifHolderPersonDoesNotExist() {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Third").get(0); final var givenAnchorPerson = realPersonRepo.findPersonByOptionalNameLike("Third").getFirst();
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth").get(0); final var givenContact = realContactRepo.findContactByOptionalCaptionLike("fourth").getFirst();
final var location = RestAssured // @formatter:off final var location = RestAssured // @formatter:off
.given() .given()
@ -407,8 +407,8 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
void globalAdmin_canNotAddRelation_ifContactDoesNotExist() { void globalAdmin_canNotAddRelation_ifContactDoesNotExist() {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Third").get(0); final var givenAnchorPerson = realPersonRepo.findPersonByOptionalNameLike("Third").getFirst();
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Paul").get(0); final var givenHolderPerson = realPersonRepo.findPersonByOptionalNameLike("Paul").getFirst();
final var givenContactUuid = UUID.fromString("00000000-0000-0000-0000-000000000000"); final var givenContactUuid = UUID.fromString("00000000-0000-0000-0000-000000000000");
final var location = RestAssured // @formatter:off final var location = RestAssured // @formatter:off
@ -506,9 +506,9 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
private HsOfficeRelation findRelation( private HsOfficeRelation findRelation(
final String anchorPersonName, final String anchorPersonName,
final String holderPersoneName) { final String holderPersoneName) {
final var anchorPersonUuid = personRepo.findPersonByOptionalNameLike(anchorPersonName).get(0).getUuid(); final var anchorPersonUuid = realPersonRepo.findPersonByOptionalNameLike(anchorPersonName).getFirst().getUuid();
final var holderPersonUuid = personRepo.findPersonByOptionalNameLike(holderPersoneName).get(0).getUuid(); final var holderPersonUuid = realPersonRepo.findPersonByOptionalNameLike(holderPersoneName).getFirst().getUuid();
final var givenRelation = relationrealRepo final var givenRelation = realRelationRepo
.findRelationRelatedToPersonUuid(anchorPersonUuid) .findRelationRelatedToPersonUuid(anchorPersonUuid)
.stream() .stream()
.filter(r -> r.getHolder().getUuid().equals(holderPersonUuid)) .filter(r -> r.getHolder().getUuid().equals(holderPersonUuid))
@ -525,7 +525,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenRelation = givenSomeTemporaryRelationBessler(); final var givenRelation = givenSomeTemporaryRelationBessler();
assertThat(givenRelation.getContact().getCaption()).isEqualTo("seventh contact"); assertThat(givenRelation.getContact().getCaption()).isEqualTo("seventh contact");
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth").get(0); final var givenContact = realContactRepo.findContactByOptionalCaptionLike("fourth").getFirst();
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
@ -551,7 +551,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
// finally, the relation is actually updated // finally, the relation is actually updated
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
assertThat(relationrealRepo.findByUuid(givenRelation.getUuid())).isPresent().get() assertThat(realRelationRepo.findByUuid(givenRelation.getUuid())).isPresent().get()
.matches(rel -> { .matches(rel -> {
assertThat(rel.getAnchor().getTradeName()).contains("Bessler"); assertThat(rel.getAnchor().getTradeName()).contains("Bessler");
assertThat(rel.getHolder().getFamilyName()).contains("Winkler"); assertThat(rel.getHolder().getFamilyName()).contains("Winkler");
@ -580,7 +580,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
.statusCode(204); // @formatter:on .statusCode(204); // @formatter:on
// then the given relation is gone // then the given relation is gone
assertThat(relationrealRepo.findByUuid(givenRelation.getUuid())).isEmpty(); assertThat(realRelationRepo.findByUuid(givenRelation.getUuid())).isEmpty();
} }
@Test @Test
@ -599,7 +599,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
.statusCode(403); // @formatter:on .statusCode(403); // @formatter:on
// then the given relation is still there // then the given relation is still there
assertThat(relationrealRepo.findByUuid(givenRelation.getUuid())).isNotEmpty(); assertThat(realRelationRepo.findByUuid(givenRelation.getUuid())).isNotEmpty();
} }
@Test @Test
@ -618,16 +618,16 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
.statusCode(404); // @formatter:on .statusCode(404); // @formatter:on
// then the given relation is still there // then the given relation is still there
assertThat(relationrealRepo.findByUuid(givenRelation.getUuid())).isNotEmpty(); assertThat(realRelationRepo.findByUuid(givenRelation.getUuid())).isNotEmpty();
} }
} }
private HsOfficeRelation givenSomeTemporaryRelationBessler() { private HsOfficeRelation givenSomeTemporaryRelationBessler() {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); final var givenAnchorPerson = realPersonRepo.findPersonByOptionalNameLike("Erben Bessler").getFirst();
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Winkler").get(0); final var givenHolderPerson = realPersonRepo.findPersonByOptionalNameLike("Winkler").getFirst();
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("seventh contact").get(0); final var givenContact = realContactRepo.findContactByOptionalCaptionLike("seventh contact").getFirst();
final var newRelation = HsOfficeRelationRealEntity.builder() final var newRelation = HsOfficeRelationRealEntity.builder()
.type(HsOfficeRelationType.REPRESENTATIVE) .type(HsOfficeRelationType.REPRESENTATIVE)
.anchor(givenAnchorPerson) .anchor(givenAnchorPerson)
@ -635,7 +635,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
.contact(givenContact) .contact(givenContact)
.build(); .build();
assertThat(toCleanup(relationrealRepo.save(newRelation))).isEqualTo(newRelation); assertThat(toCleanup(realRelationRepo.save(newRelation))).isEqualTo(newRelation);
return newRelation; return newRelation;
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();

View File

@ -28,7 +28,6 @@ import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.NATU
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.UNINCORPORATED_FIRM; import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.UNINCORPORATED_FIRM;
import static net.hostsharing.hsadminng.rbac.grant.RawRbacGrantEntity.distinctGrantDisplaysOf; import static net.hostsharing.hsadminng.rbac.grant.RawRbacGrantEntity.distinctGrantDisplaysOf;
import static net.hostsharing.hsadminng.rbac.role.RawRbacRoleEntity.distinctRoleNamesOf; import static net.hostsharing.hsadminng.rbac.role.RawRbacRoleEntity.distinctRoleNamesOf;
import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.ADMIN;
import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt; 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;
@ -284,44 +283,6 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
result.returnedValue(), result.returnedValue(),
"hs_office.contact#fifthcontact:ADMIN"); "hs_office.contact#fifthcontact:ADMIN");
// FIXME relationRbacRepo.deleteByUuid(givenRelation.getUuid());
}
@Test
public void hostsharingAdmin_withoutAssumedRole_canUpdateHolderOfArbitraryRelation() {
// given
context("superuser-alex@hostsharing.net");
final var givenRelation = givenSomeTemporaryRelationBessler(
"Bert", "fifth contact");
final var oldHolderPerson = givenRelation.getHolder();
final var newHolderPerson = personRepo.findPersonByOptionalNameLike("Paul").getFirst();
assertThatRelationActuallyInDatabase(givenRelation);
assertThatRelationIsVisibleForUserWithRole(
givenRelation,
givenRelation.getHolder().roleId(ADMIN));
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
givenRelation.setHolder(newHolderPerson);
return toCleanup(relationRbacRepo.save(givenRelation).load());
});
// then
result.assertSuccessful();
assertThat(result.returnedValue().getHolder().getGivenName()).isEqualTo("Paul");
assertThatRelationIsVisibleForUserWithRole(
result.returnedValue(),
"rbac.global#global:ADMIN");
assertThatRelationIsVisibleForUserWithRole(
result.returnedValue(),
newHolderPerson.roleId(ADMIN));
assertThatRelationIsNotVisibleForUserWithRole(
result.returnedValue(),
oldHolderPerson.roleId(ADMIN));
// FIXME: relationRbacRepo.deleteByUuid(givenRelation.getUuid());
} }
@Test @Test
@ -497,9 +458,9 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
private HsOfficeRelationRbacEntity givenSomeTemporaryRelationBessler(final String holderPerson, final String contact) { private HsOfficeRelationRbacEntity givenSomeTemporaryRelationBessler(final String holderPerson, final String contact) {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
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").getFirst();
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0); final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).getFirst();
final var givenContact = contactRealRepo.findContactByOptionalCaptionLike(contact).get(0); final var givenContact = contactRealRepo.findContactByOptionalCaptionLike(contact).getFirst();
final var newRelation = HsOfficeRelationRbacEntity.builder() final var newRelation = HsOfficeRelationRbacEntity.builder()
.type(HsOfficeRelationType.REPRESENTATIVE) .type(HsOfficeRelationType.REPRESENTATIVE)
.anchor(givenAnchorPerson) .anchor(givenAnchorPerson)