introduces generateRbacRestrictedView to generate restricted view + triggers
This commit is contained in:
@ -22,7 +22,7 @@ begin
|
||||
|
||||
createDeleteTriggerSQL = format($sql$
|
||||
create trigger deleteRbacRulesFor_%s_Trigger
|
||||
before delete
|
||||
after delete
|
||||
on %s
|
||||
for each row
|
||||
execute procedure deleteRelatedRbacObject();
|
||||
@ -113,3 +113,121 @@ begin
|
||||
execute sql;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset rbac-generators-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create or replace procedure generateRbacRestrictedView(targetTable text, orderBy text, columnUpdates text)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
sql text;
|
||||
begin
|
||||
/*
|
||||
Creates a restricted view based on the 'view' permission of the current subject.
|
||||
*/
|
||||
sql := format($sql$
|
||||
set session session authorization default;
|
||||
create view %1$s_rv as
|
||||
select target.*
|
||||
from %1$s as target
|
||||
where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', '%1$s', currentSubjectsUuids()))
|
||||
order by %2$s;
|
||||
grant all privileges on %1$s_rv to restricted;
|
||||
$sql$, targetTable, orderBy);
|
||||
execute sql;
|
||||
|
||||
/**
|
||||
Instead of insert trigger function for the restricted view.
|
||||
*/
|
||||
sql := format($sql$
|
||||
create or replace function %1$sInsert()
|
||||
returns trigger
|
||||
language plpgsql as $f$
|
||||
declare
|
||||
newTargetRow %1$s;
|
||||
begin
|
||||
insert
|
||||
into %1$s
|
||||
values (new.*)
|
||||
returning * into newTargetRow;
|
||||
return newTargetRow;
|
||||
end; $f$;
|
||||
$sql$, targetTable);
|
||||
execute sql;
|
||||
|
||||
/*
|
||||
Creates an instead of insert trigger for the restricted view.
|
||||
*/
|
||||
sql := format($sql$
|
||||
create trigger %1$sInsert_tg
|
||||
instead of insert
|
||||
on %1$s_rv
|
||||
for each row
|
||||
execute function %1$sInsert();
|
||||
$sql$, targetTable);
|
||||
execute sql;
|
||||
|
||||
/**
|
||||
Instead of delete trigger function for the restricted view.
|
||||
*/
|
||||
sql := format($sql$
|
||||
create or replace function %1$sDelete()
|
||||
returns trigger
|
||||
language plpgsql as $f$
|
||||
begin
|
||||
if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('delete', '%1$s', currentSubjectsUuids())) then
|
||||
delete from %1$s p where p.uuid = old.uuid;
|
||||
return old;
|
||||
end if;
|
||||
raise exception '[403] Subject %% is not allowed to delete %1$s uuid %%', currentSubjectsUuids(), old.uuid;
|
||||
end; $f$;
|
||||
$sql$, targetTable);
|
||||
execute sql;
|
||||
|
||||
/*
|
||||
Creates an instead of delete trigger for the restricted view.
|
||||
*/
|
||||
sql := format($sql$
|
||||
create trigger %1$sDelete_tg
|
||||
instead of delete
|
||||
on %1$s_rv
|
||||
for each row
|
||||
execute function %1$sDelete();
|
||||
$sql$, targetTable);
|
||||
execute sql;
|
||||
|
||||
/**
|
||||
Instead of update trigger function for the restricted view
|
||||
based on the 'edit' permission of the current subject.
|
||||
*/
|
||||
sql := format($sql$
|
||||
create or replace function %1$sUpdate()
|
||||
returns trigger
|
||||
language plpgsql as $f$
|
||||
begin
|
||||
if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('edit', '%1$s', currentSubjectsUuids())) then
|
||||
update %1$s
|
||||
set %2$s
|
||||
where uuid = old.uuid;
|
||||
return old;
|
||||
end if;
|
||||
raise exception '[403] Subject %% is not allowed to update %1$s uuid %%', currentSubjectsUuids(), old.uuid;
|
||||
end; $f$;
|
||||
$sql$, targetTable, columnUpdates);
|
||||
execute sql;
|
||||
|
||||
/*
|
||||
Creates an instead of delete trigger for the restricted view.
|
||||
*/
|
||||
sql = format($sql$
|
||||
create trigger %1$sUpdate_tg
|
||||
instead of update
|
||||
on %1$s_rv
|
||||
for each row
|
||||
execute function %1$sUpdate();
|
||||
$sql$, targetTable);
|
||||
execute sql;
|
||||
end; $$;
|
||||
--//
|
||||
|
@ -87,17 +87,12 @@ call generateRbacIdentityView('test_customer', $idName$
|
||||
-- ============================================================================
|
||||
--changeset test-customer-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Creates a view to the customer main table with row-level limitation
|
||||
based on the 'view' permission of the current user or assumed roles.
|
||||
*/
|
||||
set session session authorization default;
|
||||
drop view if exists test_customer_rv;
|
||||
create or replace view test_customer_rv as
|
||||
select target.*
|
||||
from test_customer as target
|
||||
where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'test_customer', currentSubjectsUuids()));
|
||||
grant all privileges on test_customer_rv to restricted;
|
||||
call generateRbacRestrictedView('test_customer', 'target.prefix',
|
||||
$updates$
|
||||
reference = new.reference,
|
||||
prefix = new.prefix,
|
||||
adminUserName = new.adminUserName
|
||||
$updates$);
|
||||
--//
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ begin
|
||||
-- an owner role is created and assigned to the customer's admin role
|
||||
packageOwnerRoleUuid = createRole(
|
||||
testPackageOwner(NEW),
|
||||
withoutPermissions(),
|
||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['*']),
|
||||
beneathRole(testCustomerAdmin(parentCustomer))
|
||||
);
|
||||
|
||||
@ -64,7 +64,6 @@ end; $$;
|
||||
An AFTER INSERT TRIGGER which creates the role structure for a new package.
|
||||
*/
|
||||
|
||||
drop trigger if exists createRbacRolesForTestPackage_Trigger on test_package;
|
||||
create trigger createRbacRolesForTestPackage_Trigger
|
||||
after insert
|
||||
on test_package
|
||||
@ -76,9 +75,7 @@ execute procedure createRbacRolesForTestPackage();
|
||||
-- ============================================================================
|
||||
--changeset test-package-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('test_package', $idName$
|
||||
target.name
|
||||
$idName$);
|
||||
call generateRbacIdentityView('test_package', 'target.name');
|
||||
--//
|
||||
|
||||
|
||||
@ -90,11 +87,22 @@ call generateRbacIdentityView('test_package', $idName$
|
||||
Creates a view to the customer main table which maps the identifying name
|
||||
(in this case, the prefix) to the objectUuid.
|
||||
*/
|
||||
drop view if exists test_package_rv;
|
||||
create or replace view test_package_rv as
|
||||
select target.*
|
||||
from test_package as target
|
||||
where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'test_package', currentSubjectsUuids()))
|
||||
order by target.name;
|
||||
grant all privileges on test_package_rv to restricted;
|
||||
-- drop view if exists test_package_rv;
|
||||
-- create or replace view test_package_rv as
|
||||
-- select target.*
|
||||
-- from test_package as target
|
||||
-- where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'test_package', currentSubjectsUuids()))
|
||||
-- order by target.name;
|
||||
-- grant all privileges on test_package_rv to restricted;
|
||||
|
||||
call generateRbacRestrictedView('test_package', 'target.name',
|
||||
$updates$
|
||||
version = new.version,
|
||||
customerUuid = new.customerUuid,
|
||||
name = new.name,
|
||||
description = new.description
|
||||
$updates$);
|
||||
|
||||
--//
|
||||
|
||||
|
||||
|
@ -31,7 +31,7 @@ begin
|
||||
|
||||
insert
|
||||
into test_package (customerUuid, name, description)
|
||||
values (cust.uuid, pacName, 'Here can add your own description of package ' || pacName || '.')
|
||||
values (cust.uuid, pacName, 'Here you can add your own description of package ' || pacName || '.')
|
||||
returning * into pac;
|
||||
|
||||
call grantRoleToUser(
|
||||
|
@ -100,7 +100,7 @@ call generateRbacIdentityView('test_domain', $idName$
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-package-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
--changeset test-domain-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
|
@ -86,82 +86,16 @@ call generateRbacIdentityView('hs_office_contact', $idName$
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Creates a view to the contact main table with row-level limitation
|
||||
based on the 'view' permission of the current user or assumed roles.
|
||||
*/
|
||||
set session session authorization default;
|
||||
drop view if exists hs_office_contact_rv;
|
||||
create or replace view hs_office_contact_rv as
|
||||
select target.*
|
||||
from hs_office_contact as target
|
||||
where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'hs_office_contact', currentSubjectsUuids()));
|
||||
grant all privileges on hs_office_contact_rv to restricted;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-rbac-INSTEAD-OF-INSERT-TRIGGER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Instead of insert trigger function for hs_office_contact_rv.
|
||||
*/
|
||||
create or replace function insertHsOfficeContact()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
declare
|
||||
newUser hs_office_contact;
|
||||
begin
|
||||
insert
|
||||
into hs_office_contact
|
||||
values (new.*)
|
||||
returning * into newUser;
|
||||
return newUser;
|
||||
end;
|
||||
$$;
|
||||
|
||||
/*
|
||||
Creates an instead of insert trigger for the hs_office_contact_rv view.
|
||||
*/
|
||||
create trigger insertHsOfficeContact_Trigger
|
||||
instead of insert
|
||||
on hs_office_contact_rv
|
||||
for each row
|
||||
execute function insertHsOfficeContact();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-rbac-INSTEAD-OF-DELETE-TRIGGER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Instead of delete trigger function for hs_office_contact_rv.
|
||||
|
||||
Checks if the current subject (user / assumed role) has the permission to delete the row.
|
||||
*/
|
||||
create or replace function deleteHsOfficeContact()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
if hasGlobalRoleGranted(currentUserUuid()) or
|
||||
old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('delete', 'hs_office_contact', currentSubjectsUuids())) then
|
||||
delete from hs_office_contact c where c.uuid = old.uuid;
|
||||
return old;
|
||||
end if;
|
||||
raise exception '[403] User % not allowed to delete contact uuid %', currentUser(), old.uuid;
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
Creates an instead of delete trigger for the hs_office_contact_rv view.
|
||||
*/
|
||||
create trigger deleteHsOfficeContact_Trigger
|
||||
instead of delete
|
||||
on hs_office_contact_rv
|
||||
for each row
|
||||
execute function deleteHsOfficeContact();
|
||||
call generateRbacRestrictedView('hs_office_contact', 'target.label',
|
||||
$updates$
|
||||
label = new.label,
|
||||
postalAddress = new.postalAddress,
|
||||
emailAddresses = new.emailAddresses,
|
||||
phoneNumbers = new.phoneNumbers
|
||||
$updates$);
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-rbac-NEW-CONTACT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
@ -17,11 +17,9 @@ call generateRbacRoleDescriptors('hsOfficePerson', 'hs_office_person');
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-ROLES-CREATION:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles and their assignments for a new person for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace function createRbacRolesForHsOfficePerson()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
@ -85,82 +83,16 @@ call generateRbacIdentityView('hs_office_person', $idName$
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Creates a view to the person main table with row-level limitation
|
||||
based on the 'view' permission of the current user or assumed roles.
|
||||
*/
|
||||
set session session authorization default;
|
||||
drop view if exists hs_office_person_rv;
|
||||
create or replace view hs_office_person_rv as
|
||||
select target.*
|
||||
from hs_office_person as target
|
||||
where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'hs_office_person', currentSubjectsUuids()));
|
||||
grant all privileges on hs_office_person_rv to restricted;
|
||||
call generateRbacRestrictedView('hs_office_person', 'concat(target.tradeName, target.familyName, target.givenName)',
|
||||
$updates$
|
||||
personType = new.personType,
|
||||
tradeName = new.tradeName,
|
||||
givenName = new.givenName,
|
||||
familyName = new.familyName
|
||||
$updates$);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-INSTEAD-OF-INSERT-TRIGGER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Instead of insert trigger function for hs_office_person_rv.
|
||||
*/
|
||||
create or replace function insertHsOfficePerson()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
declare
|
||||
newUser hs_office_person;
|
||||
begin
|
||||
insert
|
||||
into hs_office_person
|
||||
values (new.*)
|
||||
returning * into newUser;
|
||||
return newUser;
|
||||
end;
|
||||
$$;
|
||||
|
||||
/*
|
||||
Creates an instead of insert trigger for the hs_office_person_rv view.
|
||||
*/
|
||||
create trigger insertHsOfficePerson_Trigger
|
||||
instead of insert
|
||||
on hs_office_person_rv
|
||||
for each row
|
||||
execute function insertHsOfficePerson();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-INSTEAD-OF-DELETE-TRIGGER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Instead of delete trigger function for hs_office_person_rv.
|
||||
|
||||
Checks if the current subject (user / assumed role) has the permission to delete the row.
|
||||
*/
|
||||
create or replace function deleteHsOfficePerson()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
if hasGlobalRoleGranted(currentUserUuid()) or
|
||||
old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('delete', 'hs_office_person', currentSubjectsUuids())) then
|
||||
delete from hs_office_person c where c.uuid = old.uuid;
|
||||
return old;
|
||||
end if;
|
||||
raise exception '[403] User % not allowed to delete person uuid %', currentUser(), old.uuid;
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
Creates an instead of delete trigger for the hs_office_person_rv view.
|
||||
*/
|
||||
create trigger deleteHsOfficePerson_Trigger
|
||||
instead of delete
|
||||
on hs_office_person_rv
|
||||
for each row
|
||||
execute function deleteHsOfficePerson();
|
||||
--/
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-NEW-PERSON:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
@ -127,122 +127,20 @@ call generateRbacIdentityView('hs_office_partner', $idName$
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Creates a view to the partner main table with row-level limitation
|
||||
based on the 'view' permission of the current user or assumed roles.
|
||||
*/
|
||||
set session session authorization default;
|
||||
drop view if exists hs_office_partner_rv;
|
||||
create or replace view hs_office_partner_rv as
|
||||
select target.*
|
||||
from hs_office_partner as target
|
||||
where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'hs_office_partner', currentSubjectsUuids()));
|
||||
grant all privileges on hs_office_partner_rv to restricted;
|
||||
call generateRbacRestrictedView('hs_office_partner',
|
||||
'(select idName from hs_office_person_iv p where p.uuid = target.personUuid)',
|
||||
$updates$
|
||||
personUuid = new.personUuid,
|
||||
contactUuid = new.contactUuid,
|
||||
registrationOffice = new.registrationOffice,
|
||||
registrationNumber = new.registrationNumber,
|
||||
birthday = new.birthday,
|
||||
birthName = new.birthName,
|
||||
dateOfDeath = new.dateOfDeath
|
||||
$updates$);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-INSTEAD-OF-INSERT-TRIGGER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Instead of insert trigger function for hs_office_partner_rv.
|
||||
*/
|
||||
create or replace function insertHsOfficePartner()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
declare
|
||||
newUser hs_office_partner;
|
||||
begin
|
||||
insert
|
||||
into hs_office_partner
|
||||
values (new.*)
|
||||
returning * into newUser;
|
||||
return newUser;
|
||||
end;
|
||||
$$;
|
||||
|
||||
/*
|
||||
Creates an instead of insert trigger for the hs_office_partner_rv view.
|
||||
*/
|
||||
create trigger insertHsOfficePartner_Trigger
|
||||
instead of insert
|
||||
on hs_office_partner_rv
|
||||
for each row
|
||||
execute function insertHsOfficePartner();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-INSTEAD-OF-DELETE-TRIGGER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Instead of delete trigger function for hs_office_partner_rv.
|
||||
|
||||
Checks if the current subject (user / assumed role) has the permission to delete the row.
|
||||
*/
|
||||
create or replace function deleteHsOfficePartner()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('delete', 'hs_office_partner', currentSubjectsUuids())) then
|
||||
delete from hs_office_partner p where p.uuid = old.uuid;
|
||||
return old;
|
||||
end if;
|
||||
raise exception '[403] Subject % is not allowed to delete partner uuid %', currentSubjectsUuids(), old.uuid;
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
Creates an instead of delete trigger for the hs_office_partner_rv view.
|
||||
*/
|
||||
create trigger deleteHsOfficePartner_Trigger
|
||||
instead of delete
|
||||
on hs_office_partner_rv
|
||||
for each row
|
||||
execute function deleteHsOfficePartner();
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-INSTEAD-OF-UPDATE-TRIGGER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Instead of update trigger function for hs_office_partner_rv.
|
||||
|
||||
Checks if the current subject (user / assumed role) has the permission to update the row.
|
||||
*/
|
||||
create or replace function updateHsOfficePartner()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('edit', 'hs_office_partner', currentSubjectsUuids())) then
|
||||
update hs_office_partner
|
||||
set personUuid = new.personUuid,
|
||||
contactUuid = new.contactUuid,
|
||||
registrationOffice = new.registrationOffice,
|
||||
registrationNumber = new.registrationNumber,
|
||||
birthday = new.birthday,
|
||||
birthName = new.birthName,
|
||||
dateOfDeath = new.dateOfDeath
|
||||
where uuid = old.uuid;
|
||||
return old;
|
||||
end if;
|
||||
raise exception '[403] Subject % is not allowed to update partner uuid %', currentSubjectsUuids(), old.uuid;
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
Creates an instead of delete trigger for the hs_office_partner_rv view.
|
||||
*/
|
||||
create trigger updateHsOfficePartner_Trigger
|
||||
instead of update
|
||||
on hs_office_partner_rv
|
||||
for each row
|
||||
execute function updateHsOfficePartner();
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-NEW-CONTACT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user