new handcoded baseline for multiple insert permission grants

This commit is contained in:
Michael Hoennig 2024-04-26 10:27:12 +02:00
parent 4dafa031a0
commit 69b6baaeb3
2 changed files with 64 additions and 56 deletions

View File

@ -98,78 +98,79 @@ execute procedure insertTriggerForHsBookingItem_tf();
-- ============================================================================ -- ============================================================================
--changeset hs-booking-item-rbac-INSERT:1 endDelimiter:--// --changeset hs-booking-item-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
-- granting INSERT permission to hs_office_relation ----------------------------
/* /*
Creates INSERT INTO hs_booking_item permissions for the related hs_office_relation rows. Grants INSERT INTO hs_booking_item permissions to specified role of pre-existing hs_office_relation rows.
*/ */
do language plpgsql $$ do language plpgsql $$
declare declare
row hs_office_relation; row hs_office_relation;
begin begin
call defineContext('create INSERT INTO hs_booking_item permissions for the related hs_office_relation rows'); call defineContext('create INSERT INTO hs_booking_item permissions for pre-exising hs_office_relation rows');
FOR row IN SELECT * FROM hs_office_relation FOR row IN SELECT * FROM hs_office_relation
WHERE type = 'DEBITOR' WHERE type = 'DEBITOR'
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'hs_booking_item'), createPermission(row.uuid, 'INSERT', 'hs_booking_item'),
hsOfficeRelationADMIN(row)); hsOfficeRelationADMIN(row));
END LOOP; END LOOP;
END; end;
$$; $$;
/** /**
Adds hs_booking_item INSERT permission to specified role of new hs_office_relation rows. Grants hs_booking_item INSERT permission to specified role of new hs_office_relation rows.
*/ */
create or replace function hs_booking_item_hs_office_relation_insert_tf() create or replace function new_hs_booking_item_grants_insert_to_hs_office_relation_tf()
returns trigger returns trigger
language plpgsql language plpgsql
strict as $$ strict as $$
begin begin
if NEW.type = 'DEBITOR' then if NEW.type = 'DEBITOR' then
call grantPermissionToRole( call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'hs_booking_item'), createPermission(NEW.uuid, 'INSERT', 'hs_booking_item'),
hsOfficeRelationADMIN(NEW)); hsOfficeRelationADMIN(NEW));
end if; end if;
return NEW; return NEW;
end; $$; end; $$;
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist -- z_... is to put it at the end of after insert triggers, to make sure the roles exist
create trigger z_hs_booking_item_hs_office_relation_insert_tg create trigger z_new_hs_booking_item_grants_insert_to_hs_office_relation_tg
after insert on hs_office_relation after insert on hs_office_relation
for each row for each row
execute procedure hs_booking_item_hs_office_relation_insert_tf(); execute procedure new_hs_booking_item_grants_insert_to_hs_office_relation_tf();
-- ============================================================================
--changeset hs_booking_item-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/** /**
Checks if the user or assumed roles are allowed to insert a row to hs_booking_item, Checks if the user respectively the assumed roles are allowed to insert a row to hs_booking_item.
where the check is performed by an indirect role.
An indirect role is a role which depends on an object uuid which is not a direct foreign key
of the source entity, but needs to be fetched via joined tables.
*/ */
create or replace function hs_booking_item_insert_permission_check_tf() create or replace function hs_booking_item_insert_permission_check_tf()
returns trigger returns trigger
language plpgsql as $$ language plpgsql as $$
declare declare
superRoleObjectUuid uuid; superObjectUuid uuid;
begin begin
superRoleObjectUuid := (SELECT debitorRel.uuid -- check INSERT permission via indirect foreign key: NEW.debitorUuid
FROM hs_office_relation debitorRel superObjectUuid := (SELECT debitorRel.uuid
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid FROM hs_office_relation debitorRel
WHERE debitor.uuid = NEW.debitorUuid JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
); WHERE debitor.uuid = NEW.debitorUuid
assert superRoleObjectUuid is not null, 'superRoleObjectUuid must not be null'; );
assert superObjectUuid is not null, 'object uuid fetched depending on hs_booking_item.debitorUuid must not be null, also check fetchSql in RBAC DSL';
if ( not hasInsertPermission(superRoleObjectUuid, 'hs_booking_item') ) then if hasInsertPermission(superObjectUuid, 'hs_booking_item') then
raise exception return NEW;
'[403] insert into hs_booking_item not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids();
end if; end if;
return NEW;
raise exception '[403] insert into hs_booking_item not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids();
end; $$; end; $$;
create trigger hs_booking_item_insert_permission_check_tg create trigger hs_booking_item_insert_permission_check_tg
@ -178,18 +179,20 @@ create trigger hs_booking_item_insert_permission_check_tg
execute procedure hs_booking_item_insert_permission_check_tf(); execute procedure hs_booking_item_insert_permission_check_tf();
--// --//
-- ============================================================================ -- ============================================================================
--changeset hs-booking-item-rbac-IDENTITY-VIEW:1 endDelimiter:--// --changeset hs-booking-item-rbac-IDENTITY-VIEW:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call generateRbacIdentityViewFromQuery('hs_booking_item', call generateRbacIdentityViewFromQuery('hs_booking_item',
$idName$ $idName$
SELECT bookingItem.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingItem.caption) as idName SELECT bookingItem.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingItem.caption) as idName
FROM hs_booking_item bookingItem FROM hs_booking_item bookingItem
JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingItem.debitorUuid JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingItem.debitorUuid
$idName$); $idName$);
--// --//
-- ============================================================================ -- ============================================================================
--changeset hs-booking-item-rbac-RESTRICTED-VIEW:1 endDelimiter:--// --changeset hs-booking-item-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------

