rename currentUserId->currentUserUuid + currentSubjectIds->currentSubjectsUuids
| | |
| | | FOR SELECT |
| | | TO restricted |
| | | USING ( |
| | | isPermissionGrantedToSubject(findPermissionId('customer', id, 'view'), currentUserId()) |
| | | isPermissionGrantedToSubject(findPermissionId('customer', id, 'view'), currentUserUuid()) |
| | | ); |
| | | |
| | | SET SESSION AUTHORIZATION restricted; |
| | |
| | | CREATE OR REPLACE RULE "_RETURN" AS |
| | | ON SELECT TO cust_view |
| | | DO INSTEAD |
| | | SELECT * FROM customer WHERE isPermissionGrantedToSubject(findPermissionId('customer', id, 'view'), currentUserId()); |
| | | SELECT * FROM customer WHERE isPermissionGrantedToSubject(findPermissionId('customer', id, 'view'), currentUserUuid()); |
| | | |
| | | SET SESSION AUTHORIZATION restricted; |
| | | SET hsadminng.currentUser TO 'alex@example.com'; |
| | |
| | | CREATE OR REPLACE VIEW cust_view AS |
| | | SELECT c.id, c.reference, c.prefix |
| | | FROM customer AS c |
| | | JOIN queryAllPermissionsOfSubjectId(currentUserId()) AS p |
| | | JOIN queryAllPermissionsOfSubjectId(currentUserUuid()) AS p |
| | | ON p.tableName='customer' AND p.rowId=c.id AND p.op='view'; |
| | | GRANT ALL PRIVILEGES ON cust_view TO restricted; |
| | | |
| | |
| | | WHERE target.uuid IN ( |
| | | SELECT uuid |
| | | FROM queryAccessibleObjectUuidsOfSubjectIds( |
| | | 'view', 'customer', currentSubjectIds())); |
| | | 'view', 'customer', currentSubjectsUuids())); |
| | | |
| | | This view should be automatically updatable. |
| | | Where, for updates, we actually have to check for 'edit' instead of 'view' operation, which makes it a bit more complicated. |
| | |
| | | SELECT DISTINCT target.* |
| | | FROM customer AS target |
| | | JOIN queryAccessibleObjectUuidsOfSubjectIds( |
| | | 'view', 'customer', currentSubjectIds()) AS allowedObjId |
| | | 'view', 'customer', currentSubjectsUuids()) AS allowedObjId |
| | | ON target.uuid = allowedObjId; |
| | | |
| | | This view cannot is not updatable automatically, |
| | |
| | | create or replace view domain_rv as |
| | | select target.* |
| | | from Domain as target |
| | | where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'domain', currentSubjectIds())); |
| | | where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'domain', currentSubjectsUuids())); |
| | | grant all privileges on domain_rv to restricted; |
| | | |
| | | |
| | |
| | | create or replace view EMailAddress_rv as |
| | | select target.* |
| | | from EMailAddress as target |
| | | where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'emailaddress', currentSubjectIds())); |
| | | where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'emailaddress', currentSubjectsUuids())); |
| | | grant all privileges on EMailAddress_rv to restricted; |
| | | |
| | | -- generate EMailAddress test data |
| | |
| | | TO restricted |
| | | USING ( |
| | | -- id=1000 |
| | | isPermissionGrantedToSubject(findPermissionId('customer', id, 'view'), currentUserId()) |
| | | isPermissionGrantedToSubject(findPermissionId('customer', id, 'view'), currentUserUuid()) |
| | | ); |
| | | |
| | | SET SESSION AUTHORIZATION restricted; |
| | |
| | | CREATE OR REPLACE RULE "_RETURN" AS |
| | | ON SELECT TO cust_view |
| | | DO INSTEAD |
| | | SELECT * FROM customer WHERE isPermissionGrantedToSubject(findPermissionId('customer', id, 'view'), currentUserId()); |
| | | SELECT * FROM customer WHERE isPermissionGrantedToSubject(findPermissionId('customer', id, 'view'), currentUserUuid()); |
| | | SELECT * from cust_view LIMIT 10; |
| | | |
| | | select queryAllPermissionsOfSubjectId(findRbacUser('mike@hostsharing.net')); |
| | |
| | | ON SELECT TO cust_view |
| | | DO INSTEAD |
| | | SELECT c.uuid, c.reference, c.prefix FROM customer AS c |
| | | JOIN queryAllPermissionsOfSubjectId(currentUserId()) AS p |
| | | JOIN queryAllPermissionsOfSubjectId(currentUserUuid()) AS p |
| | | ON p.objectTable='customer' AND p.objectUuid=c.uuid AND p.op in ('*', 'view'); |
| | | GRANT ALL PRIVILEGES ON cust_view TO restricted; |
| | | |
| | |
| | | CREATE OR REPLACE VIEW cust_view AS |
| | | SELECT c.uuid, c.reference, c.prefix |
| | | FROM customer AS c |
| | | JOIN queryAllPermissionsOfSubjectId(currentUserId()) AS p |
| | | JOIN queryAllPermissionsOfSubjectId(currentUserUuid()) AS p |
| | | ON p.objectUuid=c.uuid AND p.op in ('*', 'view'); |
| | | GRANT ALL PRIVILEGES ON cust_view TO restricted; |
| | | |
| | |
| | | raise exception '[400] Granting roles to user is only possible if exactly one role is assumed, given: %', assumedRoles(); |
| | | end if; |
| | | |
| | | currentSubjectUuids := currentSubjectIds(); |
| | | currentSubjectUuids := currentSubjectsUuids(); |
| | | return currentSubjectUuids[1]; |
| | | end; $$; |
| | | |
| | |
| | | perform assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'RbacRole'); |
| | | perform assertReferenceType('userUuid (ascendant)', userUuid, 'RbacUser'); |
| | | |
| | | if NOT isGranted(currentSubjectIds(), grantedByRoleUuid) then |
| | | if NOT isGranted(currentSubjectsUuids(), grantedByRoleUuid) then |
| | | raise exception '[403] Access to granted-by-role % forbidden for %', grantedByRoleUuid, currentSubjects(); |
| | | end if; |
| | | |
| | |
| | | perform assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'RbacRole'); |
| | | perform assertReferenceType('userUuid (ascendant)', userUuid, 'RbacUser'); |
| | | |
| | | if NOT isGranted(currentSubjectIds(), grantedByRoleUuid) then |
| | | if NOT isGranted(currentSubjectsUuids(), grantedByRoleUuid) then |
| | | raise exception '[403] Revoking role created by % is forbidden for %.', grantedByRoleUuid, currentSubjects(); |
| | | end if; |
| | | |
| | |
| | | raise exception '[403] Revoking role % is forbidden for %.', grantedRoleUuid, currentSubjects(); |
| | | end if; |
| | | |
| | | --raise exception 'isGranted(%, %)', currentSubjectIds(), grantedByRoleUuid; |
| | | if NOT isGranted(currentSubjectIds(), grantedByRoleUuid) then |
| | | --raise exception 'isGranted(%, %)', currentSubjectsUuids(), grantedByRoleUuid; |
| | | if NOT isGranted(currentSubjectsUuids(), grantedByRoleUuid) then |
| | | raise exception '[403] Revoking role granted by % is forbidden for %.', grantedByRoleUuid, currentSubjects(); |
| | | end if; |
| | | |
| | |
| | | Raises exception if not set. |
| | | */ |
| | | |
| | | create or replace function currentUserId() |
| | | create or replace function currentUserUuid() |
| | | returns uuid |
| | | stable leakproof |
| | | language plpgsql as $$ |
| | | declare |
| | | currentUser varchar(63); |
| | | currentUserId uuid; |
| | | currentUserUuid uuid; |
| | | begin |
| | | currentUser := currentUser(); |
| | | currentUserId = (select uuid from RbacUser where name = currentUser); |
| | | if currentUserId is null then |
| | | currentUserUuid = (select uuid from RbacUser where name = currentUser); |
| | | if currentUserUuid is null then |
| | | raise exception '[401] hsadminng.currentUser defined as %, but does not exists', currentUser; |
| | | end if; |
| | | return currentUserId; |
| | | return currentUserUuid; |
| | | end; $$; |
| | | --// |
| | | |
| | |
| | | or, if any, ids of assumed role names as set in `hsadminng.assumedRoles` |
| | | or empty array, if not set. |
| | | */ |
| | | create or replace function currentSubjectIds() |
| | | create or replace function currentSubjectsUuids() |
| | | returns uuid[] |
| | | stable leakproof |
| | | language plpgsql as $$ |
| | | declare |
| | | currentUserId uuid; |
| | | currentUserUuid uuid; |
| | | roleNames varchar(63)[]; |
| | | roleName varchar(63); |
| | | objectTableToAssume varchar(63); |
| | |
| | | roleIdsToAssume uuid[]; |
| | | roleUuidToAssume uuid; |
| | | begin |
| | | currentUserId := currentUserId(); |
| | | if currentUserId is null then |
| | | currentUserUuid := currentUserUuid(); |
| | | if currentUserUuid is null then |
| | | raise exception '[401] user % does not exist', currentUser(); |
| | | end if; |
| | | |
| | | roleNames := assumedRoles(); |
| | | if cardinality(roleNames) = 0 then |
| | | return array [currentUserId]; |
| | | return array [currentUserUuid]; |
| | | end if; |
| | | |
| | | raise notice 'assuming roles: %', roleNames; |
| | |
| | | where r.objectUuid = objectUuidToAssume |
| | | and r.roleType = roleTypeToAssume |
| | | into roleUuidToAssume; |
| | | if (not isGranted(currentUserId, roleUuidToAssume)) then |
| | | raise exception '[403] user % (%) has no permission to assume role % (%)', currentUser(), currentUserId, roleName, roleUuidToAssume; |
| | | if (not isGranted(currentUserUuid, roleUuidToAssume)) then |
| | | raise exception '[403] user % (%) has no permission to assume role % (%)', currentUser(), currentUserUuid, roleName, roleUuidToAssume; |
| | | end if; |
| | | roleIdsToAssume := roleIdsToAssume || roleUuidToAssume; |
| | | end loop; |
| | |
| | | -- TODO: this could to be optimized |
| | | select (select uuid from global) in |
| | | (select queryAccessibleObjectUuidsOfSubjectIds( |
| | | op, 'global', currentSubjectIds())); |
| | | op, 'global', currentSubjectsUuids())); |
| | | $$; |
| | | --// |
| | | |
| | |
| | | -- ---------------------------------------------------------------------------- |
| | | |
| | | /* |
| | | Tests if currentUserId() can fetch the user from the session variable. |
| | | Tests if currentUserUuid() can fetch the user from the session variable. |
| | | */ |
| | | |
| | | do language plpgsql $$ |
| | |
| | | userName varchar; |
| | | begin |
| | | set local hsadminng.currentUser = 'sven@hostsharing.net'; |
| | | select userName from RbacUser where uuid = currentUserId() into userName; |
| | | select userName from RbacUser where uuid = currentUserUuid() into userName; |
| | | if userName <> 'sven@hostsharing.net' then |
| | | raise exception 'setting or fetching initial currentUser failed, got: %', userName; |
| | | end if; |
| | | |
| | | set local hsadminng.currentUser = 'mike@hostsharing.net'; |
| | | select userName from RbacUser where uuid = currentUserId() into userName; |
| | | select userName from RbacUser where uuid = currentUserUuid() into userName; |
| | | if userName = 'mike@hostsharing.net' then |
| | | raise exception 'currentUser should not change in one transaction, but did change, got: %', userName; |
| | | end if; |
| | |
| | | create or replace view customer_rv as |
| | | select target.* |
| | | from customer as target |
| | | where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'customer', currentSubjectIds())); |
| | | where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'customer', currentSubjectsUuids())); |
| | | grant all privileges on customer_rv to restricted; |
| | | --// |
| | | |
| | |
| | | create or replace view package_rv as |
| | | select target.* |
| | | from package as target |
| | | where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'package', currentSubjectIds())) |
| | | where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'package', currentSubjectsUuids())) |
| | | order by target.name; |
| | | grant all privileges on package_rv to restricted; |
| | | --// |
| | |
| | | create or replace view unixuser_rv as |
| | | select target.* |
| | | from unixuser as target |
| | | where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'unixuser', currentSubjectIds())); |
| | | where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'unixuser', currentSubjectsUuids())); |
| | | grant all privileges on unixuser_rv to restricted; |
| | | --// |