diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RawRbacGrantEntity.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RawRbacGrantEntity.java index f7b3cdf4..77a2d027 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RawRbacGrantEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RawRbacGrantEntity.java @@ -28,8 +28,8 @@ public class RawRbacGrantEntity implements Comparable { @Column(name = "grantedbyroleidname", updatable = false, insertable = false) private String grantedByRoleIdName; - @Column(name = "grantedbyroleuuid", updatable = false, insertable = false) - private UUID grantedByRoleUuid; + @Column(name = "usergrantsbyroleuuid", updatable = false, insertable = false) + private UUID userGrantsByRoleUuid; @Column(name = "ascendantidname", updatable = false, insertable = false) private String ascendantIdName; @@ -50,7 +50,7 @@ public class RawRbacGrantEntity implements Comparable { // @formatter:off return "{ grant " + descendantIdName + " to " + ascendantIdName + - " by " + ( grantedByRoleUuid == null + " by " + ( userGrantsByRoleUuid == null ? "system" : grantedByRoleIdName ) + ( assumed ? " and assume" : "") + diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantEntity.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantEntity.java index a3abf528..6f175b01 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantEntity.java @@ -22,8 +22,8 @@ public class RbacGrantEntity { @Column(name = "grantedbyroleidname", updatable = false, insertable = false) private String grantedByRoleIdName; - @Column(name = "grantedbyroleuuid", updatable = false, insertable = false) - private UUID grantedByRoleUuid; + @Column(name = "usergrantsbyroleuuid", updatable = false, insertable = false) + private UUID userGrantsByRoleUuid; @Column(name = "grantedroleidname", updatable = false, insertable = false) private String grantedRoleIdName; diff --git a/src/main/resources/api-definition/rbac/rbac-grant-schemas.yaml b/src/main/resources/api-definition/rbac/rbac-grant-schemas.yaml index 12a2cbbd..01a0b63f 100644 --- a/src/main/resources/api-definition/rbac/rbac-grant-schemas.yaml +++ b/src/main/resources/api-definition/rbac/rbac-grant-schemas.yaml @@ -8,7 +8,7 @@ components: properties: grantedByRoleIdName: type: string - grantedByRoleUuid: + userGrantsByRoleUuid: type: string format: uuid assumed: diff --git a/src/main/resources/db/changelog/050-rbac-base.sql b/src/main/resources/db/changelog/050-rbac-base.sql index 735f1932..9ae9f2ff 100644 --- a/src/main/resources/db/changelog/050-rbac-base.sql +++ b/src/main/resources/db/changelog/050-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 RbacGrants g where old.uuid in (g.userGrantsByRoleUuid, g.ascendantuuid, g.descendantuuid); else raise exception 'invalid usage of TRIGGER BEFORE DELETE'; end if; @@ -519,12 +519,12 @@ create table RbacGrants ( uuid uuid primary key default uuid_generate_v4(), grantedByTriggerOf uuid references RbacObject (uuid) on delete cascade initially deferred , - grantedByRoleUuid uuid references RbacRole (uuid), + userGrantsByRoleUuid uuid references RbacRole (uuid), ascendantUuid uuid references RbacReference (uuid), descendantUuid uuid references RbacReference (uuid), 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) ); + constraint rbacGrant_createdBy check ( userGrantsByRoleUuid is null or grantedByTriggerOf is null) ); create index on RbacGrants (ascendantUuid); create index on RbacGrants (descendantUuid); diff --git a/src/main/resources/db/changelog/051-rbac-user-grant.sql b/src/main/resources/db/changelog/051-rbac-user-grant.sql index 6b817a04..090d3cf4 100644 --- a/src/main/resources/db/changelog/051-rbac-user-grant.sql +++ b/src/main/resources/db/changelog/051-rbac-user-grant.sql @@ -20,52 +20,52 @@ begin return currentSubjectsUuids[1]; end; $$; -create or replace procedure grantRoleToUserUnchecked(grantedByRoleUuid uuid, roleUuid uuid, userUuid uuid, doAssume boolean = true) +create or replace procedure grantRoleToUserUnchecked(userGrantsByRoleUuid uuid, roleUuid uuid, userUuid uuid, doAssume boolean = true) language plpgsql as $$ begin - perform assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'RbacRole'); + perform assertReferenceType('grantingRoleUuid', userGrantsByRoleUuid, 'RbacRole'); perform assertReferenceType('roleId (descendant)', roleUuid, 'RbacRole'); perform assertReferenceType('userId (ascendant)', userUuid, 'RbacUser'); - raise notice 'role % grants role % to user %, assumed=%', grantedByRoleUuid, roleUuid, userUuid, doAssume; + raise notice 'role % grants role % to user %, assumed=%', userGrantsByRoleUuid, roleUuid, userUuid, doAssume; insert - into RbacGrants (grantedByRoleUuid, ascendantUuid, descendantUuid, assumed) - values (grantedByRoleUuid, userUuid, roleUuid, doAssume); + into RbacGrants (userGrantsByRoleUuid, ascendantUuid, descendantUuid, assumed) + values (userGrantsByRoleUuid, userUuid, roleUuid, doAssume); -- TODO.spec: What should happen on multiple grants? What if options (doAssume) are not the same? -- Most powerful or latest grant wins? What about managed? -- on conflict do nothing; -- allow granting multiple times end; $$; -create or replace procedure grantRoleToUser(grantedByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid, doAssume boolean = true) +create or replace procedure grantRoleToUser(userGrantsByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid, doAssume boolean = true) language plpgsql as $$ declare grantedByRoleIdName text; grantedRoleIdName text; begin - perform assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'RbacRole'); + perform assertReferenceType('grantingRoleUuid', userGrantsByRoleUuid, 'RbacRole'); perform assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'RbacRole'); perform assertReferenceType('userUuid (ascendant)', userUuid, 'RbacUser'); - assert grantedByRoleUuid is not null, 'grantedByRoleUuid must not be null'; + assert userGrantsByRoleUuid is not null, 'userGrantsByRoleUuid must not be null'; assert grantedRoleUuid is not null, 'grantedRoleUuid must not be null'; assert userUuid is not null, 'userUuid must not be null'; - if NOT isGranted(currentSubjectsUuids(), grantedByRoleUuid) then - select roleIdName from rbacRole_ev where uuid=grantedByRoleUuid into grantedByRoleIdName; + if NOT isGranted(currentSubjectsUuids(), userGrantsByRoleUuid) then + select roleIdName from rbacRole_ev where uuid=userGrantsByRoleUuid into grantedByRoleIdName; raise exception '[403] Access to granted-by-role % (%) forbidden for % (%)', - grantedByRoleIdName, grantedByRoleUuid, currentSubjects(), currentSubjectsUuids(); + grantedByRoleIdName, userGrantsByRoleUuid, currentSubjects(), currentSubjectsUuids(); end if; - if NOT isGranted(grantedByRoleUuid, grantedRoleUuid) then - select roleIdName from rbacRole_ev where uuid=grantedByRoleUuid into grantedByRoleIdName; + if NOT isGranted(userGrantsByRoleUuid, grantedRoleUuid) then + select roleIdName from rbacRole_ev where uuid=userGrantsByRoleUuid into grantedByRoleIdName; select roleIdName from rbacRole_ev where uuid=grantedRoleUuid into grantedRoleIdName; raise exception '[403] Access to granted role % (%) forbidden for % (%)', - grantedRoleIdName, grantedRoleUuid, grantedByRoleIdName, grantedByRoleUuid; + grantedRoleIdName, grantedRoleUuid, grantedByRoleIdName, userGrantsByRoleUuid; end if; insert - into RbacGrants (grantedByRoleUuid, ascendantUuid, descendantUuid, assumed) - values (grantedByRoleUuid, userUuid, grantedRoleUuid, doAssume); + into RbacGrants (userGrantsByRoleUuid, ascendantUuid, descendantUuid, assumed) + values (userGrantsByRoleUuid, userUuid, grantedRoleUuid, doAssume); -- TODO.spec: What should happen on mupltiple grants? What if options (doAssume) are not the same? -- Most powerful or latest grant wins? What about managed? -- on conflict do nothing; -- allow granting multiple times @@ -77,40 +77,40 @@ end; $$; --changeset rbac-user-grant-REVOKE-ROLE-FROM-USER:1 endDelimiter:--// -- ---------------------------------------------------------------------------- -create or replace procedure checkRevokeRoleFromUserPreconditions(grantedByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid) +create or replace procedure checkRevokeRoleFromUserPreconditions(userGrantsByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid) language plpgsql as $$ begin - perform assertReferenceType('grantedByRoleUuid', grantedByRoleUuid, 'RbacRole'); + perform assertReferenceType('userGrantsByRoleUuid', userGrantsByRoleUuid, 'RbacRole'); perform assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'RbacRole'); perform assertReferenceType('userUuid (ascendant)', userUuid, 'RbacUser'); - if NOT isGranted(currentSubjectsUuids(), grantedByRoleUuid) then - raise exception '[403] Revoking role created by % is forbidden for %.', grantedByRoleUuid, currentSubjects(); + if NOT isGranted(currentSubjectsUuids(), userGrantsByRoleUuid) then + raise exception '[403] Revoking role created by % is forbidden for %.', userGrantsByRoleUuid, currentSubjects(); end if; - if NOT isGranted(grantedByRoleUuid, grantedRoleUuid) then + if NOT isGranted(userGrantsByRoleUuid, grantedRoleUuid) then raise exception '[403] Revoking role % is forbidden for %.', grantedRoleUuid, currentSubjects(); end if; - --raise exception 'isGranted(%, %)', currentSubjectsUuids(), grantedByRoleUuid; - if NOT isGranted(currentSubjectsUuids(), grantedByRoleUuid) then - raise exception '[403] Revoking role granted by % is forbidden for %.', grantedByRoleUuid, currentSubjects(); + --raise exception 'isGranted(%, %)', currentSubjectsUuids(), userGrantsByRoleUuid; + if NOT isGranted(currentSubjectsUuids(), userGrantsByRoleUuid) then + raise exception '[403] Revoking role granted by % is forbidden for %.', userGrantsByRoleUuid, currentSubjects(); end if; if NOT isGranted(userUuid, grantedRoleUuid) then - raise exception '[404] No such grant found granted by % for user % to role %.', grantedByRoleUuid, userUuid, grantedRoleUuid; + raise exception '[404] No such grant found granted by % for user % to role %.', userGrantsByRoleUuid, userUuid, grantedRoleUuid; end if; end; $$; -create or replace procedure revokeRoleFromUser(grantedByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid) +create or replace procedure revokeRoleFromUser(userGrantsByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid) language plpgsql as $$ begin - call checkRevokeRoleFromUserPreconditions(grantedByRoleUuid, grantedRoleUuid, userUuid); + call checkRevokeRoleFromUserPreconditions(userGrantsByRoleUuid, grantedRoleUuid, userUuid); raise INFO 'delete from RbacGrants where ascendantUuid = % and descendantUuid = %', userUuid, grantedRoleUuid; delete from RbacGrants as g where g.ascendantUuid = userUuid and g.descendantUuid = grantedRoleUuid - and g.grantedByRoleUuid = revokeRoleFromUser.grantedByRoleUuid; + and g.userGrantsByRoleUuid = revokeRoleFromUser.userGrantsByRoleUuid; end; $$; --// diff --git a/src/main/resources/db/changelog/055-rbac-views.sql b/src/main/resources/db/changelog/055-rbac-views.sql index b494d120..e13f66ce 100644 --- a/src/main/resources/db/changelog/055-rbac-views.sql +++ b/src/main/resources/db/changelog/055-rbac-views.sql @@ -60,14 +60,14 @@ create or replace view rbacgrants_ev as go.objectTable || '#' || findIdNameByObjectUuid(go.objectTable, go.uuid) || '.' || r.roletype as grantedByRoleIdName, x.ascendingIdName as ascendantIdName, x.descendingIdName as descendantIdName, - x.grantedByRoleUuid, + x.userGrantsByRoleUuid, x.ascendantUuid as ascendantUuid, x.descendantUuid as descendantUuid, x.assumed from ( select g.uuid as grantUuid, g.grantedbytriggerof as grantedbytriggerof, - g.grantedbyroleuuid, g.ascendantuuid, g.descendantuuid, g.assumed, + g.userGrantsByRoleUuid, g.ascendantuuid, g.descendantuuid, g.assumed, coalesce( 'user ' || au.name, @@ -91,7 +91,7 @@ create or replace view rbacgrants_ev as left outer join rbacpermission dp on dp.uuid = g.descendantUuid left outer join rbacobject as dpo on dpo.uuid = dp.objectUuid ) as x - left outer join rbacrole as r on r.uuid = grantedByRoleUuid + left outer join rbacrole as r on r.uuid = userGrantsByRoleUuid left outer join rbacuser u on u.uuid = x.ascendantuuid left outer join rbacobject go on go.uuid = r.objectuuid @@ -112,10 +112,10 @@ create or replace view rbacgrants_rv as -- @formatter:off select o.objectTable || '#' || findIdNameByObjectUuid(o.objectTable, o.uuid) || '.' || r.roletype as grantedByRoleIdName, g.objectTable || '#' || g.objectIdName || '.' || g.roletype as grantedRoleIdName, g.userName, g.assumed, - g.grantedByRoleUuid, g.descendantUuid as grantedRoleUuid, g.ascendantUuid as userUuid, + g.userGrantsByRoleUuid, g.descendantUuid as grantedRoleUuid, g.ascendantUuid as userUuid, g.objectTable, g.objectUuid, g.objectIdName, g.roleType as grantedRoleType from ( - select g.grantedbyroleuuid, g.ascendantuuid, g.descendantuuid, g.assumed, + select g.userGrantsByRoleUuid, 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 @@ -124,7 +124,7 @@ select o.objectTable || '#' || findIdNameByObjectUuid(o.objectTable, o.uuid) || left outer join rbacuser u on u.uuid = g.ascendantuuid where isGranted(currentSubjectsUuids(), r.uuid) ) as g - join RbacRole as r on r.uuid = grantedByRoleUuid + join RbacRole as r on r.uuid = userGrantsByRoleUuid join RbacObject as o on o.uuid = r.objectUuid order by grantedRoleIdName; -- @formatter:on @@ -177,7 +177,7 @@ create or replace function deleteRbacGrant() returns trigger language plpgsql as $$ begin - call revokeRoleFromUser(old.grantedByRoleUuid, old.grantedRoleUuid, old.userUuid); + call revokeRoleFromUser(old.userGrantsByRoleUuid, old.grantedRoleUuid, old.userUuid); return old; end; $$; diff --git a/src/main/resources/db/changelog/057-rbac-role-builder.sql b/src/main/resources/db/changelog/057-rbac-role-builder.sql index a428e67f..b3ddbecd 100644 --- a/src/main/resources/db/changelog/057-rbac-role-builder.sql +++ b/src/main/resources/db/changelog/057-rbac-role-builder.sql @@ -31,13 +31,13 @@ create or replace function createRoleWithGrants( called on null input language plpgsql as $$ declare - roleUuid uuid; - subRoleDesc RbacRoleDescriptor; - superRoleDesc RbacRoleDescriptor; - subRoleUuid uuid; - superRoleUuid uuid; - userUuid uuid; - grantedByRoleUuid uuid; -- FIXME: rename to userGrantsByRoleUuid + roleUuid uuid; + subRoleDesc RbacRoleDescriptor; + superRoleDesc RbacRoleDescriptor; + subRoleUuid uuid; + superRoleUuid uuid; + userUuid uuid; + userGrantsByRoleUuid uuid; begin roleUuid := createRole(roleDescriptor); @@ -60,13 +60,13 @@ begin if cardinality(userUuids) > 0 then -- direct grants to users need a grantedByRole which can revoke the grant if grantedByRole is null then - grantedByRoleUuid := roleUuid; -- FIXME: or do we want to require an explicit grantedByRoleUuid? + userGrantsByRoleUuid := roleUuid; -- FIXME: or do we want to require an explicit userGrantsByRoleUuid? else - grantedByRoleUuid := getRoleId(grantedByRole); + userGrantsByRoleUuid := getRoleId(grantedByRole); end if; foreach userUuid in array userUuids loop - call grantRoleToUserUnchecked(grantedByRoleUuid, roleUuid, userUuid); + call grantRoleToUserUnchecked(userGrantsByRoleUuid, roleUuid, userUuid); end loop; end if;