RBAC Diagram+PostgreSQL Generator and view->SELECT etc. refactoring (#21)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/21 Reviewed-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
This commit is contained in:
@ -23,22 +23,27 @@ end; $$;
|
||||
Defines the transaction context.
|
||||
*/
|
||||
create or replace procedure defineContext(
|
||||
currentTask varchar,
|
||||
currentRequest varchar = null,
|
||||
currentUser varchar = null,
|
||||
assumedRoles varchar = null
|
||||
currentTask varchar(96),
|
||||
currentRequest text = null,
|
||||
currentUser varchar(63) = null,
|
||||
assumedRoles varchar(256) = null
|
||||
)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
currentTask := coalesce(currentTask, '');
|
||||
assert length(currentTask) <= 96, FORMAT('currentTask must not be longer than 96 characters: "%s"', currentTask);
|
||||
assert length(currentTask) > 8, FORMAT('currentTask must be at least 8 characters long: "%s""', currentTask);
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
currentRequest := coalesce(currentRequest, '');
|
||||
execute format('set local hsadminng.currentRequest to %L', currentRequest);
|
||||
|
||||
currentUser := coalesce(currentUser, '');
|
||||
assert length(currentUser) <= 63, FORMAT('currentUser must not be longer than 63 characters: "%s"', currentUser);
|
||||
execute format('set local hsadminng.currentUser to %L', currentUser);
|
||||
|
||||
assumedRoles := coalesce(assumedRoles, '');
|
||||
assert length(assumedRoles) <= 256, FORMAT('assumedRoles must not be longer than 256 characters: "%s"', assumedRoles);
|
||||
execute format('set local hsadminng.assumedRoles to %L', assumedRoles);
|
||||
|
||||
call contextDefined(currentTask, currentRequest, currentUser, assumedRoles);
|
||||
|
@ -27,9 +27,9 @@ create table tx_context
|
||||
txId bigint not null,
|
||||
txTimestamp timestamp not null,
|
||||
currentUser varchar(63) not null, -- not the uuid, because users can be deleted
|
||||
assumedRoles varchar not null, -- not the uuids, because roles can be deleted
|
||||
assumedRoles varchar(256) not null, -- not the uuids, because roles can be deleted
|
||||
currentTask varchar(96) not null,
|
||||
currentRequest varchar(512) not null
|
||||
currentRequest text not null
|
||||
);
|
||||
|
||||
create index on tx_context using brin (txTimestamp);
|
||||
|
@ -86,29 +86,6 @@ create or replace function findRbacUserId(userName varchar)
|
||||
language sql as $$
|
||||
select uuid from RbacUser where name = userName
|
||||
$$;
|
||||
|
||||
create type RbacWhenNotExists as enum ('fail', 'create');
|
||||
|
||||
create or replace function getRbacUserId(userName varchar, whenNotExists RbacWhenNotExists)
|
||||
returns uuid
|
||||
returns null on null input
|
||||
language plpgsql as $$
|
||||
declare
|
||||
userUuid uuid;
|
||||
begin
|
||||
userUuid = findRbacUserId(userName);
|
||||
if (userUuid is null) then
|
||||
if (whenNotExists = 'fail') then
|
||||
raise exception 'RbacUser with name="%" not found', userName;
|
||||
end if;
|
||||
if (whenNotExists = 'create') then
|
||||
userUuid = createRbacUser(userName);
|
||||
end if;
|
||||
end if;
|
||||
return userUuid;
|
||||
end;
|
||||
$$;
|
||||
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
@ -203,15 +180,33 @@ create type RbacRoleDescriptor as
|
||||
(
|
||||
objectTable varchar(63), -- for human readability and easier debugging
|
||||
objectUuid uuid,
|
||||
roleType RbacRoleType
|
||||
roleType RbacRoleType,
|
||||
assumed boolean
|
||||
);
|
||||
|
||||
create or replace function roleDescriptor(objectTable varchar(63), objectUuid uuid, roleType RbacRoleType)
|
||||
create or replace function assumed()
|
||||
returns boolean
|
||||
stable -- leakproof
|
||||
language sql as $$
|
||||
select true;
|
||||
$$;
|
||||
|
||||
create or replace function unassumed()
|
||||
returns boolean
|
||||
stable -- leakproof
|
||||
language sql as $$
|
||||
select false;
|
||||
$$;
|
||||
|
||||
|
||||
create or replace function roleDescriptor(
|
||||
objectTable varchar(63), objectUuid uuid, roleType RbacRoleType,
|
||||
assumed boolean = true) -- just for DSL readability, belongs actually to the grant
|
||||
returns RbacRoleDescriptor
|
||||
returns null on null input
|
||||
stable -- leakproof
|
||||
language sql as $$
|
||||
select objectTable, objectUuid, roleType::RbacRoleType;
|
||||
select objectTable, objectUuid, roleType::RbacRoleType, assumed;
|
||||
$$;
|
||||
|
||||
create or replace function createRole(roleDescriptor RbacRoleDescriptor)
|
||||
@ -275,21 +270,17 @@ create or replace function findRoleId(roleDescriptor RbacRoleDescriptor)
|
||||
select uuid from RbacRole where objectUuid = roleDescriptor.objectUuid and roleType = roleDescriptor.roleType;
|
||||
$$;
|
||||
|
||||
create or replace function getRoleId(roleDescriptor RbacRoleDescriptor, whenNotExists RbacWhenNotExists)
|
||||
create or replace function getRoleId(roleDescriptor RbacRoleDescriptor)
|
||||
returns uuid
|
||||
returns null on null input
|
||||
language plpgsql as $$
|
||||
declare
|
||||
roleUuid uuid;
|
||||
begin
|
||||
roleUuid = findRoleId(roleDescriptor);
|
||||
assert roleDescriptor is not null, 'roleDescriptor must not be null';
|
||||
|
||||
roleUuid := findRoleId(roleDescriptor);
|
||||
if (roleUuid is null) then
|
||||
if (whenNotExists = 'fail') then
|
||||
raise exception 'RbacRole "%#%.%" not found', roleDescriptor.objectTable, roleDescriptor.objectUuid, roleDescriptor.roleType;
|
||||
end if;
|
||||
if (whenNotExists = 'create') then
|
||||
roleUuid = createRole(roleDescriptor);
|
||||
end if;
|
||||
raise exception 'RbacRole "%#%.%" not found', roleDescriptor.objectTable, roleDescriptor.objectUuid, roleDescriptor.roleType;
|
||||
end if;
|
||||
return roleUuid;
|
||||
end;
|
||||
@ -365,38 +356,63 @@ create trigger deleteRbacRolesOfRbacObject_Trigger
|
||||
/*
|
||||
|
||||
*/
|
||||
create domain RbacOp as varchar(67)
|
||||
create domain RbacOp as varchar(67) -- TODO: shorten to 8, once the deprecated values are gone
|
||||
check (
|
||||
VALUE = '*'
|
||||
or VALUE = 'delete'
|
||||
or VALUE = 'edit'
|
||||
or VALUE = 'view'
|
||||
or VALUE = 'assume'
|
||||
VALUE = 'DELETE'
|
||||
or VALUE = 'UPDATE'
|
||||
or VALUE = 'SELECT'
|
||||
or VALUE = 'INSERT'
|
||||
or VALUE = 'ASSUME'
|
||||
-- TODO: all values below are deprecated, use insert with table
|
||||
or VALUE ~ '^add-[a-z]+$'
|
||||
or VALUE ~ '^new-[a-z-]+$'
|
||||
);
|
||||
|
||||
create table RbacPermission
|
||||
(
|
||||
uuid uuid primary key references RbacReference (uuid) on delete cascade,
|
||||
objectUuid uuid not null references RbacObject,
|
||||
op RbacOp not null,
|
||||
uuid uuid primary key references RbacReference (uuid) on delete cascade,
|
||||
objectUuid uuid not null references RbacObject,
|
||||
op RbacOp not null,
|
||||
opTableName varchar(60),
|
||||
unique (objectUuid, op)
|
||||
);
|
||||
|
||||
call create_journal('RbacPermission');
|
||||
|
||||
create or replace function permissionExists(forObjectUuid uuid, forOp RbacOp)
|
||||
returns bool
|
||||
language sql as $$
|
||||
select exists(
|
||||
select op
|
||||
from RbacPermission p
|
||||
where p.objectUuid = forObjectUuid
|
||||
and p.op in ('*', forOp)
|
||||
);
|
||||
$$;
|
||||
create or replace function createPermission(forObjectUuid uuid, forOp RbacOp, forOpTableName text = null)
|
||||
returns uuid
|
||||
language plpgsql as $$
|
||||
declare
|
||||
permissionUuid uuid;
|
||||
begin
|
||||
if (forObjectUuid is null) then
|
||||
raise exception 'forObjectUuid must not be null';
|
||||
end if;
|
||||
if (forOp = 'INSERT' and forOpTableName is null) then
|
||||
raise exception 'INSERT permissions needs forOpTableName';
|
||||
end if;
|
||||
if (forOp <> 'INSERT' and forOpTableName is not null) then
|
||||
raise exception 'forOpTableName must only be specified for ops: [INSERT]'; -- currently no other
|
||||
end if;
|
||||
|
||||
permissionUuid = (select uuid from RbacPermission where objectUuid = forObjectUuid and op = forOp and opTableName = forOpTableName);
|
||||
if (permissionUuid is null) then
|
||||
insert into RbacReference ("type")
|
||||
values ('RbacPermission')
|
||||
returning uuid into permissionUuid;
|
||||
begin
|
||||
insert into RbacPermission (uuid, objectUuid, op, opTableName)
|
||||
values (permissionUuid, forObjectUuid, forOp, forOpTableName);
|
||||
exception
|
||||
when others then
|
||||
raise exception 'insert into RbacPermission (uuid, objectUuid, op, opTableName)
|
||||
values (%, %, %, %);', permissionUuid, forObjectUuid, forOp, forOpTableName;
|
||||
end;
|
||||
end if;
|
||||
return permissionUuid;
|
||||
end; $$;
|
||||
|
||||
-- TODO: deprecated, remove and amend all usages to createPermission
|
||||
create or replace function createPermissions(forObjectUuid uuid, permitOps RbacOp[])
|
||||
returns uuid[]
|
||||
language plpgsql as $$
|
||||
@ -407,9 +423,6 @@ begin
|
||||
if (forObjectUuid is null) then
|
||||
raise exception 'forObjectUuid must not be null';
|
||||
end if;
|
||||
if (array_length(permitOps, 1) > 1 and '*' = any (permitOps)) then
|
||||
raise exception '"*" operation must not be assigned along with other operations: %', permitOps;
|
||||
end if;
|
||||
|
||||
for i in array_lower(permitOps, 1)..array_upper(permitOps, 1)
|
||||
loop
|
||||
@ -430,7 +443,19 @@ begin
|
||||
end;
|
||||
$$;
|
||||
|
||||
create or replace function findPermissionId(forObjectUuid uuid, forOp RbacOp)
|
||||
create or replace function findEffectivePermissionId(forObjectUuid uuid, forOp RbacOp, forOpTableName text = null)
|
||||
returns uuid
|
||||
returns null on null input
|
||||
stable -- leakproof
|
||||
language sql as $$
|
||||
select uuid
|
||||
from RbacPermission p
|
||||
where p.objectUuid = forObjectUuid
|
||||
and (forOp = 'SELECT' or p.op = forOp) -- all other RbacOp include 'SELECT'
|
||||
and p.opTableName = forOpTableName
|
||||
$$;
|
||||
|
||||
create or replace function findPermissionId(forObjectUuid uuid, forOp RbacOp, forOpTableName text = null)
|
||||
returns uuid
|
||||
returns null on null input
|
||||
stable -- leakproof
|
||||
@ -439,23 +464,8 @@ select uuid
|
||||
from RbacPermission p
|
||||
where p.objectUuid = forObjectUuid
|
||||
and p.op = forOp
|
||||
and p.opTableName = forOpTableName
|
||||
$$;
|
||||
|
||||
create or replace function findEffectivePermissionId(forObjectUuid uuid, forOp RbacOp)
|
||||
returns uuid
|
||||
returns null on null input
|
||||
stable -- leakproof
|
||||
language plpgsql as $$
|
||||
declare
|
||||
permissionId uuid;
|
||||
begin
|
||||
permissionId := findPermissionId(forObjectUuid, forOp);
|
||||
if permissionId is null and forOp <> '*' then
|
||||
permissionId := findPermissionId(forObjectUuid, '*');
|
||||
end if;
|
||||
return permissionId;
|
||||
end $$;
|
||||
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
@ -552,6 +562,18 @@ select exists(
|
||||
);
|
||||
$$;
|
||||
|
||||
create or replace function hasInsertPermission(objectUuid uuid, forOp RbacOp, tableName text )
|
||||
returns BOOL
|
||||
stable -- leakproof
|
||||
language plpgsql as $$
|
||||
declare
|
||||
permissionUuid uuid;
|
||||
begin
|
||||
permissionUuid = findPermissionId(objectUuid, forOp, tableName);
|
||||
return permissionUuid is not null;
|
||||
end;
|
||||
$$;
|
||||
|
||||
create or replace function hasGlobalRoleGranted(userUuid uuid)
|
||||
returns bool
|
||||
stable -- leakproof
|
||||
@ -566,6 +588,27 @@ select exists(
|
||||
);
|
||||
$$;
|
||||
|
||||
create or replace procedure grantPermissionToRole(roleUuid uuid, permissionUuid uuid)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
perform assertReferenceType('roleId (ascendant)', roleUuid, 'RbacRole');
|
||||
perform assertReferenceType('permissionId (descendant)', permissionUuid, 'RbacPermission');
|
||||
|
||||
insert
|
||||
into RbacGrants (grantedByTriggerOf, ascendantUuid, descendantUuid, assumed)
|
||||
values (currentTriggerObjectUuid(), roleUuid, permissionUuid, true)
|
||||
on conflict do nothing; -- allow granting multiple times
|
||||
end;
|
||||
$$;
|
||||
|
||||
create or replace procedure grantPermissionToRole(roleDesc RbacRoleDescriptor, permissionUuid uuid)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
call grantPermissionToRole(findRoleId(roleDesc), permissionUuid);
|
||||
end;
|
||||
$$;
|
||||
|
||||
-- TODO: deprecated, remove and use grantPermissionToRole(...)
|
||||
create or replace procedure grantPermissionsToRole(roleUuid uuid, permissionIds uuid[])
|
||||
language plpgsql as $$
|
||||
begin
|
||||
@ -697,7 +740,7 @@ begin
|
||||
select descendantUuid
|
||||
from grants) as granted
|
||||
join RbacPermission perm
|
||||
on granted.descendantUuid = perm.uuid and perm.op in ('*', requiredOp)
|
||||
on granted.descendantUuid = perm.uuid and (requiredOp = 'SELECT' or perm.op = requiredOp)
|
||||
join RbacObject obj on obj.uuid = perm.objectUuid and obj.objectTable = forObjectTable
|
||||
limit maxObjects + 1;
|
||||
|
||||
@ -789,6 +832,5 @@ do $$
|
||||
create role restricted;
|
||||
grant all privileges on all tables in schema public to restricted;
|
||||
end if;
|
||||
end $$
|
||||
end $$;
|
||||
--//
|
||||
|
||||
|
@ -30,24 +30,35 @@ begin
|
||||
insert
|
||||
into RbacGrants (grantedByRoleUuid, ascendantUuid, descendantUuid, assumed)
|
||||
values (grantedByRoleUuid, userUuid, roleUuid, doAssume);
|
||||
-- TODO.spec: What should happen on mupltiple grants? What if options (doAssume) are not the same?
|
||||
-- TODO.spec: What should happen on multiple grants? What if options (doAssume) are not the same?
|
||||
-- Most powerful or latest grant wins? What about managed?
|
||||
-- on conflict do nothing; -- allow granting multiple times
|
||||
end; $$;
|
||||
|
||||
create or replace procedure grantRoleToUser(grantedByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid, doAssume boolean = true)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
grantedByRoleIdName text;
|
||||
grantedRoleIdName text;
|
||||
begin
|
||||
perform assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'RbacRole');
|
||||
perform assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'RbacRole');
|
||||
perform assertReferenceType('userUuid (ascendant)', userUuid, 'RbacUser');
|
||||
|
||||
if NOT isGranted(currentSubjectsUuids(), grantedByRoleUuid) then
|
||||
raise exception '[403] Access to granted-by-role % forbidden for %', grantedByRoleUuid, currentSubjects();
|
||||
end if;
|
||||
assert grantedByRoleUuid is not null, 'grantedByRoleUuid must not be null';
|
||||
assert grantedRoleUuid is not null, 'grantedRoleUuid must not be null';
|
||||
assert userUuid is not null, 'userUuid must not be null';
|
||||
|
||||
if NOT isGranted(currentSubjectsUuids(), grantedByRoleUuid) then
|
||||
select roleIdName from rbacRole_ev where uuid=grantedByRoleUuid into grantedByRoleIdName;
|
||||
raise exception '[403] Access to granted-by-role % (%) forbidden for % (%)',
|
||||
grantedByRoleIdName, grantedByRoleUuid, currentSubjects(), currentSubjectsUuids();
|
||||
end if;
|
||||
if NOT isGranted(grantedByRoleUuid, grantedRoleUuid) then
|
||||
raise exception '[403] Access to granted role % forbidden for %', grantedRoleUuid, currentSubjects();
|
||||
select roleIdName from rbacRole_ev where uuid=grantedByRoleUuid into grantedByRoleIdName;
|
||||
select roleIdName from rbacRole_ev where uuid=grantedRoleUuid into grantedRoleIdName;
|
||||
raise exception '[403] Access to granted role % (%) forbidden for % (%)',
|
||||
grantedRoleIdName, grantedRoleUuid, grantedByRoleIdName, grantedByRoleUuid;
|
||||
end if;
|
||||
|
||||
insert
|
||||
@ -99,4 +110,17 @@ begin
|
||||
where g.ascendantUuid = userUuid and g.descendantUuid = grantedRoleUuid
|
||||
and g.grantedByRoleUuid = revokeRoleFromUser.grantedByRoleUuid;
|
||||
end; $$;
|
||||
--/
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset rbac-user-grant-REVOKE-PERMISSION-FROM-ROLE:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create or replace procedure revokePermissionFromRole(permissionUuid uuid, superRoleUuid uuid)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise INFO 'delete from RbacGrants where ascendantUuid = % and descendantUuid = %', superRoleUuid, permissionUuid;
|
||||
delete from RbacGrants as g
|
||||
where g.ascendantUuid = superRoleUuid and g.descendantUuid = permissionUuid;
|
||||
end; $$;
|
||||
--//
|
||||
|
@ -337,11 +337,9 @@ grant all privileges on RbacOwnGrantedPermissions_rv to ${HSADMINNG_POSTGRES_RES
|
||||
/*
|
||||
Returns all permissions granted to the given user,
|
||||
which are also visible to the current user or assumed roles.
|
||||
|
||||
|
||||
*/
|
||||
create or replace function grantedPermissions(targetUserUuid uuid)
|
||||
returns table(roleUuid uuid, roleName text, permissionUuid uuid, op RbacOp, objectTable varchar, objectIdName varchar, objectUuid uuid)
|
||||
*/
|
||||
create or replace function grantedPermissionsRaw(targetUserUuid uuid)
|
||||
returns table(roleUuid uuid, roleName text, permissionUuid uuid, op RbacOp, opTableName varchar(60), objectTable varchar(60), objectIdName varchar, objectUuid uuid)
|
||||
returns null on null input
|
||||
language plpgsql as $$
|
||||
declare
|
||||
@ -357,11 +355,13 @@ begin
|
||||
return query select
|
||||
xp.roleUuid,
|
||||
(xp.roleObjectTable || '#' || xp.roleObjectIdName || '.' || xp.roleType) as roleName,
|
||||
xp.permissionUuid, xp.op, xp.permissionObjectTable, xp.permissionObjectIdName, xp.permissionObjectUuid
|
||||
xp.permissionUuid, xp.op, xp.opTableName,
|
||||
xp.permissionObjectTable, xp.permissionObjectIdName, xp.permissionObjectUuid
|
||||
from (select
|
||||
r.uuid as roleUuid, r.roletype, ro.objectTable as roleObjectTable,
|
||||
findIdNameByObjectUuid(ro.objectTable, ro.uuid) as roleObjectIdName,
|
||||
p.uuid as permissionUuid, p.op, po.objecttable as permissionObjectTable,
|
||||
p.uuid as permissionUuid, p.op, p.opTableName,
|
||||
po.objecttable as permissionObjectTable,
|
||||
findIdNameByObjectUuid(po.objectTable, po.uuid) as permissionObjectIdName,
|
||||
po.uuid as permissionObjectUuid
|
||||
from queryPermissionsGrantedToSubjectId( targetUserUuid) as p
|
||||
@ -373,4 +373,15 @@ begin
|
||||
) xp;
|
||||
-- @formatter:on
|
||||
end; $$;
|
||||
|
||||
create or replace function grantedPermissions(targetUserUuid uuid)
|
||||
returns table(roleUuid uuid, roleName text, permissionUuid uuid, op RbacOp, opTableName varchar(60), objectTable varchar(60), objectIdName varchar, objectUuid uuid)
|
||||
returns null on null input
|
||||
language sql as $$
|
||||
select * from grantedPermissionsRaw(targetUserUuid)
|
||||
union all
|
||||
select roleUuid, roleName, permissionUuid, 'SELECT'::RbacOp, opTableName, objectTable, objectIdName, objectUuid
|
||||
from grantedPermissionsRaw(targetUserUuid)
|
||||
where op <> 'SELECT'::RbacOp;
|
||||
$$;
|
||||
--//
|
||||
|
@ -13,24 +13,6 @@ begin
|
||||
return createPermissions(forObjectUuid, permitOps);
|
||||
end; $$;
|
||||
|
||||
create or replace function toRoleUuids(roleDescriptors RbacRoleDescriptor[])
|
||||
returns uuid[]
|
||||
language plpgsql
|
||||
strict as $$
|
||||
declare
|
||||
superRoleDescriptor RbacRoleDescriptor;
|
||||
superRoleUuids uuid[] := array []::uuid[];
|
||||
begin
|
||||
foreach superRoleDescriptor in array roleDescriptors
|
||||
loop
|
||||
if superRoleDescriptor is not null then
|
||||
superRoleUuids := superRoleUuids || getRoleId(superRoleDescriptor, 'fail');
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return superRoleUuids;
|
||||
end; $$;
|
||||
|
||||
|
||||
-- =================================================================
|
||||
-- CREATE ROLE
|
||||
@ -50,32 +32,37 @@ create or replace function createRoleWithGrants(
|
||||
language plpgsql as $$
|
||||
declare
|
||||
roleUuid uuid;
|
||||
superRoleUuid uuid;
|
||||
subRoleDesc RbacRoleDescriptor;
|
||||
superRoleDesc RbacRoleDescriptor;
|
||||
subRoleUuid uuid;
|
||||
superRoleUuid uuid;
|
||||
userUuid uuid;
|
||||
grantedByRoleUuid uuid;
|
||||
begin
|
||||
roleUuid := createRole(roleDescriptor);
|
||||
|
||||
if cardinality(permissions) >0 then
|
||||
if cardinality(permissions) > 0 then
|
||||
call grantPermissionsToRole(roleUuid, toPermissionUuids(roleDescriptor.objectuuid, permissions));
|
||||
end if;
|
||||
|
||||
foreach superRoleUuid in array toRoleUuids(incomingSuperRoles)
|
||||
foreach superRoleDesc in array array_remove(incomingSuperRoles, null)
|
||||
loop
|
||||
call grantRoleToRole(roleUuid, superRoleUuid);
|
||||
superRoleUuid := getRoleId(superRoleDesc);
|
||||
call grantRoleToRole(roleUuid, superRoleUuid, superRoleDesc.assumed);
|
||||
end loop;
|
||||
|
||||
foreach subRoleUuid in array toRoleUuids(outgoingSubRoles)
|
||||
foreach subRoleDesc in array array_remove(outgoingSubRoles, null)
|
||||
loop
|
||||
call grantRoleToRole(subRoleUuid, roleUuid);
|
||||
subRoleUuid := getRoleId(subRoleDesc);
|
||||
call grantRoleToRole(subRoleUuid, roleUuid, subRoleDesc.assumed);
|
||||
end loop;
|
||||
|
||||
if cardinality(userUuids) > 0 then
|
||||
if grantedByRole is null then
|
||||
raise exception 'to directly assign users to roles, grantingRole has to be given';
|
||||
grantedByRoleUuid := roleUuid;
|
||||
else
|
||||
grantedByRoleUuid := getRoleId(grantedByRole);
|
||||
end if;
|
||||
grantedByRoleUuid := getRoleId(grantedByRole, 'fail');
|
||||
foreach userUuid in array userUuids
|
||||
loop
|
||||
call grantRoleToUserUnchecked(grantedByRoleUuid, roleUuid, userUuid);
|
||||
|
@ -13,8 +13,7 @@ declare
|
||||
begin
|
||||
createInsertTriggerSQL = format($sql$
|
||||
create trigger createRbacObjectFor_%s_Trigger
|
||||
before insert
|
||||
on %s
|
||||
before insert on %s
|
||||
for each row
|
||||
execute procedure insertRelatedRbacObject();
|
||||
$sql$, targetTable, targetTable);
|
||||
@ -36,50 +35,50 @@ end; $$;
|
||||
--changeset rbac-generators-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create or replace procedure generateRbacRoleDescriptors(prefix text, targetTable text)
|
||||
create procedure generateRbacRoleDescriptors(prefix text, targetTable text)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
sql text;
|
||||
begin
|
||||
sql = format($sql$
|
||||
create or replace function %1$sOwner(entity %2$s)
|
||||
create or replace function %1$sOwner(entity %2$s, assumed boolean = true)
|
||||
returns RbacRoleDescriptor
|
||||
language plpgsql
|
||||
strict as $f$
|
||||
begin
|
||||
return roleDescriptor('%2$s', entity.uuid, 'owner');
|
||||
return roleDescriptor('%2$s', entity.uuid, 'owner', assumed);
|
||||
end; $f$;
|
||||
|
||||
create or replace function %1$sAdmin(entity %2$s)
|
||||
create or replace function %1$sAdmin(entity %2$s, assumed boolean = true)
|
||||
returns RbacRoleDescriptor
|
||||
language plpgsql
|
||||
strict as $f$
|
||||
begin
|
||||
return roleDescriptor('%2$s', entity.uuid, 'admin');
|
||||
return roleDescriptor('%2$s', entity.uuid, 'admin', assumed);
|
||||
end; $f$;
|
||||
|
||||
create or replace function %1$sAgent(entity %2$s)
|
||||
create or replace function %1$sAgent(entity %2$s, assumed boolean = true)
|
||||
returns RbacRoleDescriptor
|
||||
language plpgsql
|
||||
strict as $f$
|
||||
begin
|
||||
return roleDescriptor('%2$s', entity.uuid, 'agent');
|
||||
return roleDescriptor('%2$s', entity.uuid, 'agent', assumed);
|
||||
end; $f$;
|
||||
|
||||
create or replace function %1$sTenant(entity %2$s)
|
||||
create or replace function %1$sTenant(entity %2$s, assumed boolean = true)
|
||||
returns RbacRoleDescriptor
|
||||
language plpgsql
|
||||
strict as $f$
|
||||
begin
|
||||
return roleDescriptor('%2$s', entity.uuid, 'tenant');
|
||||
return roleDescriptor('%2$s', entity.uuid, 'tenant', assumed);
|
||||
end; $f$;
|
||||
|
||||
create or replace function %1$sGuest(entity %2$s)
|
||||
create or replace function %1$sGuest(entity %2$s, assumed boolean = true)
|
||||
returns RbacRoleDescriptor
|
||||
language plpgsql
|
||||
strict as $f$
|
||||
begin
|
||||
return roleDescriptor('%2$s', entity.uuid, 'guest');
|
||||
return roleDescriptor('%2$s', entity.uuid, 'guest', assumed);
|
||||
end; $f$;
|
||||
|
||||
$sql$, prefix, targetTable);
|
||||
@ -92,7 +91,7 @@ end; $$;
|
||||
--changeset rbac-generators-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create or replace procedure generateRbacIdentityView(targetTable text, idNameExpression text)
|
||||
create or replace procedure generateRbacIdentityViewFromQuery(targetTable text, sqlQuery text)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
sql text;
|
||||
@ -101,11 +100,9 @@ begin
|
||||
|
||||
-- create a view to the target main table which maps an idName to the objectUuid
|
||||
sql = format($sql$
|
||||
create or replace view %1$s_iv as
|
||||
select target.uuid, cleanIdentifier(%2$s) as idName
|
||||
from %1$s as target;
|
||||
create or replace view %1$s_iv as %2$s;
|
||||
grant all privileges on %1$s_iv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||
$sql$, targetTable, idNameExpression);
|
||||
$sql$, targetTable, sqlQuery);
|
||||
execute sql;
|
||||
|
||||
-- creates a function which maps an idName to the objectUuid
|
||||
@ -130,6 +127,20 @@ begin
|
||||
$sql$, targetTable);
|
||||
execute sql;
|
||||
end; $$;
|
||||
|
||||
create or replace procedure generateRbacIdentityViewFromProjection(targetTable text, sqlProjection text)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
sqlQuery text;
|
||||
begin
|
||||
targettable := lower(targettable);
|
||||
|
||||
sqlQuery = format($sql$
|
||||
select target.uuid, cleanIdentifier(%2$s) as idName
|
||||
from %1$s as target;
|
||||
$sql$, targetTable, sqlProjection);
|
||||
call generateRbacIdentityViewFromQuery(targetTable, sqlQuery);
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
@ -145,13 +156,13 @@ begin
|
||||
targetTable := lower(targetTable);
|
||||
|
||||
/*
|
||||
Creates a restricted view based on the 'view' permission of the current subject.
|
||||
Creates a restricted view based on the 'SELECT' permission of the current subject.
|
||||
*/
|
||||
sql := format($sql$
|
||||
set session session authorization default;
|
||||
create view %1$s_rv as
|
||||
with accessibleObjects as (
|
||||
select queryAccessibleObjectUuidsOfSubjectIds('view', '%1$s', currentSubjectsUuids())
|
||||
select queryAccessibleObjectUuidsOfSubjectIds('SELECT', '%1$s', currentSubjectsUuids())
|
||||
)
|
||||
select target.*
|
||||
from %1$s as target
|
||||
@ -200,7 +211,7 @@ begin
|
||||
returns trigger
|
||||
language plpgsql as $f$
|
||||
begin
|
||||
if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('delete', '%1$s', currentSubjectsUuids())) then
|
||||
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;
|
||||
@ -223,7 +234,7 @@ begin
|
||||
|
||||
/**
|
||||
Instead of update trigger function for the restricted view
|
||||
based on the 'edit' permission of the current subject.
|
||||
based on the 'UPDATE' permission of the current subject.
|
||||
*/
|
||||
if columnUpdates is not null then
|
||||
sql := format($sql$
|
||||
@ -231,7 +242,7 @@ begin
|
||||
returns trigger
|
||||
language plpgsql as $f$
|
||||
begin
|
||||
if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('edit', '%1$s', currentSubjectsUuids())) then
|
||||
if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('UPDATE', '%1$s', currentSubjectsUuids())) then
|
||||
update %1$s
|
||||
set %2$s
|
||||
where uuid = old.uuid;
|
||||
|
@ -22,6 +22,19 @@ grant select on global to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset rbac-global-IS-GLOBAL-ADMIN:1 endDelimiter:--//
|
||||
-- ------------------------------------------------------------------
|
||||
|
||||
create or replace function isGlobalAdmin()
|
||||
returns boolean
|
||||
language plpgsql as $$
|
||||
begin
|
||||
return isGranted(currentSubjectsUuids(), findRoleId(globalAdmin()));
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset rbac-global-HAS-GLOBAL-PERMISSION:1 endDelimiter:--//
|
||||
-- ------------------------------------------------------------------
|
||||
@ -96,12 +109,12 @@ commit;
|
||||
/*
|
||||
A global administrator role.
|
||||
*/
|
||||
create or replace function globalAdmin()
|
||||
create or replace function globalAdmin(assumed boolean = true)
|
||||
returns RbacRoleDescriptor
|
||||
returns null on null input
|
||||
stable -- leakproof
|
||||
language sql as $$
|
||||
select 'global', (select uuid from RbacObject where objectTable = 'global'), 'admin'::RbacRoleType;
|
||||
select 'global', (select uuid from RbacObject where objectTable = 'global'), 'admin'::RbacRoleType, assumed;
|
||||
$$;
|
||||
|
||||
begin transaction;
|
||||
|
43
src/main/resources/db/changelog/113-test-customer-rbac.md
Normal file
43
src/main/resources/db/changelog/113-test-customer-rbac.md
Normal file
@ -0,0 +1,43 @@
|
||||
### rbac customer
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-11T11:29:11.571772062.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph customer["`**customer**`"]
|
||||
direction TB
|
||||
style customer fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph customer:roles[ ]
|
||||
style customer:roles fill:#dd4901,stroke:white
|
||||
|
||||
role:customer:owner[[customer:owner]]
|
||||
role:customer:admin[[customer:admin]]
|
||||
role:customer:tenant[[customer:tenant]]
|
||||
end
|
||||
|
||||
subgraph customer:permissions[ ]
|
||||
style customer:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:customer:DELETE{{customer:DELETE}}
|
||||
perm:customer:UPDATE{{customer:UPDATE}}
|
||||
perm:customer:SELECT{{customer:SELECT}}
|
||||
end
|
||||
end
|
||||
|
||||
%% granting roles to users
|
||||
user:creator ==>|XX| role:customer:owner
|
||||
|
||||
%% granting roles to roles
|
||||
role:global:admin ==>|XX| role:customer:owner
|
||||
role:customer:owner ==> role:customer:admin
|
||||
role:customer:admin ==> role:customer:tenant
|
||||
|
||||
%% granting permissions to roles
|
||||
role:customer:owner ==> perm:customer:DELETE
|
||||
role:customer:admin ==> perm:customer:UPDATE
|
||||
role:customer:tenant ==> perm:customer:SELECT
|
||||
|
||||
```
|
@ -1,4 +1,5 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator at 2024-03-11T11:29:11.584886824.
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-customer-rbac-OBJECT:1 endDelimiter:--//
|
||||
@ -15,82 +16,103 @@ call generateRbacRoleDescriptors('testCustomer', 'test_customer');
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-customer-rbac-ROLES-CREATION:1 endDelimiter:--//
|
||||
--changeset test-customer-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles and their assignments for a new customer for the AFTER INSERT TRIGGER.
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace function createRbacRolesForTestCustomer()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
declare
|
||||
testCustomerOwnerUuid uuid;
|
||||
customerAdminUuid uuid;
|
||||
begin
|
||||
if TG_OP <> 'INSERT' then
|
||||
raise exception 'invalid usage of TRIGGER AFTER INSERT';
|
||||
end if;
|
||||
create or replace procedure buildRbacSystemForTestCustomer(
|
||||
NEW test_customer
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
-- the owner role with full access for Hostsharing administrators
|
||||
testCustomerOwnerUuid = createRoleWithGrants(
|
||||
perform createRoleWithGrants(
|
||||
testCustomerOwner(NEW),
|
||||
permissions => array['*'],
|
||||
incomingSuperRoles => array[globalAdmin()]
|
||||
);
|
||||
permissions => array['DELETE'],
|
||||
userUuids => array[currentUserUuid()],
|
||||
incomingSuperRoles => array[globalAdmin(unassumed())]
|
||||
);
|
||||
|
||||
-- the admin role for the customer's admins, who can view and add products
|
||||
customerAdminUuid = createRoleWithGrants(
|
||||
perform createRoleWithGrants(
|
||||
testCustomerAdmin(NEW),
|
||||
permissions => array['view', 'add-package'],
|
||||
-- NO auto assume for customer owner to avoid exploding permissions for administrators
|
||||
userUuids => array[getRbacUserId(NEW.adminUserName, 'create')], -- implicitly ignored if null
|
||||
grantedByRole => globalAdmin()
|
||||
);
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[testCustomerOwner(NEW)]
|
||||
);
|
||||
|
||||
-- allow the customer owner role (thus administrators) to assume the customer admin role
|
||||
call grantRoleToRole(customerAdminUuid, testCustomerOwnerUuid, false);
|
||||
|
||||
-- the tenant role which later can be used by owners+admins of sub-objects
|
||||
perform createRoleWithGrants(
|
||||
testCustomerTenant(NEW),
|
||||
permissions => array['view']
|
||||
);
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[testCustomerAdmin(NEW)]
|
||||
);
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
An AFTER INSERT TRIGGER which creates the role structure for a new customer.
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new test_customer row.
|
||||
*/
|
||||
|
||||
drop trigger if exists createRbacRolesForTestCustomer_Trigger on test_customer;
|
||||
create trigger createRbacRolesForTestCustomer_Trigger
|
||||
after insert
|
||||
on test_customer
|
||||
create or replace function insertTriggerForTestCustomer_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForTestCustomer(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForTestCustomer_tg
|
||||
after insert on test_customer
|
||||
for each row
|
||||
execute procedure createRbacRolesForTestCustomer();
|
||||
execute procedure insertTriggerForTestCustomer_tf();
|
||||
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-customer-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to test_customer.
|
||||
*/
|
||||
create or replace function test_customer_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into test_customer not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger test_customer_insert_permission_check_tg
|
||||
before insert on test_customer
|
||||
for each row
|
||||
-- As there is no explicit INSERT grant specified for this table,
|
||||
-- only global admins are allowed to insert any rows.
|
||||
when ( not isGlobalAdmin() )
|
||||
execute procedure test_customer_insert_permission_missing_tf();
|
||||
|
||||
--//
|
||||
-- ============================================================================
|
||||
--changeset test-customer-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('test_customer', $idName$
|
||||
target.prefix
|
||||
|
||||
call generateRbacIdentityViewFromProjection('test_customer', $idName$
|
||||
prefix
|
||||
$idName$);
|
||||
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-customer-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('test_customer', 'target.prefix',
|
||||
call generateRbacRestrictedView('test_customer',
|
||||
'reference',
|
||||
$updates$
|
||||
reference = new.reference,
|
||||
prefix = new.prefix,
|
||||
@ -99,47 +121,3 @@ call generateRbacRestrictedView('test_customer', 'target.prefix',
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-customer-rbac-ADD-CUSTOMER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Creates a global permission for add-customer and assigns it to the hostsharing admins role.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
addCustomerPermissions uuid[];
|
||||
globalObjectUuid uuid;
|
||||
globalAdminRoleUuid uuid ;
|
||||
begin
|
||||
call defineContext('granting global add-customer permission to global admin role', null, null, null);
|
||||
|
||||
globalAdminRoleUuid := findRoleId(globalAdmin());
|
||||
globalObjectUuid := (select uuid from global);
|
||||
addCustomerPermissions := createPermissions(globalObjectUuid, array ['add-customer']);
|
||||
call grantPermissionsToRole(globalAdminRoleUuid, addCustomerPermissions);
|
||||
end;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Used by the trigger to prevent the add-customer to current user respectively assumed roles.
|
||||
*/
|
||||
create or replace function addTestCustomerNotAllowedForCurrentSubjects()
|
||||
returns trigger
|
||||
language PLPGSQL
|
||||
as $$
|
||||
begin
|
||||
raise exception '[403] add-customer not permitted for %',
|
||||
array_to_string(currentSubjects(), ';', 'null');
|
||||
end; $$;
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to add a new customer.
|
||||
*/
|
||||
create trigger test_customer_insert_trigger
|
||||
before insert
|
||||
on test_customer
|
||||
for each row
|
||||
when ( not hasGlobalPermission('add-customer') )
|
||||
execute procedure addTestCustomerNotAllowedForCurrentSubjects();
|
||||
--//
|
||||
|
||||
|
@ -28,6 +28,8 @@ declare
|
||||
currentTask varchar;
|
||||
custRowId uuid;
|
||||
custAdminName varchar;
|
||||
custAdminUuid uuid;
|
||||
newCust test_customer;
|
||||
begin
|
||||
currentTask = 'creating RBAC test customer #' || custReference || '/' || custPrefix;
|
||||
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin');
|
||||
@ -35,10 +37,19 @@ begin
|
||||
|
||||
custRowId = uuid_generate_v4();
|
||||
custAdminName = 'customer-admin@' || custPrefix || '.example.com';
|
||||
custAdminUuid = createRbacUser(custAdminName);
|
||||
|
||||
insert
|
||||
into test_customer (reference, prefix, adminUserName)
|
||||
values (custReference, custPrefix, custAdminName);
|
||||
|
||||
select * into newCust
|
||||
from test_customer where reference=custReference;
|
||||
call grantRoleToUser(
|
||||
getRoleId(testCustomerOwner(newCust)),
|
||||
getRoleId(testCustomerAdmin(newCust)),
|
||||
custAdminUuid,
|
||||
true);
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
59
src/main/resources/db/changelog/123-test-package-rbac.md
Normal file
59
src/main/resources/db/changelog/123-test-package-rbac.md
Normal file
@ -0,0 +1,59 @@
|
||||
### rbac package
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-11T11:29:11.624847792.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph package["`**package**`"]
|
||||
direction TB
|
||||
style package fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph package:roles[ ]
|
||||
style package:roles fill:#dd4901,stroke:white
|
||||
|
||||
role:package:owner[[package:owner]]
|
||||
role:package:admin[[package:admin]]
|
||||
role:package:tenant[[package:tenant]]
|
||||
end
|
||||
|
||||
subgraph package:permissions[ ]
|
||||
style package:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:package:INSERT{{package:INSERT}}
|
||||
perm:package:DELETE{{package:DELETE}}
|
||||
perm:package:UPDATE{{package:UPDATE}}
|
||||
perm:package:SELECT{{package:SELECT}}
|
||||
end
|
||||
end
|
||||
|
||||
subgraph customer["`**customer**`"]
|
||||
direction TB
|
||||
style customer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph customer:roles[ ]
|
||||
style customer:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:customer:owner[[customer:owner]]
|
||||
role:customer:admin[[customer:admin]]
|
||||
role:customer:tenant[[customer:tenant]]
|
||||
end
|
||||
end
|
||||
|
||||
%% granting roles to roles
|
||||
role:global:admin -.->|XX| role:customer:owner
|
||||
role:customer:owner -.-> role:customer:admin
|
||||
role:customer:admin -.-> role:customer:tenant
|
||||
role:customer:admin ==> role:package:owner
|
||||
role:package:owner ==> role:package:admin
|
||||
role:package:admin ==> role:package:tenant
|
||||
role:package:tenant ==> role:customer:tenant
|
||||
|
||||
%% granting permissions to roles
|
||||
role:customer:admin ==> perm:package:INSERT
|
||||
role:package:owner ==> perm:package:DELETE
|
||||
role:package:owner ==> perm:package:UPDATE
|
||||
role:package:tenant ==> perm:package:SELECT
|
||||
|
||||
```
|
@ -1,4 +1,5 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator at 2024-03-11T11:29:11.625353859.
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-package-rbac-OBJECT:1 endDelimiter:--//
|
||||
@ -15,95 +16,211 @@ call generateRbacRoleDescriptors('testPackage', 'test_package');
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-package-rbac-ROLES-CREATION:1 endDelimiter:--//
|
||||
--changeset test-package-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles and their assignments for a new package for the AFTER INSERT TRIGGER.
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
create or replace function createRbacRolesForTestPackage()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
|
||||
create or replace procedure buildRbacSystemForTestPackage(
|
||||
NEW test_package
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
parentCustomer test_customer;
|
||||
newCustomer test_customer;
|
||||
|
||||
begin
|
||||
if TG_OP <> 'INSERT' then
|
||||
raise exception 'invalid usage of TRIGGER AFTER INSERT';
|
||||
end if;
|
||||
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
SELECT * FROM test_customer c
|
||||
WHERE c.uuid= NEW.customerUuid
|
||||
into newCustomer;
|
||||
|
||||
select * from test_customer as c where c.uuid = NEW.customerUuid into parentCustomer;
|
||||
|
||||
-- an owner role is created and assigned to the customer's admin role
|
||||
perform createRoleWithGrants(
|
||||
testPackageOwner(NEW),
|
||||
permissions => array ['*'],
|
||||
incomingSuperRoles => array[testCustomerAdmin(parentCustomer)]
|
||||
);
|
||||
testPackageOwner(NEW),
|
||||
permissions => array['DELETE', 'UPDATE'],
|
||||
incomingSuperRoles => array[testCustomerAdmin(newCustomer)]
|
||||
);
|
||||
|
||||
-- an owner role is created and assigned to the package owner role
|
||||
perform createRoleWithGrants(
|
||||
testPackageAdmin(NEW),
|
||||
permissions => array ['add-domain'],
|
||||
testPackageAdmin(NEW),
|
||||
incomingSuperRoles => array[testPackageOwner(NEW)]
|
||||
);
|
||||
);
|
||||
|
||||
-- and a package tenant role is created and assigned to the package admin as well
|
||||
perform createRoleWithGrants(
|
||||
testPackageTenant(NEW),
|
||||
permissions => array['view'],
|
||||
incomingsuperroles => array[testPackageAdmin(NEW)],
|
||||
outgoingSubRoles => array[testCustomerTenant(parentCustomer)]
|
||||
);
|
||||
testPackageTenant(NEW),
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[testPackageAdmin(NEW)],
|
||||
outgoingSubRoles => array[testCustomerTenant(newCustomer)]
|
||||
);
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
An AFTER INSERT TRIGGER which creates the role structure for a new package.
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new test_package row.
|
||||
*/
|
||||
|
||||
create trigger createRbacRolesForTestPackage_Trigger
|
||||
after insert
|
||||
on test_package
|
||||
create or replace function insertTriggerForTestPackage_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForTestPackage(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForTestPackage_tg
|
||||
after insert on test_package
|
||||
for each row
|
||||
execute procedure createRbacRolesForTestPackage();
|
||||
execute procedure insertTriggerForTestPackage_tf();
|
||||
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-package-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('test_package', 'target.name');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-package-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
--changeset test-package-rbac-update-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates a view to the customer main table which maps the identifying name
|
||||
(in this case, the prefix) to the objectUuid.
|
||||
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
|
||||
*/
|
||||
-- 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 ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||
|
||||
call generateRbacRestrictedView('test_package', 'target.name',
|
||||
$updates$
|
||||
version = new.version,
|
||||
customerUuid = new.customerUuid,
|
||||
name = new.name,
|
||||
description = new.description
|
||||
$updates$);
|
||||
create or replace procedure updateRbacRulesForTestPackage(
|
||||
OLD test_package,
|
||||
NEW test_package
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
oldCustomer test_customer;
|
||||
newCustomer test_customer;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM test_customer c
|
||||
WHERE c.uuid= OLD.customerUuid
|
||||
into oldCustomer;
|
||||
SELECT * FROM test_customer c
|
||||
WHERE c.uuid= NEW.customerUuid
|
||||
into newCustomer;
|
||||
|
||||
if NEW.customerUuid <> OLD.customerUuid then
|
||||
|
||||
call revokePermissionFromRole(findPermissionId(OLD.uuid, 'INSERT'), testCustomerAdmin(oldCustomer));
|
||||
|
||||
call revokeRoleFromRole(testPackageOwner(OLD), testCustomerAdmin(oldCustomer));
|
||||
call grantRoleToRole(testPackageOwner(NEW), testCustomerAdmin(newCustomer));
|
||||
|
||||
call revokeRoleFromRole(testCustomerTenant(oldCustomer), testPackageTenant(OLD));
|
||||
call grantRoleToRole(testCustomerTenant(newCustomer), testPackageTenant(NEW));
|
||||
|
||||
end if;
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to re-wire the grant structure for a new test_package row.
|
||||
*/
|
||||
|
||||
create or replace function updateTriggerForTestPackage_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call updateRbacRulesForTestPackage(OLD, NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger updateTriggerForTestPackage_tg
|
||||
after update on test_package
|
||||
for each row
|
||||
execute procedure updateTriggerForTestPackage_tf();
|
||||
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-package-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO test_package permissions for the related test_customer rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row test_customer;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO test_package permissions for the related test_customer rows');
|
||||
|
||||
FOR row IN SELECT * FROM test_customer
|
||||
LOOP
|
||||
roleUuid := findRoleId(testCustomerAdmin(row));
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'test_package');
|
||||
call grantPermissionToRole(roleUuid, permissionUuid);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds test_package INSERT permission to specified role of new test_customer rows.
|
||||
*/
|
||||
create or replace function test_package_test_customer_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
testCustomerAdmin(NEW),
|
||||
createPermission(NEW.uuid, 'INSERT', 'test_package'));
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger test_package_test_customer_insert_tg
|
||||
after insert on test_customer
|
||||
for each row
|
||||
execute procedure test_package_test_customer_insert_tf();
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to test_package.
|
||||
*/
|
||||
create or replace function test_package_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into test_package not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger test_package_insert_permission_check_tg
|
||||
before insert on test_package
|
||||
for each row
|
||||
when ( not hasInsertPermission(NEW.customerUuid, 'INSERT', 'test_package') )
|
||||
execute procedure test_package_insert_permission_missing_tf();
|
||||
|
||||
--//
|
||||
-- ============================================================================
|
||||
--changeset test-package-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call generateRbacIdentityViewFromProjection('test_package', $idName$
|
||||
name
|
||||
$idName$);
|
||||
|
||||
--//
|
||||
-- ============================================================================
|
||||
--changeset test-package-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('test_package',
|
||||
'name',
|
||||
$updates$
|
||||
version = new.version,
|
||||
customerUuid = new.customerUuid,
|
||||
description = new.description
|
||||
$updates$);
|
||||
--//
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ begin
|
||||
|
||||
custAdminUser = 'customer-admin@' || cust.prefix || '.example.com';
|
||||
custAdminRole = 'test_customer#' || cust.prefix || '.admin';
|
||||
call defineContext(currentTask, null, custAdminUser, custAdminRole);
|
||||
call defineContext(currentTask, null, 'superuser-fran@hostsharing.net', custAdminRole);
|
||||
raise notice 'task: % by % as %', currentTask, custAdminUser, custAdminRole;
|
||||
|
||||
insert
|
||||
@ -35,7 +35,7 @@ begin
|
||||
returning * into pac;
|
||||
|
||||
call grantRoleToUser(
|
||||
getRoleId(testCustomerAdmin(cust), 'fail'),
|
||||
getRoleId(testCustomerAdmin(cust)),
|
||||
findRoleId(testPackageAdmin(pac)),
|
||||
createRbacUser('pac-admin-' || pacName || '@' || cust.prefix || '.example.com'),
|
||||
true);
|
||||
|
88
src/main/resources/db/changelog/133-test-domain-rbac.md
Normal file
88
src/main/resources/db/changelog/133-test-domain-rbac.md
Normal file
@ -0,0 +1,88 @@
|
||||
### rbac domain
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-11T11:29:11.644658132.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph package.customer["`**package.customer**`"]
|
||||
direction TB
|
||||
style package.customer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph package.customer:roles[ ]
|
||||
style package.customer:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:package.customer:owner[[package.customer:owner]]
|
||||
role:package.customer:admin[[package.customer:admin]]
|
||||
role:package.customer:tenant[[package.customer:tenant]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph package["`**package**`"]
|
||||
direction TB
|
||||
style package fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph package.customer["`**package.customer**`"]
|
||||
direction TB
|
||||
style package.customer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph package.customer:roles[ ]
|
||||
style package.customer:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:package.customer:owner[[package.customer:owner]]
|
||||
role:package.customer:admin[[package.customer:admin]]
|
||||
role:package.customer:tenant[[package.customer:tenant]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph package:roles[ ]
|
||||
style package:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:package:owner[[package:owner]]
|
||||
role:package:admin[[package:admin]]
|
||||
role:package:tenant[[package:tenant]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph domain["`**domain**`"]
|
||||
direction TB
|
||||
style domain fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph domain:roles[ ]
|
||||
style domain:roles fill:#dd4901,stroke:white
|
||||
|
||||
role:domain:owner[[domain:owner]]
|
||||
role:domain:admin[[domain:admin]]
|
||||
end
|
||||
|
||||
subgraph domain:permissions[ ]
|
||||
style domain:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:domain:INSERT{{domain:INSERT}}
|
||||
perm:domain:DELETE{{domain:DELETE}}
|
||||
perm:domain:UPDATE{{domain:UPDATE}}
|
||||
perm:domain:SELECT{{domain:SELECT}}
|
||||
end
|
||||
end
|
||||
|
||||
%% granting roles to roles
|
||||
role:global:admin -.->|XX| role:package.customer:owner
|
||||
role:package.customer:owner -.-> role:package.customer:admin
|
||||
role:package.customer:admin -.-> role:package.customer:tenant
|
||||
role:package.customer:admin -.-> role:package:owner
|
||||
role:package:owner -.-> role:package:admin
|
||||
role:package:admin -.-> role:package:tenant
|
||||
role:package:tenant -.-> role:package.customer:tenant
|
||||
role:package:admin ==> role:domain:owner
|
||||
role:domain:owner ==> role:package:tenant
|
||||
role:domain:owner ==> role:domain:admin
|
||||
role:domain:admin ==> role:package:tenant
|
||||
|
||||
%% granting permissions to roles
|
||||
role:package:admin ==> perm:domain:INSERT
|
||||
role:domain:owner ==> perm:domain:DELETE
|
||||
role:domain:owner ==> perm:domain:UPDATE
|
||||
role:domain:admin ==> perm:domain:SELECT
|
||||
|
||||
```
|
@ -1,4 +1,5 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator at 2024-03-11T11:29:11.645391647.
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-domain-rbac-OBJECT:1 endDelimiter:--//
|
||||
@ -11,107 +12,214 @@ call generateRelatedRbacObject('test_domain');
|
||||
--changeset test-domain-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRoleDescriptors('testDomain', 'test_domain');
|
||||
|
||||
create or replace function createTestDomainTenantRoleIfNotExists(domain test_domain)
|
||||
returns uuid
|
||||
returns null on null input
|
||||
language plpgsql as $$
|
||||
declare
|
||||
domainTenantRoleDesc RbacRoleDescriptor;
|
||||
domainTenantRoleUuid uuid;
|
||||
begin
|
||||
domainTenantRoleDesc = testdomainTenant(domain);
|
||||
domainTenantRoleUuid = findRoleId(domainTenantRoleDesc);
|
||||
if domainTenantRoleUuid is not null then
|
||||
return domainTenantRoleUuid;
|
||||
end if;
|
||||
|
||||
return createRoleWithGrants(
|
||||
domainTenantRoleDesc,
|
||||
permissions => array['view'],
|
||||
incomingSuperRoles => array[testdomainAdmin(domain)]
|
||||
);
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-domain-rbac-ROLES-CREATION:1 endDelimiter:--//
|
||||
--changeset test-domain-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles and their assignments for a new domain for the AFTER INSERT TRIGGER.
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace function createRbacRulesForTestDomain()
|
||||
create or replace procedure buildRbacSystemForTestDomain(
|
||||
NEW test_domain
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
newPackage test_package;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
SELECT * FROM test_package p
|
||||
WHERE p.uuid= NEW.packageUuid
|
||||
into newPackage;
|
||||
|
||||
perform createRoleWithGrants(
|
||||
testDomainOwner(NEW),
|
||||
permissions => array['DELETE', 'UPDATE'],
|
||||
incomingSuperRoles => array[testPackageAdmin(newPackage)],
|
||||
outgoingSubRoles => array[testPackageTenant(newPackage)]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
testDomainAdmin(NEW),
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[testDomainOwner(NEW)],
|
||||
outgoingSubRoles => array[testPackageTenant(newPackage)]
|
||||
);
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new test_domain row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForTestDomain_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
declare
|
||||
parentPackage test_package;
|
||||
begin
|
||||
if TG_OP <> 'INSERT' then
|
||||
raise exception 'invalid usage of TRIGGER AFTER INSERT';
|
||||
end if;
|
||||
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
select * from test_package where uuid = NEW.packageUuid into parentPackage;
|
||||
|
||||
-- an owner role is created and assigned to the package's admin group
|
||||
perform createRoleWithGrants(
|
||||
testDomainOwner(NEW),
|
||||
permissions => array['*'],
|
||||
incomingSuperRoles => array[testPackageAdmin(parentPackage)]
|
||||
);
|
||||
|
||||
-- and a domain admin role is created and assigned to the domain owner as well
|
||||
perform createRoleWithGrants(
|
||||
testDomainAdmin(NEW),
|
||||
permissions => array['edit'],
|
||||
incomingSuperRoles => array[testDomainOwner(NEW)],
|
||||
outgoingSubRoles => array[testPackageTenant(parentPackage)]
|
||||
);
|
||||
|
||||
-- a tenent role is only created on demand
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
call buildRbacSystemForTestDomain(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
|
||||
/*
|
||||
An AFTER INSERT TRIGGER which creates the role structure for a new domain.
|
||||
*/
|
||||
drop trigger if exists createRbacRulesForTestDomain_Trigger on test_domain;
|
||||
create trigger createRbacRulesForTestDomain_Trigger
|
||||
after insert
|
||||
on test_domain
|
||||
create trigger insertTriggerForTestDomain_tg
|
||||
after insert on test_domain
|
||||
for each row
|
||||
execute procedure createRbacRulesForTestDomain();
|
||||
execute procedure insertTriggerForTestDomain_tf();
|
||||
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-domain-rbac-update-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
|
||||
*/
|
||||
|
||||
create or replace procedure updateRbacRulesForTestDomain(
|
||||
OLD test_domain,
|
||||
NEW test_domain
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
oldPackage test_package;
|
||||
newPackage test_package;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM test_package p
|
||||
WHERE p.uuid= OLD.packageUuid
|
||||
into oldPackage;
|
||||
SELECT * FROM test_package p
|
||||
WHERE p.uuid= NEW.packageUuid
|
||||
into newPackage;
|
||||
|
||||
if NEW.packageUuid <> OLD.packageUuid then
|
||||
|
||||
call revokePermissionFromRole(findPermissionId(OLD.uuid, 'INSERT'), testPackageAdmin(oldPackage));
|
||||
|
||||
call revokeRoleFromRole(testDomainOwner(OLD), testPackageAdmin(oldPackage));
|
||||
call grantRoleToRole(testDomainOwner(NEW), testPackageAdmin(newPackage));
|
||||
|
||||
call revokeRoleFromRole(testPackageTenant(oldPackage), testDomainOwner(OLD));
|
||||
call grantRoleToRole(testPackageTenant(newPackage), testDomainOwner(NEW));
|
||||
|
||||
call revokeRoleFromRole(testPackageTenant(oldPackage), testDomainAdmin(OLD));
|
||||
call grantRoleToRole(testPackageTenant(newPackage), testDomainAdmin(NEW));
|
||||
|
||||
end if;
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to re-wire the grant structure for a new test_domain row.
|
||||
*/
|
||||
|
||||
create or replace function updateTriggerForTestDomain_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call updateRbacRulesForTestDomain(OLD, NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger updateTriggerForTestDomain_tg
|
||||
after update on test_domain
|
||||
for each row
|
||||
execute procedure updateTriggerForTestDomain_tf();
|
||||
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-domain-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO test_domain permissions for the related test_package rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row test_package;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO test_domain permissions for the related test_package rows');
|
||||
|
||||
FOR row IN SELECT * FROM test_package
|
||||
LOOP
|
||||
roleUuid := findRoleId(testPackageAdmin(row));
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'test_domain');
|
||||
call grantPermissionToRole(roleUuid, permissionUuid);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds test_domain INSERT permission to specified role of new test_package rows.
|
||||
*/
|
||||
create or replace function test_domain_test_package_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
testPackageAdmin(NEW),
|
||||
createPermission(NEW.uuid, 'INSERT', 'test_domain'));
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger test_domain_test_package_insert_tg
|
||||
after insert on test_package
|
||||
for each row
|
||||
execute procedure test_domain_test_package_insert_tf();
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to test_domain.
|
||||
*/
|
||||
create or replace function test_domain_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into test_domain not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger test_domain_insert_permission_check_tg
|
||||
before insert on test_domain
|
||||
for each row
|
||||
when ( not hasInsertPermission(NEW.packageUuid, 'INSERT', 'test_domain') )
|
||||
execute procedure test_domain_insert_permission_missing_tf();
|
||||
|
||||
--//
|
||||
-- ============================================================================
|
||||
--changeset test-domain-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('test_domain', $idName$
|
||||
target.name
|
||||
|
||||
call generateRbacIdentityViewFromProjection('test_domain', $idName$
|
||||
name
|
||||
$idName$);
|
||||
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset test-domain-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
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_domain_rv;
|
||||
create or replace view test_domain_rv as
|
||||
select target.*
|
||||
from test_domain as target
|
||||
where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'domain', currentSubjectsUuids()));
|
||||
grant all privileges on test_domain_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||
call generateRbacRestrictedView('test_domain',
|
||||
'name',
|
||||
$updates$
|
||||
version = new.version,
|
||||
packageUuid = new.packageUuid,
|
||||
description = new.description
|
||||
$updates$);
|
||||
--//
|
||||
|
||||
|
||||
|
@ -33,7 +33,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeContactOwner(NEW),
|
||||
permissions => array['*'],
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalAdmin()],
|
||||
userUuids => array[currentUserUuid()],
|
||||
grantedByRole => globalAdmin()
|
||||
@ -41,7 +41,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeContactAdmin(NEW),
|
||||
permissions => array['edit'],
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[hsOfficeContactOwner(NEW)]
|
||||
);
|
||||
|
||||
@ -52,7 +52,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeContactGuest(NEW),
|
||||
permissions => array['view'],
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[hsOfficeContactTenant(NEW)]
|
||||
);
|
||||
|
||||
@ -75,7 +75,7 @@ execute procedure createRbacRolesForHsOfficeContact();
|
||||
--changeset hs-office-contact-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call generateRbacIdentityView('hs_office_contact', $idName$
|
||||
call generateRbacIdentityViewFromProjection('hs_office_contact', $idName$
|
||||
target.label
|
||||
$idName$);
|
||||
--//
|
||||
|
@ -31,16 +31,16 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficePersonOwner(NEW),
|
||||
permissions => array['*'],
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalAdmin()],
|
||||
userUuids => array[currentUserUuid()],
|
||||
grantedByRole => globalAdmin()
|
||||
);
|
||||
|
||||
-- TODO: who is admin? the person itself? is it allowed for the person itself or a representative to edit the data?
|
||||
-- TODO: who is admin? the person itself? is it allowed for the person itself or a representative to update the data?
|
||||
perform createRoleWithGrants(
|
||||
hsOfficePersonAdmin(NEW),
|
||||
permissions => array['edit'],
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[hsOfficePersonOwner(NEW)]
|
||||
);
|
||||
|
||||
@ -51,7 +51,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficePersonGuest(NEW),
|
||||
permissions => array['view'],
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[hsOfficePersonTenant(NEW)]
|
||||
);
|
||||
|
||||
@ -73,7 +73,7 @@ execute procedure createRbacRolesForHsOfficePerson();
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('hs_office_person', $idName$
|
||||
call generateRbacIdentityViewFromProjection('hs_office_person', $idName$
|
||||
concat(target.tradeName, target.familyName, target.givenName)
|
||||
$idName$);
|
||||
--//
|
||||
|
@ -42,151 +42,3 @@ subgraph hsOfficeRelationship
|
||||
end
|
||||
```
|
||||
|
||||
if TG_OP = 'INSERT' then
|
||||
|
||||
-- the owner role with full access for admins of the relAnchor global admins
|
||||
ownerRole = createRole(
|
||||
hsOfficeRelationshipOwner(NEW),
|
||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['*']),
|
||||
beneathRoles(array[
|
||||
globalAdmin(),
|
||||
hsOfficePersonAdmin(newRelAnchor)])
|
||||
);
|
||||
|
||||
-- the admin role with full access for the owner
|
||||
adminRole = createRole(
|
||||
hsOfficeRelationshipAdmin(NEW),
|
||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['edit']),
|
||||
beneathRole(ownerRole)
|
||||
);
|
||||
|
||||
-- the tenant role for those related users who can view the data
|
||||
perform createRole(
|
||||
hsOfficeRelationshipTenant,
|
||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['view']),
|
||||
beneathRoles(array[
|
||||
hsOfficePersonAdmin(newRelAnchor),
|
||||
hsOfficePersonAdmin(newRelHolder),
|
||||
hsOfficeContactAdmin(newContact)]),
|
||||
withSubRoles(array[
|
||||
hsOfficePersonTenant(newRelAnchor),
|
||||
hsOfficePersonTenant(newRelHolder),
|
||||
hsOfficeContactTenant(newContact)])
|
||||
);
|
||||
|
||||
-- anchor and holder admin roles need each others tenant role
|
||||
-- to be able to see the joined relationship
|
||||
call grantRoleToRole(hsOfficePersonTenant(newRelAnchor), hsOfficePersonAdmin(newRelHolder));
|
||||
call grantRoleToRole(hsOfficePersonTenant(newRelHolder), hsOfficePersonAdmin(newRelAnchor));
|
||||
call grantRoleToRoleIfNotNull(hsOfficePersonTenant(newRelHolder), hsOfficeContactAdmin(newContact));
|
||||
|
||||
elsif TG_OP = 'UPDATE' then
|
||||
|
||||
if OLD.contactUuid <> NEW.contactUuid then
|
||||
-- nothing but the contact can be updated,
|
||||
-- in other cases, a new relationship needs to be created and the old updated
|
||||
|
||||
select * from hs_office_contact as c where c.uuid = OLD.contactUuid into oldContact;
|
||||
|
||||
call revokeRoleFromRole( hsOfficeRelationshipTenant, hsOfficeContactAdmin(oldContact) );
|
||||
call grantRoleToRole( hsOfficeRelationshipTenant, hsOfficeContactAdmin(newContact) );
|
||||
|
||||
call revokeRoleFromRole( hsOfficeContactTenant(oldContact), hsOfficeRelationshipTenant );
|
||||
call grantRoleToRole( hsOfficeContactTenant(newContact), hsOfficeRelationshipTenant );
|
||||
end if;
|
||||
else
|
||||
raise exception 'invalid usage of TRIGGER';
|
||||
end if;
|
||||
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
An AFTER INSERT TRIGGER which creates the role structure for a new customer.
|
||||
*/
|
||||
create trigger createRbacRolesForHsOfficeRelationship_Trigger
|
||||
after insert
|
||||
on hs_office_relationship
|
||||
for each row
|
||||
execute procedure hsOfficeRelationshipRbacRolesTrigger();
|
||||
|
||||
/*
|
||||
An AFTER UPDATE TRIGGER which updates the role structure of a customer.
|
||||
*/
|
||||
create trigger updateRbacRolesForHsOfficeRelationship_Trigger
|
||||
after update
|
||||
on hs_office_relationship
|
||||
for each row
|
||||
execute procedure hsOfficeRelationshipRbacRolesTrigger();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relationship-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('hs_office_relationship', $idName$
|
||||
(select idName from hs_office_person_iv p where p.uuid = target.relAnchorUuid)
|
||||
|| '-with-' || target.relType || '-' ||
|
||||
(select idName from hs_office_person_iv p where p.uuid = target.relHolderUuid)
|
||||
$idName$);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relationship-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('hs_office_relationship',
|
||||
'(select idName from hs_office_person_iv p where p.uuid = target.relHolderUuid)',
|
||||
$updates$
|
||||
contactUuid = new.contactUuid
|
||||
$updates$);
|
||||
--//
|
||||
|
||||
-- TODO: exception if one tries to amend any other column
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relationship-rbac-NEW-RELATHIONSHIP:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Creates a global permission for new-relationship and assigns it to the hostsharing admins role.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
addCustomerPermissions uuid[];
|
||||
globalObjectUuid uuid;
|
||||
globalAdminRoleUuid uuid ;
|
||||
begin
|
||||
call defineContext('granting global new-relationship permission to global admin role', null, null, null);
|
||||
|
||||
globalAdminRoleUuid := findRoleId(globalAdmin());
|
||||
globalObjectUuid := (select uuid from global);
|
||||
addCustomerPermissions := createPermissions(globalObjectUuid, array ['new-relationship']);
|
||||
call grantPermissionsToRole(globalAdminRoleUuid, addCustomerPermissions);
|
||||
end;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Used by the trigger to prevent the add-customer to current user respectively assumed roles.
|
||||
*/
|
||||
create or replace function addHsOfficeRelationshipNotAllowedForCurrentSubjects()
|
||||
returns trigger
|
||||
language PLPGSQL
|
||||
as $$
|
||||
begin
|
||||
raise exception '[403] new-relationship not permitted for %',
|
||||
array_to_string(currentSubjects(), ';', 'null');
|
||||
end; $$;
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to create a new customer.
|
||||
*/
|
||||
create trigger hs_office_relationship_insert_trigger
|
||||
before insert
|
||||
on hs_office_relationship
|
||||
for each row
|
||||
-- TODO.spec: who is allowed to create new relationships
|
||||
when ( not hasAssumedRole() )
|
||||
execute procedure addHsOfficeRelationshipNotAllowedForCurrentSubjects();
|
||||
--//
|
||||
|
||||
|
@ -45,7 +45,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeRelationshipOwner(NEW),
|
||||
permissions => array['*'],
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[
|
||||
globalAdmin(),
|
||||
hsOfficePersonAdmin(newRelAnchor)]
|
||||
@ -53,14 +53,14 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeRelationshipAdmin(NEW),
|
||||
permissions => array['edit'],
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[hsOfficeRelationshipOwner(NEW)]
|
||||
);
|
||||
|
||||
-- the tenant role for those related users who can view the data
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeRelationshipTenant,
|
||||
permissions => array['view'],
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[
|
||||
hsOfficeRelationshipAdmin(NEW),
|
||||
hsOfficePersonAdmin(newRelAnchor),
|
||||
@ -124,7 +124,7 @@ execute procedure hsOfficeRelationshipRbacRolesTrigger();
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relationship-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('hs_office_relationship', $idName$
|
||||
call generateRbacIdentityViewFromProjection('hs_office_relationship', $idName$
|
||||
(select idName from hs_office_person_iv p where p.uuid = target.relAnchorUuid)
|
||||
|| '-with-' || target.relType || '-' ||
|
||||
(select idName from hs_office_person_iv p where p.uuid = target.relHolderUuid)
|
||||
|
@ -48,13 +48,13 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficePartnerOwner(NEW),
|
||||
permissions => array['*'],
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalAdmin()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficePartnerAdmin(NEW),
|
||||
permissions => array['edit'],
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[
|
||||
hsOfficePartnerOwner(NEW)],
|
||||
outgoingSubRoles => array[
|
||||
@ -84,7 +84,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficePartnerGuest(NEW),
|
||||
permissions => array['view'],
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[hsOfficePartnerTenant(NEW)]
|
||||
);
|
||||
|
||||
@ -98,21 +98,21 @@ begin
|
||||
--Attention: Cannot be in partner-details because of insert order (partner is not in database yet)
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficePartnerOwner(NEW), 'fail'),
|
||||
createPermissions(NEW.detailsUuid, array ['*'])
|
||||
getRoleId(hsOfficePartnerOwner(NEW)),
|
||||
createPermissions(NEW.detailsUuid, array ['DELETE'])
|
||||
);
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficePartnerAdmin(NEW), 'fail'),
|
||||
createPermissions(NEW.detailsUuid, array ['edit'])
|
||||
getRoleId(hsOfficePartnerAdmin(NEW)),
|
||||
createPermissions(NEW.detailsUuid, array ['UPDATE'])
|
||||
);
|
||||
|
||||
call grantPermissionsToRole(
|
||||
-- Yes, here hsOfficePartnerAGENT is used, not hsOfficePartnerTENANT.
|
||||
-- Do NOT grant view permission on partner-details to hsOfficePartnerTENANT!
|
||||
-- Otherwise package-admins etc. would be able to read the data.
|
||||
getRoleId(hsOfficePartnerAgent(NEW), 'fail'),
|
||||
createPermissions(NEW.detailsUuid, array ['view'])
|
||||
getRoleId(hsOfficePartnerAgent(NEW)),
|
||||
createPermissions(NEW.detailsUuid, array ['SELECT'])
|
||||
);
|
||||
|
||||
|
||||
@ -187,7 +187,7 @@ execute procedure hsOfficePartnerRbacRolesTrigger();
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('hs_office_partner', $idName$
|
||||
call generateRbacIdentityViewFromProjection('hs_office_partner', $idName$
|
||||
partnerNumber || ':' ||
|
||||
(select idName from hs_office_person_iv p where p.uuid = target.personuuid)
|
||||
|| '-' ||
|
||||
|
@ -7,13 +7,10 @@ call generateRelatedRbacObject('hs_office_partner_details');
|
||||
--//
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-details-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('hs_office_partner_details', $idName$
|
||||
call generateRbacIdentityViewFromProjection('hs_office_partner_details', $idName$
|
||||
(select idName || '-details' from hs_office_partner_iv partner_iv
|
||||
join hs_office_partner partner on (partner_iv.uuid = partner.uuid)
|
||||
where partner.detailsUuid = target.uuid)
|
||||
@ -38,7 +35,7 @@ call generateRbacRestrictedView('hs_office_partner_details',
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-details-rbac-NEW-CONTACT:1 endDelimiter:--//
|
||||
--changeset hs-office-partner-details-rbac-NEW-PARTNER-DETAILS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Creates a global permission for new-partner-details and assigns it to the hostsharing admins role.
|
||||
|
@ -4,14 +4,14 @@
|
||||
flowchart TB
|
||||
|
||||
subgraph global
|
||||
style hsOfficeBankAccount fill: #e9f7ef
|
||||
style global fill: lightgray
|
||||
|
||||
role:global.admin[global.admin]
|
||||
end
|
||||
|
||||
subgraph hsOfficeBankAccount
|
||||
direction TB
|
||||
style hsOfficeBankAccount fill: #e9f7ef
|
||||
style hsOfficeBankAccount fill: lightgreen
|
||||
|
||||
user:hsOfficeBankAccount.creator([bankAccount.creator])
|
||||
|
||||
|
@ -33,7 +33,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeBankAccountOwner(NEW),
|
||||
permissions => array['delete'],
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalAdmin()],
|
||||
userUuids => array[currentUserUuid()],
|
||||
grantedByRole => globalAdmin()
|
||||
@ -51,7 +51,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeBankAccountGuest(NEW),
|
||||
permissions => array['view'],
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[hsOfficeBankAccountTenant(NEW)]
|
||||
);
|
||||
|
||||
@ -74,7 +74,7 @@ execute procedure createRbacRolesForHsOfficeBankAccount();
|
||||
--changeset hs-office-bankaccount-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call generateRbacIdentityView('hs_office_bankaccount', $idName$
|
||||
call generateRbacIdentityViewFromProjection('hs_office_bankaccount', $idName$
|
||||
target.holder
|
||||
$idName$);
|
||||
--//
|
||||
|
@ -41,13 +41,13 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeSepaMandateOwner(NEW),
|
||||
permissions => array['*'],
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalAdmin()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeSepaMandateAdmin(NEW),
|
||||
permissions => array['edit'],
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[hsOfficeSepaMandateOwner(NEW)],
|
||||
outgoingSubRoles => array[hsOfficeBankAccountTenant(newHsOfficeBankAccount)]
|
||||
);
|
||||
@ -66,7 +66,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeSepaMandateGuest(NEW),
|
||||
permissions => array['view'],
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[hsOfficeSepaMandateTenant(NEW)]
|
||||
);
|
||||
|
||||
@ -94,7 +94,7 @@ execute procedure hsOfficeSepaMandateRbacRolesTrigger();
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('hs_office_sepamandate', idNameExpression => 'target.reference');
|
||||
call generateRbacIdentityViewFromProjection('hs_office_sepamandate', 'target.reference');
|
||||
--//
|
||||
|
||||
|
||||
|
@ -49,7 +49,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeDebitorOwner(NEW),
|
||||
permissions => array['*'],
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalAdmin()],
|
||||
userUuids => array[currentUserUuid()],
|
||||
grantedByRole => globalAdmin()
|
||||
@ -57,7 +57,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeDebitorAdmin(NEW),
|
||||
permissions => array['edit'],
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[hsOfficeDebitorOwner(NEW)]
|
||||
);
|
||||
|
||||
@ -85,7 +85,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeDebitorGuest(NEW),
|
||||
permissions => array['view'],
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[
|
||||
hsOfficeDebitorTenant(NEW)]
|
||||
);
|
||||
@ -173,7 +173,7 @@ execute procedure hsOfficeDebitorRbacRolesTrigger();
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('hs_office_debitor', $idName$
|
||||
call generateRbacIdentityViewFromProjection('hs_office_debitor', $idName$
|
||||
'#' ||
|
||||
(select partnerNumber from hs_office_partner p where p.uuid = target.partnerUuid) ||
|
||||
to_char(debitorNumberSuffix, 'fm00') ||
|
||||
|
@ -41,13 +41,13 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeMembershipOwner(NEW),
|
||||
permissions => array['*'],
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalAdmin()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeMembershipAdmin(NEW),
|
||||
permissions => array['edit'],
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[hsOfficeMembershipOwner(NEW)]
|
||||
);
|
||||
|
||||
@ -65,7 +65,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeMembershipGuest(NEW),
|
||||
permissions => array['view'],
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[hsOfficeMembershipTenant(NEW), hsOfficePartnerTenant(newHsOfficePartner), hsOfficeDebitorTenant(newHsOfficeDebitor)]
|
||||
);
|
||||
|
||||
@ -93,7 +93,7 @@ execute procedure hsOfficeMembershipRbacRolesTrigger();
|
||||
-- ============================================================================
|
||||
--changeset hs-office-membership-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('hs_office_membership', idNameExpression => $idName$
|
||||
call generateRbacIdentityViewFromProjection('hs_office_membership', $idName$
|
||||
'#' ||
|
||||
(select partnerNumber from hs_office_partner p where p.uuid = target.partnerUuid) ||
|
||||
memberNumberSuffix ||
|
||||
|
@ -42,8 +42,8 @@ begin
|
||||
|
||||
-- coopsharestransactions cannot be edited nor deleted, just created+viewed
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeMembershipTenant(newHsOfficeMembership), 'fail'),
|
||||
createPermissions(NEW.uuid, array ['view'])
|
||||
getRoleId(hsOfficeMembershipTenant(newHsOfficeMembership)),
|
||||
createPermissions(NEW.uuid, array ['SELECT'])
|
||||
);
|
||||
|
||||
else
|
||||
@ -68,8 +68,7 @@ execute procedure hsOfficeCoopSharesTransactionRbacRolesTrigger();
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopSharesTransaction-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('hs_office_coopSharesTransaction',
|
||||
idNameExpression => 'target.reference');
|
||||
call generateRbacIdentityViewFromProjection('hs_office_coopSharesTransaction', 'target.reference');
|
||||
--//
|
||||
|
||||
|
||||
|
@ -42,8 +42,8 @@ begin
|
||||
|
||||
-- coopassetstransactions cannot be edited nor deleted, just created+viewed
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeMembershipTenant(newHsOfficeMembership), 'fail'),
|
||||
createPermissions(NEW.uuid, array ['view'])
|
||||
getRoleId(hsOfficeMembershipTenant(newHsOfficeMembership)),
|
||||
createPermissions(NEW.uuid, array ['SELECT'])
|
||||
);
|
||||
|
||||
else
|
||||
@ -68,8 +68,7 @@ execute procedure hsOfficeCoopAssetsTransactionRbacRolesTrigger();
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopAssetsTransaction-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityView('hs_office_coopAssetsTransaction',
|
||||
idNameExpression => 'target.reference');
|
||||
call generateRbacIdentityViewFromProjection('hs_office_coopAssetsTransaction', 'target.reference');
|
||||
--//
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user