1
0

add RbacUser* tests and improved http status codes

This commit is contained in:
Michael Hoennig
2022-08-05 14:31:54 +02:00
parent f2bc42bd85
commit bef358eda6
16 changed files with 540 additions and 73 deletions

View File

@ -391,6 +391,19 @@ select exists(
);
$$;
create or replace function hasGlobalRoleGranted(userUuid uuid)
returns bool
stable leakproof
language sql as $$
select exists(
select r.uuid
from RbacGrants as g
join RbacRole as r on r.uuid = g.descendantuuid
join RbacObject as o on o.uuid = r.objectuuid
where g.ascendantuuid = userUuid and o.objecttable = 'global'
);
$$;
create or replace procedure grantPermissionsToRole(roleUuid uuid, permissionIds uuid[])
language plpgsql as $$
begin
@ -417,7 +430,7 @@ begin
perform assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole');
if (isGranted(subRoleId, superRoleId)) then
raise exception 'Cyclic role grant detected between % and %', subRoleId, superRoleId;
raise exception '[400] Cyclic role grant detected between % and %', subRoleId, superRoleId;
end if;
insert
@ -487,7 +500,7 @@ begin
foundRows = lastRowCount();
if foundRows > maxObjects then
raise exception 'Too many accessible objects, limit is %, found %.', maxObjects, foundRows
raise exception '[400] Too many accessible objects, limit is %, found %.', maxObjects, foundRows
using
errcode = 'P0003',
hint = 'Please assume a sub-role and try again.';

View File

@ -21,7 +21,7 @@ begin
currentUser := null;
end;
if (currentUser is null or currentUser = '') then
raise exception 'hsadminng.currentUser must be defined, please use "SET LOCAL ...;"';
raise exception '[401] hsadminng.currentUser must be defined, please use "SET LOCAL ...;"';
end if;
return currentUser;
end; $$;
@ -37,7 +37,7 @@ begin
currentUser := currentUser();
currentUserId = (select uuid from RbacUser where name = currentUser);
if currentUserId is null then
raise exception 'hsadminng.currentUser defined as %, but does not exists', currentUser;
raise exception '[401] hsadminng.currentUser defined as %, but does not exists', currentUser;
end if;
return currentUserId;
end; $$;
@ -150,7 +150,7 @@ declare
begin
currentUserId := currentUserId();
if currentUserId is null then
raise exception 'user % does not exist', currentUser();
raise exception '[401] user % does not exist', currentUser();
end if;
roleNames := assumedRoles();
@ -176,7 +176,7 @@ begin
and r.roleType = roleTypeToAssume
into roleUuidToAssume;
if (not isGranted(currentUserId, roleUuidToAssume)) then
raise exception 'user % (%) has no permission to assume role % (%)', currentUser(), currentUserId, roleName, roleUuidToAssume;
raise exception '[403] user % (%) has no permission to assume role % (%)', currentUser(), currentUserId, roleName, roleUuidToAssume;
end if;
roleIdsToAssume := roleIdsToAssume || roleUuidToAssume;
end loop;

View File

@ -61,31 +61,45 @@ grant all privileges on RbacOwnGrantedPermissions_rv to restricted;
/*
Returns all permissions granted to the given user,
which are also visible to the current user or assumed roles.
*/
create or replace function grantedPermissions(userName varchar)
returns table(roleUuid uuid, roleName text, permissionUuid uuid, op RbacOp, objectTable varchar, objectIdName varchar, objectUuid uuid)
returns null on null input
language plpgsql as $$
declare
targetUserId uuid;
currentUserId uuid;
begin
-- @formatter:off
if cardinality(assumedRoles()) > 0 then
raise exception 'grantedPermissions(...) does not support assumed roles';
raise exception '[400] grantedPermissions(...) does not support assumed roles';
end if;
targetUserId := findRbacUserId(userName);
currentUserId := currentUserId();
if hasGlobalRoleGranted(targetUserId) and not hasGlobalRoleGranted(currentUserId) then
raise exception '[403] permissions of user "%" are not accessible to user "%"', userName, currentUser();
end if;
return query select
xp.roleUuid,
(xp.objecttable || '#' || xp.objectidname || '.' || xp.roletype) as roleName,
xp.permissionUuid, xp.op, xp.objecttable, xp.objectIdName, xp.objectuuid
(xp.roleObjectTable || '#' || xp.roleObjectIdName || '.' || xp.roleType) as roleName,
xp.permissionUuid, xp.op, xp.permissionObjectTable, xp.permissionObjectIdName, xp.permissionObjectUuid
from (select
r.uuid as roleUuid, r.roletype,
p.uuid as permissionUuid, p.op, o.objecttable,
findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName,
o.uuid as objectuuid
from queryPermissionsGrantedToSubjectId( findRbacUserId(userName)) p
join rbacgrants g on g.descendantuuid = p.uuid
join rbacobject o on o.uuid = p.objectuuid
join rbacrole r on r.uuid = g.ascendantuuid
where isGranted(currentUserId(), r.uuid)
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,
findIdNameByObjectUuid(po.objectTable, po.uuid) as permissionObjectIdName,
po.uuid as permissionObjectUuid
from queryPermissionsGrantedToSubjectId( targetUserId) as p
join rbacgrants as g on g.descendantUuid = p.uuid
join rbacobject as po on po.uuid = p.objectUuid
join rbacrole_rv as r on r.uuid = g.ascendantUuid
join rbacobject as ro on ro.uuid = r.objectUuid
where isGranted(targetUserId, r.uuid)
) xp;
-- @formatter:on
end; $$;

View File

@ -220,7 +220,7 @@ create or replace function addCustomerNotAllowedForCurrentSubjects()
language PLPGSQL
as $$
begin
raise exception 'add-customer not permitted for %', array_to_string(currentSubjects(), ';', 'null');
raise exception '[403] add-customer not permitted for %', array_to_string(currentSubjects(), ';', 'null');
end; $$;
/**

View File

@ -12,10 +12,11 @@ create or replace procedure createPackageTestData(
)
language plpgsql as $$
declare
cust customer;
pacName varchar;
currentTask varchar;
custAdmin varchar;
cust customer;
pacName varchar;
currentTask varchar;
custAdmin varchar;
pac package;
begin
set hsadminng.currentUser to '';
@ -37,7 +38,13 @@ create or replace procedure createPackageTestData(
insert
into package (name, customerUuid)
values (pacName, cust.uuid);
values (pacName, cust.uuid)
returning * into pac;
call grantRoleToUser(
findRoleId(packageAdmin(pac)),
createRbacUser(pacName || '@' || cust.prefix || '.example.com'));
end loop;
end loop;