2022-08-23 14:36:22 +02:00
|
|
|
--liquibase formatted sql
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
--changeset rbac-context-CURRENT-USER-ID:1 endDelimiter:--//
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Returns the id of the current user as set by `hsadminng.currentUser`.
|
|
|
|
Raises exception if not set.
|
|
|
|
*/
|
|
|
|
|
2022-08-30 09:18:52 +02:00
|
|
|
create or replace function currentUserUuid()
|
2022-08-23 14:36:22 +02:00
|
|
|
returns uuid
|
|
|
|
stable leakproof
|
|
|
|
language plpgsql as $$
|
|
|
|
declare
|
|
|
|
currentUser varchar(63);
|
2022-08-30 09:18:52 +02:00
|
|
|
currentUserUuid uuid;
|
2022-08-23 14:36:22 +02:00
|
|
|
begin
|
|
|
|
currentUser := currentUser();
|
2022-08-30 09:18:52 +02:00
|
|
|
currentUserUuid = (select uuid from RbacUser where name = currentUser);
|
|
|
|
if currentUserUuid is null then
|
2022-08-23 14:36:22 +02:00
|
|
|
raise exception '[401] hsadminng.currentUser defined as %, but does not exists', currentUser;
|
|
|
|
end if;
|
2022-08-30 09:18:52 +02:00
|
|
|
return currentUserUuid;
|
2022-08-23 14:36:22 +02:00
|
|
|
end; $$;
|
|
|
|
--//
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
|
|
--changeset rbac-context-CURRENT-SUBJECT-IDS:1 endDelimiter:--//
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Returns id of current user as set in `hsadminng.currentUser`
|
|
|
|
or, if any, ids of assumed role names as set in `hsadminng.assumedRoles`
|
|
|
|
or empty array, if not set.
|
|
|
|
*/
|
2022-08-30 09:18:52 +02:00
|
|
|
create or replace function currentSubjectsUuids()
|
2022-08-23 14:36:22 +02:00
|
|
|
returns uuid[]
|
|
|
|
stable leakproof
|
|
|
|
language plpgsql as $$
|
|
|
|
declare
|
2022-08-30 09:18:52 +02:00
|
|
|
currentUserUuid uuid;
|
2022-08-23 14:36:22 +02:00
|
|
|
roleNames varchar(63)[];
|
|
|
|
roleName varchar(63);
|
|
|
|
objectTableToAssume varchar(63);
|
|
|
|
objectNameToAssume varchar(63);
|
|
|
|
objectUuidToAssume uuid;
|
|
|
|
roleTypeToAssume RbacRoleType;
|
|
|
|
roleIdsToAssume uuid[];
|
|
|
|
roleUuidToAssume uuid;
|
|
|
|
begin
|
2022-08-30 09:18:52 +02:00
|
|
|
currentUserUuid := currentUserUuid();
|
|
|
|
if currentUserUuid is null then
|
2022-08-23 14:36:22 +02:00
|
|
|
raise exception '[401] user % does not exist', currentUser();
|
|
|
|
end if;
|
|
|
|
|
|
|
|
roleNames := assumedRoles();
|
|
|
|
if cardinality(roleNames) = 0 then
|
2022-08-30 09:18:52 +02:00
|
|
|
return array [currentUserUuid];
|
2022-08-23 14:36:22 +02:00
|
|
|
end if;
|
|
|
|
|
|
|
|
raise notice 'assuming roles: %', roleNames;
|
|
|
|
|
|
|
|
foreach roleName in array roleNames
|
|
|
|
loop
|
|
|
|
roleName = overlay(roleName placing '#' from length(roleName) + 1 - strpos(reverse(roleName), '.'));
|
|
|
|
objectTableToAssume = split_part(roleName, '#', 1);
|
|
|
|
objectNameToAssume = split_part(roleName, '#', 2);
|
|
|
|
roleTypeToAssume = split_part(roleName, '#', 3);
|
|
|
|
|
|
|
|
objectUuidToAssume = findObjectUuidByIdName(objectTableToAssume, objectNameToAssume);
|
|
|
|
|
|
|
|
-- TODO: either the result needs to be cached at least per transaction or we need to get rid of SELCT in a loop
|
|
|
|
select uuid as roleuuidToAssume
|
|
|
|
from RbacRole r
|
|
|
|
where r.objectUuid = objectUuidToAssume
|
|
|
|
and r.roleType = roleTypeToAssume
|
|
|
|
into roleUuidToAssume;
|
2022-08-30 09:18:52 +02:00
|
|
|
if (not isGranted(currentUserUuid, roleUuidToAssume)) then
|
|
|
|
raise exception '[403] user % (%) has no permission to assume role % (%)', currentUser(), currentUserUuid, roleName, roleUuidToAssume;
|
2022-08-23 14:36:22 +02:00
|
|
|
end if;
|
|
|
|
roleIdsToAssume := roleIdsToAssume || roleUuidToAssume;
|
|
|
|
end loop;
|
|
|
|
|
|
|
|
return roleIdsToAssume;
|
|
|
|
end; $$;
|
|
|
|
--//
|
|
|
|
|