View File

@ -100,16 +100,16 @@ execute procedure insertTriggerForHsHostingAsset_tf();
*/ */
do language plpgsql $$ do language plpgsql $$
declare declare
preExistingRow hs_booking_item; row hs_booking_item;
begin begin
call defineContext('create INSERT INTO hs_hosting_asset permissions for pre-exising hs_booking_item rows'); call defineContext('create INSERT INTO hs_hosting_asset permissions for pre-exising hs_booking_item rows');
FOR preExistingRow IN SELECT * FROM hs_booking_item FOR row IN SELECT * FROM hs_booking_item
-- unconditional for all rows in that table -- unconditional for all rows in that table
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(preExistingRow.uuid, 'INSERT', 'hs_hosting_asset'), createPermission(row.uuid, 'INSERT', 'hs_hosting_asset'),
hsBookingItemAGENT(preExistingRow)); hsBookingItemAGENT(row));
END LOOP; END LOOP;
end; end;
$$; $$;
@ -169,27 +169,31 @@ execute procedure new_hs_hosting_asset_grants_insert_to_hs_hosting_asset_tf();
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/** /**
Checks if the user or assumed roles are allowed to insert a row to hs_hosting_asset, Checks if the user respectively the assumed roles are allowed to insert a row to hs_hosting_asset.
where the check is performed by a direct role.
A direct role is a role depending on a foreign key directly available in the NEW row.
*/ */
create or replace function hs_hosting_asset_insert_permission_missing_tf() create or replace function hs_hosting_asset_insert_permission_check_tf()
returns trigger returns trigger
language plpgsql as $$ language plpgsql as $$
declare
superObjectUuid uuid;
begin begin
-- check INSERT permission via direct foreign key: NEW.bookingItemUuid
if NEW.type in ('CLOUD_SERVER', 'MANAGED_SERVER', 'MANAGED_WEBSPACE') and hasInsertPermission(NEW.bookingItemUuid, 'hs_hosting_asset') then
return NEW;
end if;
-- check INSERT permission via direct foreign key: NEW.parentAssetUuid
if NEW.type in ('MANAGED_WEBSPACE') and hasInsertPermission(NEW.parentAssetUuid, 'hs_hosting_asset') then
return NEW;
end if;
raise exception '[403] insert into hs_hosting_asset not allowed for current subjects % (%)', raise exception '[403] insert into hs_hosting_asset not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids(); currentSubjects(), currentSubjectsUuids();
end; $$; end; $$;
create trigger hs_hosting_asset_insert_permission_check_tg create trigger hs_hosting_asset_insert_permission_check_tg
before insert on hs_hosting_asset before insert on hs_hosting_asset
for each row for each row
when ( not ( execute procedure hs_hosting_asset_insert_permission_check_tf();
hasInsertPermission(NEW.bookingItemUuid, 'hs_hosting_asset') or
NEW.type in ('MANAGED_WEBSPACE') and hasInsertPermission(NEW.parentAssetUuid, 'hs_hosting_asset')
) )
execute procedure hs_hosting_asset_insert_permission_missing_tf();
--// --//
@ -197,14 +201,15 @@ create trigger hs_hosting_asset_insert_permission_check_tg
--changeset hs-hosting-asset-rbac-IDENTITY-VIEW:1 endDelimiter:--// --changeset hs-hosting-asset-rbac-IDENTITY-VIEW:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
call generateRbacIdentityViewFromQuery('hs_hosting_asset', call generateRbacIdentityViewFromQuery('hs_hosting_asset',
$idName$ $idName$
SELECT asset.uuid as uuid, bookingItemIV.idName || '-' || cleanIdentifier(asset.identifier) as idName SELECT asset.uuid as uuid, bookingItemIV.idName || '-' || cleanIdentifier(asset.identifier) as idName
FROM hs_hosting_asset asset FROM hs_hosting_asset asset
JOIN hs_booking_item_iv bookingItemIV ON bookingItemIV.uuid = asset.bookingItemUuid JOIN hs_booking_item_iv bookingItemIV ON bookingItemIV.uuid = asset.bookingItemUuid
$idName$); $idName$);
--// --//
-- ============================================================================ -- ============================================================================
--changeset hs-hosting-asset-rbac-RESTRICTED-VIEW:1 endDelimiter:--// --changeset hs-hosting-asset-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------