From 342102e85c470ea17717cafd67d57a58738c2579 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Fri, 13 Sep 2024 20:31:41 +0200 Subject: [PATCH] rbac.grants --- .../RolesGrantsAndPermissionsGenerator.java | 2 +- .../db/changelog/1-rbac/1050-rbac-base.sql | 50 +++++++++---------- .../1-rbac/1051-rbac-subject-grant.sql | 12 ++--- .../db/changelog/1-rbac/1055-rbac-views.sql | 12 ++--- .../changelog/1-rbac/1058-rbac-generators.sql | 12 ++--- .../changelog/1-rbac/1059-rbac-statistics.sql | 2 +- .../5033-hs-office-relation-rbac.sql | 2 +- .../5063-hs-office-debitor-rbac.sql | 2 +- .../7013-hs-hosting-asset-rbac.sql | 2 +- 9 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java index d28f3193..727e5d62 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java @@ -114,7 +114,7 @@ class RolesGrantsAndPermissionsGenerator { begin if ${updateConditions} then - delete from rbacgrants g where g.grantedbytriggerof = OLD.uuid; + delete from rbac.grants g where g.grantedbytriggerof = OLD.uuid; call buildRbacSystemFor${simpleEntityName}(NEW); end if; end; $$; diff --git a/src/main/resources/db/changelog/1-rbac/1050-rbac-base.sql b/src/main/resources/db/changelog/1-rbac/1050-rbac-base.sql index 232ceb0d..41ac20b3 100644 --- a/src/main/resources/db/changelog/1-rbac/1050-rbac-base.sql +++ b/src/main/resources/db/changelog/1-rbac/1050-rbac-base.sql @@ -300,7 +300,7 @@ create or replace function deleteRbacGrantsOfRbacRole() strict as $$ begin if TG_OP = 'DELETE' then - delete from RbacGrants g where old.uuid in (g.grantedbyroleuuid, g.ascendantuuid, g.descendantuuid); + delete from rbac.grants g where old.uuid in (g.grantedbyroleuuid, g.ascendantuuid, g.descendantuuid); else raise exception 'invalid usage of TRIGGER BEFORE DELETE'; end if; @@ -484,7 +484,7 @@ $$; /* Table to store grants / role- or permission assignments to subjects or roles. */ -create table RbacGrants +create table rbac.grants ( uuid uuid primary key default uuid_generate_v4(), grantedByTriggerOf uuid references rbac.object (uuid) on delete cascade initially deferred , @@ -494,26 +494,26 @@ create table RbacGrants assumed boolean not null default true, -- auto assumed (true) vs. needs assumeRoles (false) unique (ascendantUuid, descendantUuid), constraint rbacGrant_createdBy check ( grantedByRoleUuid is null or grantedByTriggerOf is null) ); -create index on RbacGrants (ascendantUuid); -create index on RbacGrants (descendantUuid); +create index on rbac.grants (ascendantUuid); +create index on rbac.grants (descendantUuid); -call base.create_journal('RbacGrants'); +call base.create_journal('rbac.grants'); create or replace function findGrantees(grantedId uuid) returns setof rbac.reference returns null on null input language sql as $$ with recursive grants as ( select descendantUuid, ascendantUuid - from RbacGrants + from rbac.grants where descendantUuid = grantedId union all select g.descendantUuid, g.ascendantUuid - from RbacGrants g + from rbac.grants g inner join grants on grants.ascendantUuid = g.descendantUuid ) select ref.* from grants - join rbac.reference ref on ref.uuid = grants.ascendantUuid; + join rbac.reference ref on ref.uuid = grants.ascendantUuid; $$; create or replace function isGranted(granteeIds uuid[], grantedId uuid) @@ -522,11 +522,11 @@ create or replace function isGranted(granteeIds uuid[], grantedId uuid) language sql as $$ with recursive grants as ( select descendantUuid, ascendantUuid - from RbacGrants + from rbac.grants where descendantUuid = grantedId union all select "grant".descendantUuid, "grant".ascendantUuid - from RbacGrants "grant" + from rbac.grants "grant" inner join grants recur on recur.ascendantUuid = "grant".descendantUuid ) select exists ( @@ -548,11 +548,11 @@ create or replace function isPermissionGrantedToSubject(permissionId uuid, subje language sql as $$ with recursive grants as ( select descendantUuid, ascendantUuid - from RbacGrants + from rbac.grants where descendantUuid = permissionId union all select g.descendantUuid, g.ascendantUuid - from RbacGrants g + from rbac.grants g inner join grants on grants.ascendantUuid = g.descendantUuid ) select exists( @@ -580,7 +580,7 @@ create or replace function hasGlobalRoleGranted(forAscendantUuid uuid) language sql as $$ select exists( select r.uuid - from RbacGrants as g + from rbac.grants as g join RbacRole as r on r.uuid = g.descendantuuid join rbac.object as o on o.uuid = r.objectuuid where g.ascendantuuid = forAscendantUuid @@ -595,7 +595,7 @@ begin perform rbac.assertReferenceType('permissionId (descendant)', permissionUuid, 'RbacPermission'); insert - into RbacGrants (grantedByTriggerOf, ascendantUuid, descendantUuid, assumed) + into rbac.grants (grantedByTriggerOf, ascendantUuid, descendantUuid, assumed) values (rbac.currentTriggerObjectUuid(), roleUuid, permissionUuid, true) on conflict do nothing; -- allow granting multiple times end; @@ -619,7 +619,7 @@ begin end if; insert - into RbacGrants (grantedByTriggerOf, ascendantuuid, descendantUuid, assumed) + into rbac.grants (grantedByTriggerOf, ascendantuuid, descendantUuid, assumed) values (rbac.currentTriggerObjectUuid(), superRoleId, subRoleId, doAssume) on conflict do nothing; -- allow granting multiple times end; $$; @@ -647,7 +647,7 @@ begin end if; insert - into RbacGrants (grantedByTriggerOf, ascendantuuid, descendantUuid, assumed) + into rbac.grants (grantedByTriggerOf, ascendantuuid, descendantUuid, assumed) values (rbac.currentTriggerObjectUuid(), superRoleId, subRoleId, doAssume) on conflict do nothing; -- allow granting multiple times end; $$; @@ -665,7 +665,7 @@ begin perform rbac.assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole'); if (isGranted(superRoleId, subRoleId)) then - delete from RbacGrants where ascendantUuid = superRoleId and descendantUuid = subRoleId; + delete from rbac.grants where ascendantUuid = superRoleId and descendantUuid = subRoleId; else raise exception 'cannot revoke role % (%) from % (%) because it is not granted', subRole, subRoleId, superRole, superRoleId; @@ -686,10 +686,10 @@ begin perform rbac.assertReferenceType('permission (descendant)', permissionId, 'RbacPermission'); if (isGranted(superRoleId, permissionId)) then - delete from RbacGrants where ascendantUuid = superRoleId and descendantUuid = permissionId; + delete from rbac.grants where ascendantUuid = superRoleId and descendantUuid = permissionId; else select p.op, o.objectTable, o.uuid - from rbacGrants g + from rbac.grants g join rbacPermission p on p.uuid=g.descendantUuid join rbac.object o on o.uuid=p.objectUuid where g.uuid=permissionId @@ -720,12 +720,12 @@ begin return query WITH RECURSIVE grants AS ( SELECT descendantUuid, ascendantUuid, 1 AS level - FROM RbacGrants + FROM rbac.grants WHERE assumed AND ascendantUuid = any(subjectIds) UNION ALL SELECT g.descendantUuid, g.ascendantUuid, grants.level + 1 AS level - FROM RbacGrants g + FROM rbac.grants g INNER JOIN grants ON grants.descendantUuid = g.ascendantUuid WHERE g.assumed ), @@ -764,11 +764,11 @@ create or replace function queryPermissionsGrantedToSubjectId(subjectId uuid) language sql as $$ with recursive grants as ( select descendantUuid, ascendantUuid - from RbacGrants + from rbac.grants where ascendantUuid = subjectId union all select g.descendantUuid, g.ascendantUuid - from RbacGrants g + from rbac.grants g inner join grants on grants.descendantUuid = g.ascendantUuid ) select perm.* @@ -798,11 +798,11 @@ select * -- @formatter:off with recursive grants as ( select descendantUuid, ascendantUuid - from RbacGrants + from rbac.grants where descendantUuid = objectId union all select "grant".descendantUuid, "grant".ascendantUuid - from RbacGrants "grant" + from rbac.grants "grant" inner join grants recur on recur.ascendantUuid = "grant".descendantUuid ) -- @formatter:on diff --git a/src/main/resources/db/changelog/1-rbac/1051-rbac-subject-grant.sql b/src/main/resources/db/changelog/1-rbac/1051-rbac-subject-grant.sql index b0b56c49..c44d21e4 100644 --- a/src/main/resources/db/changelog/1-rbac/1051-rbac-subject-grant.sql +++ b/src/main/resources/db/changelog/1-rbac/1051-rbac-subject-grant.sql @@ -28,7 +28,7 @@ begin perform rbac.assertReferenceType('subjectUuid (ascendant)', subjectUuid, 'rbac.subject'); insert - into RbacGrants (grantedByRoleUuid, ascendantUuid, descendantUuid, assumed) + into rbac.grants (grantedByRoleUuid, ascendantUuid, descendantUuid, assumed) values (grantedByRoleUuid, subjectUuid, grantedRoleUuid, doAssume) -- TODO: check if grantedByRoleUuid+doAssume are the same, otherwise raise exception? on conflict do nothing; -- allow granting multiple times @@ -61,7 +61,7 @@ begin end if; insert - into RbacGrants (grantedByRoleUuid, ascendantUuid, descendantUuid, assumed) + into rbac.grants (grantedByRoleUuid, ascendantUuid, descendantUuid, assumed) values (grantedByRoleUuid, subjectUuid, grantedRoleUuid, doAssume); -- TODO.impl: What should happen on multiple grants? What if options (doAssume) are not the same? -- Most powerful or latest grant wins? What about managed? @@ -104,8 +104,8 @@ create or replace procedure rbac.revokeRoleFromSubject(grantedByRoleUuid uuid, g begin call rbac.checkRevokeRoleFromSubjectPreconditions(grantedByRoleUuid, grantedRoleUuid, subjectUuid); - raise INFO 'delete from RbacGrants where ascendantUuid = % and descendantUuid = %', subjectUuid, grantedRoleUuid; - delete from RbacGrants as g + raise INFO 'delete from rbac.grants where ascendantUuid = % and descendantUuid = %', subjectUuid, grantedRoleUuid; + delete from rbac.grants as g where g.ascendantUuid = subjectUuid and g.descendantUuid = grantedRoleUuid and g.grantedByRoleUuid = revokeRoleFromSubject.grantedByRoleUuid; end; $$; @@ -118,8 +118,8 @@ end; $$; create or replace procedure rbac.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 + raise INFO 'delete from rbac.grants where ascendantUuid = % and descendantUuid = %', superRoleUuid, permissionUuid; + delete from rbac.grants as g where g.ascendantUuid = superRoleUuid and g.descendantUuid = permissionUuid; end; $$; --// diff --git a/src/main/resources/db/changelog/1-rbac/1055-rbac-views.sql b/src/main/resources/db/changelog/1-rbac/1055-rbac-views.sql index 51d6c9e7..d549bb42 100644 --- a/src/main/resources/db/changelog/1-rbac/1055-rbac-views.sql +++ b/src/main/resources/db/changelog/1-rbac/1055-rbac-views.sql @@ -85,7 +85,7 @@ create or replace view rbacgrants_ev as ) as descendingIdName, dro.objectTable, dro.uuid, dp.op, dp.optablename - from rbacgrants as g + from rbac.grants as g left outer join rbacrole as ar on ar.uuid = g.ascendantUuid left outer join rbac.object as aro on aro.uuid = ar.objectuuid @@ -123,7 +123,7 @@ select o.objectTable || '#' || findIdNameByObjectUuid(o.objectTable, o.uuid) || select g.grantedbyroleuuid, g.ascendantuuid, g.descendantuuid, g.assumed, u.name as userName, o.objecttable, r.objectuuid, r.roletype, findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName - from rbacgrants as g + from rbac.grants as g join rbacrole as r on r.uuid = g.descendantUuid join rbac.object o on o.uuid = r.objectuuid left outer join rbac.subject u on u.uuid = g.ascendantuuid @@ -211,7 +211,7 @@ select distinct * from ( select usersInRolesOfcurrentSubject.* from rbac.subject as usersInRolesOfcurrentSubject - join RbacGrants as g on g.ascendantuuid = usersInRolesOfcurrentSubject.uuid + join rbac.grants as g on g.ascendantuuid = usersInRolesOfcurrentSubject.uuid join rbacrole_ev as r on r.uuid = g.descendantuuid union select users.* @@ -236,7 +236,7 @@ create or replace view rbac.subject_rv as from ( select usersInRolesOfcurrentSubject.* from rbac.subject as usersInRolesOfcurrentSubject - join RbacGrants as g on g.ascendantuuid = usersInRolesOfcurrentSubject.uuid + join rbac.grants as g on g.ascendantuuid = usersInRolesOfcurrentSubject.uuid join rbacrole_rv as r on r.uuid = g.descendantuuid union select users.* @@ -330,7 +330,7 @@ select r.uuid as roleuuid, p.uuid as permissionUuid, (r.objecttable || ':' || r.objectidname || ':' || r.roletype) as roleName, p.op, o.objecttable, r.objectidname, o.uuid as objectuuid from rbacrole_rv r - join rbacgrants g on g.ascendantuuid = r.uuid + join rbac.grants g on g.ascendantuuid = r.uuid join rbacpermission p on p.uuid = g.descendantuuid join rbac.object o on o.uuid = p.objectuuid; grant all privileges on rbac.own_granted_permissions_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}; @@ -370,7 +370,7 @@ begin findIdNameByObjectUuid(po.objectTable, po.uuid) as permissionObjectIdName, po.uuid as permissionObjectUuid from queryPermissionsGrantedToSubjectId( targetSubjectUuid) as p - join rbacgrants as g on g.descendantUuid = p.uuid + join rbac.grants as g on g.descendantUuid = p.uuid join rbac.object as po on po.uuid = p.objectUuid join rbacrole_rv as r on r.uuid = g.ascendantUuid join rbac.object as ro on ro.uuid = r.objectUuid diff --git a/src/main/resources/db/changelog/1-rbac/1058-rbac-generators.sql b/src/main/resources/db/changelog/1-rbac/1058-rbac-generators.sql index a8fdfe1e..e0dcf75e 100644 --- a/src/main/resources/db/changelog/1-rbac/1058-rbac-generators.sql +++ b/src/main/resources/db/changelog/1-rbac/1058-rbac-generators.sql @@ -179,19 +179,19 @@ begin with accessible_%1$s_uuids as ( with recursive recursive_grants as - (select distinct rbacgrants.descendantuuid, - rbacgrants.ascendantuuid, + (select distinct rbac.grants.descendantuuid, + rbac.grants.ascendantuuid, 1 as level, true - from rbacgrants - where rbacgrants.assumed - and (rbacgrants.ascendantuuid = any (rbac.currentSubjectOrAssumedRolesUuids())) + from rbac.grants + where rbac.grants.assumed + and (rbac.grants.ascendantuuid = any (rbac.currentSubjectOrAssumedRolesUuids())) union all select distinct g.descendantuuid, g.ascendantuuid, grants.level + 1 as level, base.assertTrue(grants.level < 22, 'too many grant-levels: ' || grants.level) - from rbacgrants g + from rbac.grants g join recursive_grants grants on grants.descendantuuid = g.ascendantuuid where g.assumed), grant_count AS ( diff --git a/src/main/resources/db/changelog/1-rbac/1059-rbac-statistics.sql b/src/main/resources/db/changelog/1-rbac/1059-rbac-statistics.sql index 2f11a5ca..e503ae01 100644 --- a/src/main/resources/db/changelog/1-rbac/1059-rbac-statistics.sql +++ b/src/main/resources/db/changelog/1-rbac/1059-rbac-statistics.sql @@ -20,7 +20,7 @@ select no, to_char("count", '9 999 999 999') as "count", "table" from rbac.reference union select 5 as no, count(*) as "count", 'grants' as "table" - from RbacGrants + from rbac.grants union select 6 as no, count(*) as "count", 'objects' as "table" from rbac.object) as totals diff --git a/src/main/resources/db/changelog/5-hs-office/503-relation/5033-hs-office-relation-rbac.sql b/src/main/resources/db/changelog/5-hs-office/503-relation/5033-hs-office-relation-rbac.sql index 84e19105..b0769dec 100644 --- a/src/main/resources/db/changelog/5-hs-office/503-relation/5033-hs-office-relation-rbac.sql +++ b/src/main/resources/db/changelog/5-hs-office/503-relation/5033-hs-office-relation-rbac.sql @@ -125,7 +125,7 @@ create or replace procedure updateRbacRulesForHsOfficeRelation( begin if NEW.contactUuid is distinct from OLD.contactUuid then - delete from rbacgrants g where g.grantedbytriggerof = OLD.uuid; + delete from rbac.grants g where g.grantedbytriggerof = OLD.uuid; call buildRbacSystemForHsOfficeRelation(NEW); end if; end; $$; diff --git a/src/main/resources/db/changelog/5-hs-office/506-debitor/5063-hs-office-debitor-rbac.sql b/src/main/resources/db/changelog/5-hs-office/506-debitor/5063-hs-office-debitor-rbac.sql index b0a392da..58175132 100644 --- a/src/main/resources/db/changelog/5-hs-office/506-debitor/5063-hs-office-debitor-rbac.sql +++ b/src/main/resources/db/changelog/5-hs-office/506-debitor/5063-hs-office-debitor-rbac.sql @@ -101,7 +101,7 @@ begin if NEW.debitorRelUuid is distinct from OLD.debitorRelUuid or NEW.refundBankAccountUuid is distinct from OLD.refundBankAccountUuid then - delete from rbacgrants g where g.grantedbytriggerof = OLD.uuid; + delete from rbac.grants g where g.grantedbytriggerof = OLD.uuid; call buildRbacSystemForHsOfficeDebitor(NEW); end if; end; $$; diff --git a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.sql b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.sql index 93135e0c..72357dff 100644 --- a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.sql +++ b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.sql @@ -129,7 +129,7 @@ begin if NEW.assignedToAssetUuid is distinct from OLD.assignedToAssetUuid or NEW.alarmContactUuid is distinct from OLD.alarmContactUuid then - delete from rbacgrants g where g.grantedbytriggerof = OLD.uuid; + delete from rbac.grants g where g.grantedbytriggerof = OLD.uuid; call buildRbacSystemForHsHostingAsset(NEW); end if; end; $$;