hs.hsadmin.ng/src/main/resources/db/changelog/223-hs-office-relationship-rbac.sql
2024-03-15 18:41:02 +01:00

278 lines
10 KiB
PL/PgSQL

--liquibase formatted sql
-- This code generated was by RbacViewPostgresGenerator at 2024-03-15T17:17:00.864301165.
-- ============================================================================
--changeset hs-office-relationship-rbac-OBJECT:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call generateRelatedRbacObject('hs_office_relationship');
--//
-- ============================================================================
--changeset hs-office-relationship-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call generateRbacRoleDescriptors('hsOfficeRelationship', 'hs_office_relationship');
--//
-- ============================================================================
--changeset hs-office-relationship-rbac-insert-trigger:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
*/
create or replace procedure buildRbacSystemForHsOfficeRelationship(
NEW hs_office_relationship
)
language plpgsql as $$
declare
newHolderPerson hs_office_person;
newAnchorPerson hs_office_person;
newContact hs_office_contact;
begin
call enterTriggerForObjectUuid(NEW.uuid);
select * from hs_office_person as p where p.uuid = NEW.relHolderUuid INTO newHolderPerson;
assert newHolderPerson.uuid is not null, format('newHolderPerson must not be null for NEW.relHolderUuid = %s', NEW.relHolderUuid);
select * from hs_office_person as p where p.uuid = NEW.relAnchorUuid INTO newAnchorPerson;
assert newAnchorPerson.uuid is not null, format('newAnchorPerson must not be null for NEW.relAnchorUuid = %s', NEW.relAnchorUuid);
select * from hs_office_contact as c where c.uuid = NEW.contactUuid INTO newContact;
assert newContact.uuid is not null, format('newContact must not be null for NEW.contactUuid = %s', NEW.contactUuid);
perform createRoleWithGrants(
hsOfficeRelationshipOwner(NEW),
permissions => array['DELETE'],
incomingSuperRoles => array[globalAdmin()],
userUuids => array[currentUserUuid()]
);
perform createRoleWithGrants(
hsOfficeRelationshipAdmin(NEW),
permissions => array['UPDATE'],
incomingSuperRoles => array[
hsOfficeRelationshipOwner(NEW),
hsOfficePersonAdmin(newAnchorPerson)]
);
perform createRoleWithGrants(
hsOfficeRelationshipAgent(NEW),
incomingSuperRoles => array[
hsOfficePersonAdmin(newHolderPerson),
hsOfficeRelationshipAdmin(NEW)]
);
perform createRoleWithGrants(
hsOfficeRelationshipTenant(NEW),
permissions => array['SELECT'],
incomingSuperRoles => array[
hsOfficeRelationshipAgent(NEW),
hsOfficeContactAdmin(newContact),
hsOfficePersonAdmin(newHolderPerson)],
outgoingSubRoles => array[
hsOfficeContactReferrer(newContact),
hsOfficePersonReferrer(newHolderPerson),
hsOfficePersonReferrer(newAnchorPerson)]
);
call leaveTriggerForObjectUuid(NEW.uuid);
end; $$;
/*
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_relationship row.
*/
create or replace function insertTriggerForHsOfficeRelationship_tf()
returns trigger
language plpgsql
strict as $$
begin
call buildRbacSystemForHsOfficeRelationship(NEW);
return NEW;
end; $$;
create trigger insertTriggerForHsOfficeRelationship_tg
after insert on hs_office_relationship
for each row
execute procedure insertTriggerForHsOfficeRelationship_tf();
--//
-- ============================================================================
--changeset hs-office-relationship-rbac-update-trigger:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
*/
create or replace procedure updateRbacRulesForHsOfficeRelationship(
OLD hs_office_relationship,
NEW hs_office_relationship
)
language plpgsql as $$
declare
oldHolderPerson hs_office_person;
newHolderPerson hs_office_person;
oldAnchorPerson hs_office_person;
newAnchorPerson hs_office_person;
oldContact hs_office_contact;
newContact hs_office_contact;
begin
call enterTriggerForObjectUuid(NEW.uuid);
select * from hs_office_person as p where p.uuid = OLD.relHolderUuid INTO oldHolderPerson;
assert oldHolderPerson.uuid is not null, format('oldHolderPerson must not be null for OLD.relHolderUuid = %s', OLD.relHolderUuid);
select * from hs_office_person as p where p.uuid = NEW.relHolderUuid INTO newHolderPerson;
assert newHolderPerson.uuid is not null, format('newHolderPerson must not be null for NEW.relHolderUuid = %s', NEW.relHolderUuid);
select * from hs_office_person as p where p.uuid = OLD.relAnchorUuid INTO oldAnchorPerson;
assert oldAnchorPerson.uuid is not null, format('oldAnchorPerson must not be null for OLD.relAnchorUuid = %s', OLD.relAnchorUuid);
select * from hs_office_person as p where p.uuid = NEW.relAnchorUuid INTO newAnchorPerson;
assert newAnchorPerson.uuid is not null, format('newAnchorPerson must not be null for NEW.relAnchorUuid = %s', NEW.relAnchorUuid);
select * from hs_office_contact as c where c.uuid = OLD.contactUuid INTO oldContact;
assert oldContact.uuid is not null, format('oldContact must not be null for OLD.contactUuid = %s', OLD.contactUuid);
select * from hs_office_contact as c where c.uuid = NEW.contactUuid INTO newContact;
assert newContact.uuid is not null, format('newContact must not be null for NEW.contactUuid = %s', NEW.contactUuid);
if NEW.contactUuid <> OLD.contactUuid then
call revokeRoleFromRole(hsOfficeRelationshipTenant(OLD), hsOfficeContactAdmin(oldContact));
call grantRoleToRole(hsOfficeRelationshipTenant(NEW), hsOfficeContactAdmin(newContact));
call revokeRoleFromRole(hsOfficeContactReferrer(oldContact), hsOfficeRelationshipTenant(OLD));
call grantRoleToRole(hsOfficeContactReferrer(newContact), hsOfficeRelationshipTenant(NEW));
end if;
call leaveTriggerForObjectUuid(NEW.uuid);
end; $$;
/*
AFTER INSERT TRIGGER to re-wire the grant structure for a new hs_office_relationship row.
*/
create or replace function updateTriggerForHsOfficeRelationship_tf()
returns trigger
language plpgsql
strict as $$
begin
call updateRbacRulesForHsOfficeRelationship(OLD, NEW);
return NEW;
end; $$;
create trigger updateTriggerForHsOfficeRelationship_tg
after update on hs_office_relationship
for each row
execute procedure updateTriggerForHsOfficeRelationship_tf();
--//
-- ============================================================================
--changeset hs-office-relationship-rbac-INSERT:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Creates INSERT INTO hs_office_relationship permissions for the related hs_office_person rows.
*/
do language plpgsql $$
declare
row hs_office_person;
permissionUuid uuid;
roleUuid uuid;
begin
call defineContext('create INSERT INTO hs_office_relationship permissions for the related hs_office_person rows');
FOR row IN SELECT * FROM hs_office_person
LOOP
roleUuid := findRoleId(hsOfficePersonAdmin(row));
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_relationship');
call grantPermissionToRole(permissionUuid, roleUuid);
END LOOP;
END;
$$;
/**
Adds hs_office_relationship INSERT permission to specified role of new hs_office_person rows.
*/
create or replace function hs_office_relationship_hs_office_person_insert_tf()
returns trigger
language plpgsql
strict as $$
begin
call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'hs_office_relationship'),
hsOfficePersonAdmin(NEW));
return NEW;
end; $$;
create trigger z_hs_office_relationship_hs_office_person_insert_tg
after insert on hs_office_person
for each row
execute procedure hs_office_relationship_hs_office_person_insert_tf();
/**
Checks if the user or assumed roles are allowed to insert a row to hs_office_relationship.
*/
create or replace function hs_office_relationship_insert_permission_missing_tf()
returns trigger
language plpgsql as $$
begin
if ( not hasInsertPermission(
( SELECT anchorPerson.uuid FROM
(select * from hs_office_person as p where p.uuid = NEW.relAnchorUuid) AS anchorPerson
), 'INSERT', 'hs_office_relationship') ) then
raise exception
'[403] insert into hs_office_relationship not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids();
end if;
return NEW;
end; $$;
create trigger hs_office_relationship_insert_permission_check_tg
before insert on hs_office_relationship
for each row
execute procedure hs_office_relationship_insert_permission_missing_tf();
--//
-- ============================================================================
--changeset hs-office-relationship-rbac-IDENTITY-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call generateRbacIdentityViewFromProjection('hs_office_relationship', $idName$
(select idName from hs_office_person_iv p where p.uuid = relAnchorUuid)
|| '-with-' || target.relType || '-'
|| (select idName from hs_office_person_iv p where p.uuid = relHolderUuid)
$idName$);
--//
-- ============================================================================
--changeset hs-office-relationship-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call generateRbacRestrictedView('hs_office_relationship',
$orderBy$
(select idName from hs_office_person_iv p where p.uuid = target.relHolderUuid)
$orderBy$,
$updates$
contactUuid = new.contactUuid
$updates$);
--//