preparation for changing updatable columns #161
@ -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("contactUuid")
|
.withUpdatableColumns("anchorUuid", "holderUuid", "contactUuid")
|
||||||
.importEntityAlias("anchorPerson", HsOfficePersonRbacEntity.class, usingDefaultCase(),
|
.importEntityAlias("anchorPerson", HsOfficePersonRbacEntity.class, usingDefaultCase(),
|
||||||
dependsOnColumn("anchorUuid"),
|
dependsOnColumn("anchorUuid"),
|
||||||
directlyFetchedByDependsOnColumn(),
|
directlyFetchedByDependsOnColumn(),
|
||||||
|
@ -235,7 +235,7 @@ begin
|
|||||||
*/
|
*/
|
||||||
newColumns := 'new.' || replace(columnNames, ', ', ', new.');
|
newColumns := 'new.' || replace(columnNames, ', ', ', new.');
|
||||||
sql := format($sql$
|
sql := format($sql$
|
||||||
create function %1$s_instead_of_insert_tf()
|
create or replace function %1$s_instead_of_insert_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $f$
|
language plpgsql as $f$
|
||||||
declare
|
declare
|
||||||
@ -254,7 +254,7 @@ begin
|
|||||||
Creates an instead of insert trigger for the restricted view.
|
Creates an instead of insert trigger for the restricted view.
|
||||||
*/
|
*/
|
||||||
sql := format($sql$
|
sql := format($sql$
|
||||||
create trigger instead_of_insert_tg
|
create or replace trigger instead_of_insert_tg
|
||||||
instead of insert
|
instead of insert
|
||||||
on %1$s_rv
|
on %1$s_rv
|
||||||
for each row
|
for each row
|
||||||
@ -266,7 +266,7 @@ begin
|
|||||||
Instead of delete trigger function for the restricted view.
|
Instead of delete trigger function for the restricted view.
|
||||||
*/
|
*/
|
||||||
sql := format($sql$
|
sql := format($sql$
|
||||||
create function %1$s_instead_of_delete_tf()
|
create or replace function %1$s_instead_of_delete_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $f$
|
language plpgsql as $f$
|
||||||
begin
|
begin
|
||||||
@ -283,7 +283,7 @@ begin
|
|||||||
Creates an instead of delete trigger for the restricted view.
|
Creates an instead of delete trigger for the restricted view.
|
||||||
*/
|
*/
|
||||||
sql := format($sql$
|
sql := format($sql$
|
||||||
create trigger instead_of_delete_tg
|
create or replace trigger instead_of_delete_tg
|
||||||
instead of delete
|
instead of delete
|
||||||
on %1$s_rv
|
on %1$s_rv
|
||||||
for each row
|
for each row
|
||||||
@ -297,7 +297,7 @@ begin
|
|||||||
*/
|
*/
|
||||||
if columnUpdates is not null then
|
if columnUpdates is not null then
|
||||||
sql := format($sql$
|
sql := format($sql$
|
||||||
create function %1$s_instead_of_update_tf()
|
create or replace function %1$s_instead_of_update_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $f$
|
language plpgsql as $f$
|
||||||
begin
|
begin
|
||||||
@ -316,7 +316,7 @@ begin
|
|||||||
Creates an instead of delete trigger for the restricted view.
|
Creates an instead of delete trigger for the restricted view.
|
||||||
*/
|
*/
|
||||||
sql = format($sql$
|
sql = format($sql$
|
||||||
create trigger instead_of_update_tg
|
create or replace trigger instead_of_update_tg
|
||||||
instead of update
|
instead of update
|
||||||
on %1$s_rv
|
on %1$s_rv
|
||||||
for each row
|
for each row
|
||||||
|
@ -110,7 +110,7 @@ execute procedure hs_office.relation_build_rbac_system_after_insert_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset RolesGrantsAndPermissionsGenerator:hs-office-relation-rbac-update-trigger endDelimiter:--//
|
--changeset RolesGrantsAndPermissionsGenerator:hs-office-relation-rbac-update-trigger runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -124,7 +124,9 @@ create or replace procedure hs_office.relation_update_rbac_system(
|
|||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
|
|
||||||
if NEW.contactUuid is distinct from OLD.contactUuid then
|
if NEW.holderUuid is distinct from OLD.holderUuid
|
||||||
|
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;
|
||||||
@ -143,7 +145,7 @@ begin
|
|||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger update_rbac_system_after_update_tg
|
create or replace trigger update_rbac_system_after_update_tg
|
||||||
after update on hs_office.relation
|
after update on hs_office.relation
|
||||||
for each row
|
for each row
|
||||||
execute procedure hs_office.relation_update_rbac_system_after_update_tf();
|
execute procedure hs_office.relation_update_rbac_system_after_update_tf();
|
||||||
@ -241,20 +243,22 @@ call rbac.generateRbacIdentityViewFromProjection('hs_office.relation',
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset RbacRestrictedViewGenerator:hs-office-relation-rbac-RESTRICTED-VIEW endDelimiter:--//
|
--changeset RbacRestrictedViewGenerator:hs-office-relation-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call rbac.generateRbacRestrictedView('hs_office.relation',
|
call rbac.generateRbacRestrictedView('hs_office.relation',
|
||||||
$orderBy$
|
$orderBy$
|
||||||
(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$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset RbacRbacSystemRebuildGenerator:hs-office-relation-rbac-rebuild endDelimiter:--//
|
--changeset RbacRbacSystemRebuildGenerator:hs-office-relation-rbac-rebuild runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
-- HOWTO: Rebuild RBAC-system for table hs_office.relation after changing its RBAC specification.
|
-- HOWTO: Rebuild RBAC-system for table hs_office.relation after changing its RBAC specification.
|
||||||
@ -305,3 +309,17 @@ 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;
|
||||||
|
--//
|
||||||
|
@ -28,6 +28,7 @@ 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;
|
||||||
|
|
||||||
@ -283,7 +284,44 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
result.returnedValue(),
|
result.returnedValue(),
|
||||||
"hs_office.contact#fifthcontact:ADMIN");
|
"hs_office.contact#fifthcontact:ADMIN");
|
||||||
|
|
||||||
relationRbacRepo.deleteByUuid(givenRelation.getUuid());
|
// 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
|
||||||
@ -296,13 +334,17 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
givenRelation,
|
givenRelation,
|
||||||
"hs_office.relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerAnita:AGENT");
|
"hs_office.relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerAnita:AGENT");
|
||||||
assertThatRelationActuallyInDatabase(givenRelation);
|
assertThatRelationActuallyInDatabase(givenRelation);
|
||||||
|
final var givenContact = contactRealRepo.findContactByOptionalCaptionLike("sixth contact")
|
||||||
|
.stream()
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context(
|
context(
|
||||||
"superuser-alex@hostsharing.net",
|
"superuser-alex@hostsharing.net",
|
||||||
"hs_office.relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerAnita:AGENT");
|
"hs_office.relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerAnita:AGENT");
|
||||||
givenRelation.setContact(null);
|
givenRelation.setContact(givenContact);
|
||||||
return relationRbacRepo.save(givenRelation);
|
return relationRbacRepo.save(givenRelation);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -12129,8 +12129,8 @@ INSERT INTO hs_office.debitor (uuid, version, debitornumbersuffix, debitorreluui
|
|||||||
-- Data for Name: membership; Type: TABLE DATA; Schema: hs_office; Owner: postgres
|
-- Data for Name: membership; Type: TABLE DATA; Schema: hs_office; Owner: postgres
|
||||||
--
|
--
|
||||||
|
|
||||||
INSERT INTO hs_office.membership (uuid, version, partneruuid, membernumbersuffix, validity, status, membershipfeebillable) VALUES ('4330e211-e36c-45ec-9332-f7593ff42811', 0, 'c27d1b0c-7e43-4b64-ae69-4317f51023ba', '01', '[2022-10-01,)', 'ACTIVE', true);
|
INSERT INTO hs_office.membership (uuid, version, partneruuid, membernumbersuffix, validity, status, membershipfeebillable) VALUES ('4330e211-e36c-45ec-9332-f7593ff42811', 0, 'c27d1b0c-7e43-4b64-ae69-4317f51023ba', '01', '[2022-10-01,2025-01-01)', 'ACTIVE', true);
|
||||||
INSERT INTO hs_office.membership (uuid, version, partneruuid, membernumbersuffix, validity, status, membershipfeebillable) VALUES ('bed3c145-aa55-425f-9211-be9f5e9f4ebe', 0, '11583dae-da71-4786-a61d-d70f51ce988e', '02', '[2022-10-01,)', 'ACTIVE', true);
|
INSERT INTO hs_office.membership (uuid, version, partneruuid, membernumbersuffix, validity, status, membershipfeebillable) VALUES ('bed3c145-aa55-425f-9211-be9f5e9f4ebe', 0, '11583dae-da71-4786-a61d-d70f51ce988e', '02', '[2022-10-01,2026-01-01)', 'ACTIVE', true);
|
||||||
INSERT INTO hs_office.membership (uuid, version, partneruuid, membernumbersuffix, validity, status, membershipfeebillable) VALUES ('a42d61c5-7dad-4379-9dd9-39a8d21ddc32', 0, '7fe704c0-2e54-463e-891e-533f0274da76', '03', '[2022-10-01,)', 'ACTIVE', true);
|
INSERT INTO hs_office.membership (uuid, version, partneruuid, membernumbersuffix, validity, status, membershipfeebillable) VALUES ('a42d61c5-7dad-4379-9dd9-39a8d21ddc32', 0, '7fe704c0-2e54-463e-891e-533f0274da76', '03', '[2022-10-01,)', 'ACTIVE', true);
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user