2022-08-23 14:36:22 +02:00
- - liquibase formatted sql
2022-08-30 09:35:59 +02:00
2022-08-23 14:36:22 +02:00
-- ============================================================================
2024-09-16 15:36:37 +02:00
- - changeset michael . hoennig : rbac - context - DETERMINE endDelimiter : - - / /
2022-08-23 14:36:22 +02:00
-- ----------------------------------------------------------------------------
2024-09-16 15:36:37 +02:00
create or replace function rbac . determineCurrentSubjectUuid ( currentSubject varchar )
2022-08-23 14:36:22 +02:00
returns uuid
2024-01-23 15:11:23 +01:00
stable -- leakproof
2022-08-23 14:36:22 +02:00
language plpgsql as $ $
declare
2024-09-16 15:36:37 +02:00
currentSubjectUuid uuid ;
2022-08-23 14:36:22 +02:00
begin
2024-09-16 15:36:37 +02:00
if currentSubject = ' ' then
2022-08-30 09:35:59 +02:00
return null ;
2022-08-23 14:36:22 +02:00
end if ;
2022-08-30 09:35:59 +02:00
2024-09-16 15:36:37 +02:00
select uuid from rbac . subject where name = currentSubject into currentSubjectUuid ;
if currentSubjectUuid is null then
raise exception ' [401] subject % given in `base.defineContext(...)` does not exist ' , currentSubject ;
2022-08-31 16:26:31 +02:00
end if ;
2024-09-16 15:36:37 +02:00
return currentSubjectUuid ;
2022-08-23 14:36:22 +02:00
end ; $ $ ;
2024-09-16 15:36:37 +02:00
create or replace function rbac . determinecurrentsubjectorassumedrolesuuids ( currentSubjectOrAssumedRolesUuids uuid , assumedRoles varchar )
2022-08-23 14:36:22 +02:00
returns uuid [ ]
2024-01-23 15:11:23 +01:00
stable -- leakproof
2022-08-23 14:36:22 +02:00
language plpgsql as $ $
declare
2024-01-23 15:11:23 +01:00
roleName text ;
roleNameParts text ;
2022-08-23 14:36:22 +02:00
objectTableToAssume varchar ( 63 ) ;
objectNameToAssume varchar ( 63 ) ;
objectUuidToAssume uuid ;
2024-09-16 15:36:37 +02:00
roleTypeToAssume rbac . RoleType ;
2022-08-23 14:36:22 +02:00
roleIdsToAssume uuid [ ] ;
roleUuidToAssume uuid ;
begin
2024-09-16 15:36:37 +02:00
if currentSubjectOrAssumedRolesUuids is null then
2022-08-31 16:26:31 +02:00
if length ( coalesce ( assumedRoles , ' ' ) ) > 0 then
2022-08-30 09:35:59 +02:00
raise exception ' [403] undefined has no permission to assume role % ' , assumedRoles ;
else
return array [ ] : : uuid [ ] ;
end if ;
2022-08-23 14:36:22 +02:00
end if ;
2022-08-30 09:35:59 +02:00
if length ( coalesce ( assumedRoles , ' ' ) ) = 0 then
2024-09-16 15:36:37 +02:00
return array [ currentSubjectOrAssumedRolesUuids ] ;
2022-08-23 14:36:22 +02:00
end if ;
2022-08-30 09:35:59 +02:00
foreach roleName in array string_to_array ( assumedRoles , ' ; ' )
2022-08-23 14:36:22 +02:00
loop
2024-04-02 12:01:37 +02:00
roleNameParts = overlay ( roleName placing ' # ' from length ( roleName ) + 1 - strpos ( reverse ( roleName ) , ' : ' ) ) ;
2022-08-30 13:08:29 +02:00
objectTableToAssume = split_part ( roleNameParts , ' # ' , 1 ) ;
objectNameToAssume = split_part ( roleNameParts , ' # ' , 2 ) ;
roleTypeToAssume = split_part ( roleNameParts , ' # ' , 3 ) ;
2022-08-23 14:36:22 +02:00
2024-09-16 15:36:37 +02:00
objectUuidToAssume = base . findObjectUuidByIdName ( objectTableToAssume , objectNameToAssume ) ;
2024-03-26 11:25:18 +01:00
if objectUuidToAssume is null then
2024-09-16 15:36:37 +02:00
raise exception ' [401] object % cannot be found in table % (from roleNameParts=%) ' , objectNameToAssume , objectTableToAssume , roleNameParts ;
2024-03-26 11:25:18 +01:00
end if ;
2022-08-23 14:36:22 +02:00
2024-03-26 11:25:18 +01:00
select uuid
2024-09-16 15:36:37 +02:00
from rbac . role r
2022-08-23 14:36:22 +02:00
where r . objectUuid = objectUuidToAssume
and r . roleType = roleTypeToAssume
into roleUuidToAssume ;
2022-08-30 13:08:29 +02:00
if roleUuidToAssume is null then
2024-09-16 15:36:37 +02:00
raise exception ' [403] role % does not exist or is not accessible for subject % ' , roleName , base . currentSubject ( ) ;
2022-08-30 13:08:29 +02:00
end if ;
2024-09-16 15:36:37 +02:00
if not rbac . isGranted ( currentSubjectOrAssumedRolesUuids , roleUuidToAssume ) then
raise exception ' [403] subject % has no permission to assume role % ' , base . currentSubject ( ) , roleName ;
2022-08-23 14:36:22 +02:00
end if ;
roleIdsToAssume : = roleIdsToAssume | | roleUuidToAssume ;
end loop ;
return roleIdsToAssume ;
end ; $ $ ;
2022-08-30 09:35:59 +02:00
-- ============================================================================
2024-09-16 15:36:37 +02:00
- - changeset michael . hoennig : rbac - context - CONTEXT - DEFINED endDelimiter : - - / /
2022-08-30 09:35:59 +02:00
-- ----------------------------------------------------------------------------
/*
Callback which is called after the context has been ( re - ) defined .
This function will be overwritten by later changesets .
* /
2024-09-16 15:36:37 +02:00
create or replace procedure base . contextDefined (
2024-04-02 13:14:46 +02:00
currentTask varchar ( 127 ) ,
currentRequest text ,
2024-09-16 15:36:37 +02:00
currentSubject varchar ( 63 ) ,
2024-04-02 13:14:46 +02:00
assumedRoles varchar ( 1023 )
2022-08-30 09:35:59 +02:00
)
language plpgsql as $ $
declare
2024-09-16 15:36:37 +02:00
currentSubjectUuid uuid ;
2022-08-30 09:35:59 +02:00
begin
execute format ( ' set local hsadminng.currentTask to %L ' , currentTask ) ;
execute format ( ' set local hsadminng.currentRequest to %L ' , currentRequest ) ;
2024-09-16 15:36:37 +02:00
execute format ( ' set local hsadminng.currentSubject to %L ' , currentSubject ) ;
select rbac . determineCurrentSubjectUuid ( currentSubject ) into currentSubjectUuid ;
execute format ( ' set local hsadminng.currentSubjectUuid to %L ' , coalesce ( currentSubjectUuid : : text , ' ' ) ) ;
2022-08-30 09:35:59 +02:00
execute format ( ' set local hsadminng.assumedRoles to %L ' , assumedRoles ) ;
2024-09-16 15:36:37 +02:00
execute format ( ' set local hsadminng.currentSubjectOrAssumedRolesUuids to %L ' ,
( select array_to_string ( rbac . determinecurrentsubjectorassumedrolesuuids ( currentSubjectUuid , assumedRoles ) , ' ; ' ) ) ) ;
2022-08-30 09:35:59 +02:00
2024-09-16 15:36:37 +02:00
raise notice ' Context defined as: %, %, %, [%] ' , currentTask , currentRequest , currentSubject , assumedRoles ;
2022-08-30 09:35:59 +02:00
end ; $ $ ;
-- ============================================================================
2024-09-16 15:36:37 +02:00
- - changeset michael . hoennig : rbac - context - current - subject - ID endDelimiter : - - / /
2022-08-30 09:35:59 +02:00
-- ----------------------------------------------------------------------------
/*
2024-09-16 15:36:37 +02:00
Returns the uuid of the current subject as set via ` base . defineContext ( . . . ) ` .
2022-08-30 09:35:59 +02:00
* /
2024-09-16 15:36:37 +02:00
create or replace function rbac . currentSubjectUuid ( )
2022-08-30 09:35:59 +02:00
returns uuid
2024-01-23 15:11:23 +01:00
stable -- leakproof
2022-08-30 09:35:59 +02:00
language plpgsql as $ $
declare
2024-09-16 15:36:37 +02:00
currentSubjectUuid text ;
currentSubjectName text ;
2022-08-30 09:35:59 +02:00
begin
begin
2024-09-16 15:36:37 +02:00
currentSubjectUuid : = current_setting ( ' hsadminng.currentSubjectUuid ' ) ;
2022-08-30 09:35:59 +02:00
exception
when others then
2024-09-16 15:36:37 +02:00
currentSubjectUuid : = null ;
2022-08-30 09:35:59 +02:00
end ;
2024-09-16 15:36:37 +02:00
if ( currentSubjectUuid is null or currentSubjectUuid = ' ' ) then
currentSubjectName : = base . currentSubject ( ) ;
if ( length ( currentSubjectName ) > 0 ) then
raise exception ' [401] currentSubjectUuid cannot be determined, unknown subject name "%" ' , currentSubjectName ;
2022-08-30 09:35:59 +02:00
else
2024-09-16 15:36:37 +02:00
raise exception ' [401] currentSubjectUuid cannot be determined, please call `base.defineContext(...)` first;" ' ;
2022-08-30 09:35:59 +02:00
end if ;
end if ;
2024-09-16 15:36:37 +02:00
return currentSubjectUuid : : uuid ;
2022-08-30 09:35:59 +02:00
end ; $ $ ;
- - / /
-- ============================================================================
2024-09-16 15:36:37 +02:00
- - changeset michael . hoennig : rbac - context - CURRENT - SUBJECT - UUIDS endDelimiter : - - / /
2022-08-30 09:35:59 +02:00
-- ----------------------------------------------------------------------------
/*
2024-09-16 15:36:37 +02:00
Returns the uuid of the current subject as set via ` base . defineContext ( . . . ) ` ,
or , if any , the uuids of all assumed roles as set via ` base . defineContext ( . . . ) `
2022-08-30 09:35:59 +02:00
or empty array , if context is not defined .
* /
2024-09-16 15:36:37 +02:00
create or replace function rbac . currentSubjectOrAssumedRolesUuids ( )
2022-08-30 09:35:59 +02:00
returns uuid [ ]
2024-01-23 15:11:23 +01:00
stable -- leakproof
2022-08-30 09:35:59 +02:00
language plpgsql as $ $
declare
2024-09-16 15:36:37 +02:00
currentSubjectOrAssumedRolesUuids text ;
currentSubjectName text ;
2022-08-30 09:35:59 +02:00
begin
begin
2024-09-16 15:36:37 +02:00
currentSubjectOrAssumedRolesUuids : = current_setting ( ' hsadminng.currentSubjectOrAssumedRolesUuids ' ) ;
2022-08-30 09:35:59 +02:00
exception
when others then
2024-09-16 15:36:37 +02:00
currentSubjectOrAssumedRolesUuids : = null ;
2022-08-30 09:35:59 +02:00
end ;
2024-09-16 15:36:37 +02:00
if ( currentSubjectOrAssumedRolesUuids is null or length ( currentSubjectOrAssumedRolesUuids ) = 0 ) then
currentSubjectName : = base . currentSubject ( ) ;
if ( length ( currentSubjectName ) > 0 ) then
raise exception ' [401] currentSubjectOrAssumedRolesUuids (%) cannot be determined, unknown subject name "%" ' , currentSubjectOrAssumedRolesUuids , currentSubjectName ;
2022-08-30 09:35:59 +02:00
else
2024-09-16 15:36:37 +02:00
raise exception ' [401] currentSubjectOrAssumedRolesUuids cannot be determined, please call `base.defineContext(...)` with a valid subject;" ' ;
2022-08-30 09:35:59 +02:00
end if ;
end if ;
2024-09-16 15:36:37 +02:00
return string_to_array ( currentSubjectOrAssumedRolesUuids , ' ; ' ) ;
2022-08-30 09:35:59 +02:00
end ; $ $ ;
2022-08-23 14:36:22 +02:00
- - / /