Compare commits
No commits in common. "d1c8c30d8b6a40545d73bed405cf263e01dbc151" and "365a228d44322a4cda136475a87c6303cf16483c" have entirely different histories.
d1c8c30d8b
...
365a228d44
@ -94,7 +94,7 @@ public class RbacGrantsDiagramService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String allGrantsFrom(final UUID targetObject, final String op, final EnumSet<Include> includes) {
|
public String allGrantsFrom(final UUID targetObject, final String op, final EnumSet<Include> includes) {
|
||||||
final var refUuid = (UUID) em.createNativeQuery("SELECT uuid FROM rbac.permission WHERE objectuuid=:targetObject AND op=:op")
|
final var refUuid = (UUID) em.createNativeQuery("SELECT uuid FROM rbacpermission WHERE objectuuid=:targetObject AND op=:op")
|
||||||
.setParameter("targetObject", targetObject)
|
.setParameter("targetObject", targetObject)
|
||||||
.setParameter("op", op)
|
.setParameter("op", op)
|
||||||
.getSingleResult();
|
.getSingleResult();
|
||||||
|
@ -8,7 +8,7 @@ import jakarta.persistence.*;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(schema = "rbac", name = "role_rv")
|
@Table(name = "rbacrole_rv")
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@ToString
|
@ToString
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
*/
|
*/
|
||||||
create type rbac.referenceType as enum ('rbac.subject', 'rbac.role', 'rbac.permission');
|
create type rbac.referenceType as enum ('rbac.subject', 'RbacRole', 'RbacPermission');
|
||||||
|
|
||||||
create table rbac.reference
|
create table rbac.reference
|
||||||
(
|
(
|
||||||
@ -166,7 +166,7 @@ end; $$;
|
|||||||
|
|
||||||
create type RbacRoleType as enum ('OWNER', 'ADMIN', 'AGENT', 'TENANT', 'GUEST', 'REFERRER');
|
create type RbacRoleType as enum ('OWNER', 'ADMIN', 'AGENT', 'TENANT', 'GUEST', 'REFERRER');
|
||||||
|
|
||||||
create table rbac.role
|
create table RbacRole
|
||||||
(
|
(
|
||||||
uuid uuid primary key references rbac.reference (uuid) on delete cascade initially deferred, -- initially deferred
|
uuid uuid primary key references rbac.reference (uuid) on delete cascade initially deferred, -- initially deferred
|
||||||
objectUuid uuid not null references rbac.object (uuid) initially deferred,
|
objectUuid uuid not null references rbac.object (uuid) initially deferred,
|
||||||
@ -174,7 +174,7 @@ create table rbac.role
|
|||||||
unique (objectUuid, roleType)
|
unique (objectUuid, roleType)
|
||||||
);
|
);
|
||||||
|
|
||||||
call base.create_journal('rbac.role');
|
call base.create_journal('RbacRole');
|
||||||
|
|
||||||
create type RbacRoleDescriptor as
|
create type RbacRoleDescriptor as
|
||||||
(
|
(
|
||||||
@ -218,10 +218,10 @@ declare
|
|||||||
begin
|
begin
|
||||||
insert
|
insert
|
||||||
into rbac.reference (type)
|
into rbac.reference (type)
|
||||||
values ('rbac.role')
|
values ('RbacRole')
|
||||||
returning uuid into referenceId;
|
returning uuid into referenceId;
|
||||||
insert
|
insert
|
||||||
into rbac.role (uuid, objectUuid, roleType)
|
into RbacRole (uuid, objectUuid, roleType)
|
||||||
values (referenceId, roleDescriptor.objectUuid, roleDescriptor.roleType);
|
values (referenceId, roleDescriptor.objectUuid, roleDescriptor.roleType);
|
||||||
return referenceId;
|
return referenceId;
|
||||||
end;
|
end;
|
||||||
@ -232,7 +232,7 @@ create or replace procedure deleteRole(roleUUid uuid)
|
|||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
--raise exception '% deleting role uuid %', rbac.currentSubjectOrAssumedRolesUuids(), roleUUid;
|
--raise exception '% deleting role uuid %', rbac.currentSubjectOrAssumedRolesUuids(), roleUUid;
|
||||||
delete from rbac.role where uuid = roleUUid;
|
delete from RbacRole where uuid = roleUUid;
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ begin
|
|||||||
objectUuidOfRole = findObjectUuidByIdName(objectTableFromRoleIdName, objectNameFromRoleIdName);
|
objectUuidOfRole = findObjectUuidByIdName(objectTableFromRoleIdName, objectNameFromRoleIdName);
|
||||||
|
|
||||||
select uuid
|
select uuid
|
||||||
from rbac.role
|
from RbacRole
|
||||||
where objectUuid = objectUuidOfRole
|
where objectUuid = objectUuidOfRole
|
||||||
and roleType = roleTypeFromRoleIdName
|
and roleType = roleTypeFromRoleIdName
|
||||||
into roleUuid;
|
into roleUuid;
|
||||||
@ -267,7 +267,7 @@ create or replace function findRoleId(roleDescriptor RbacRoleDescriptor)
|
|||||||
returns uuid
|
returns uuid
|
||||||
returns null on null input
|
returns null on null input
|
||||||
language sql as $$
|
language sql as $$
|
||||||
select uuid from rbac.role where objectUuid = roleDescriptor.objectUuid and roleType = roleDescriptor.roleType;
|
select uuid from RbacRole where objectUuid = roleDescriptor.objectUuid and roleType = roleDescriptor.roleType;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
create or replace function getRoleId(roleDescriptor RbacRoleDescriptor)
|
create or replace function getRoleId(roleDescriptor RbacRoleDescriptor)
|
||||||
@ -280,7 +280,7 @@ begin
|
|||||||
|
|
||||||
roleUuid := findRoleId(roleDescriptor);
|
roleUuid := findRoleId(roleDescriptor);
|
||||||
if (roleUuid is null) then
|
if (roleUuid is null) then
|
||||||
raise exception 'rbac.role "%#%.%" not found', roleDescriptor.objectTable, roleDescriptor.objectUuid, roleDescriptor.roleType;
|
raise exception 'RbacRole "%#%.%" not found', roleDescriptor.objectTable, roleDescriptor.objectUuid, roleDescriptor.roleType;
|
||||||
end if;
|
end if;
|
||||||
return roleUuid;
|
return roleUuid;
|
||||||
end;
|
end;
|
||||||
@ -292,9 +292,9 @@ $$;
|
|||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
rbac.role BEFORE DELETE TRIGGER function which deletes all related roles.
|
RbacRole BEFORE DELETE TRIGGER function which deletes all related roles.
|
||||||
*/
|
*/
|
||||||
create or replace function rbac.delete_grants_of_role_tf()
|
create or replace function deleteRbacGrantsOfRbacRole()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
@ -308,13 +308,13 @@ begin
|
|||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Installs the rbac.role BEFORE DELETE TRIGGER.
|
Installs the RbacRole BEFORE DELETE TRIGGER.
|
||||||
*/
|
*/
|
||||||
create trigger delete_grants_of_role_tg
|
create trigger deleteRbacGrantsOfRbacRole_Trigger
|
||||||
before delete
|
before delete
|
||||||
on rbac.role
|
on RbacRole
|
||||||
for each row
|
for each row
|
||||||
execute procedure rbac.delete_grants_of_role_tf();
|
execute procedure deleteRbacGrantsOfRbacRole();
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
@ -325,14 +325,14 @@ execute procedure rbac.delete_grants_of_role_tf();
|
|||||||
/*
|
/*
|
||||||
rbac.object BEFORE DELETE TRIGGER function which deletes all related roles.
|
rbac.object BEFORE DELETE TRIGGER function which deletes all related roles.
|
||||||
*/
|
*/
|
||||||
create or replace function rbac.delete_roles_of_object_tf()
|
create or replace function deleteRbacRolesOfRbacObject()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
if TG_OP = 'DELETE' then
|
if TG_OP = 'DELETE' then
|
||||||
delete from rbac.permission p where p.objectuuid = old.uuid;
|
delete from RbacPermission p where p.objectuuid = old.uuid;
|
||||||
delete from rbac.role r where r.objectUuid = old.uuid;
|
delete from RbacRole r where r.objectUuid = old.uuid;
|
||||||
else
|
else
|
||||||
raise exception 'invalid usage of TRIGGER BEFORE DELETE';
|
raise exception 'invalid usage of TRIGGER BEFORE DELETE';
|
||||||
end if;
|
end if;
|
||||||
@ -340,13 +340,13 @@ begin
|
|||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Installs the rbac.role BEFORE DELETE TRIGGER.
|
Installs the RbacRole BEFORE DELETE TRIGGER.
|
||||||
*/
|
*/
|
||||||
create trigger delete_roles_of_object_tg
|
create trigger deleteRbacRolesOfRbacObject_Trigger
|
||||||
before delete
|
before delete
|
||||||
on rbac.object
|
on rbac.object
|
||||||
for each row
|
for each row
|
||||||
execute procedure rbac.delete_roles_of_object_tf();
|
execute procedure deleteRbacRolesOfRbacObject();
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
@ -365,7 +365,7 @@ create domain RbacOp as varchar(6)
|
|||||||
or VALUE = 'ASSUME'
|
or VALUE = 'ASSUME'
|
||||||
);
|
);
|
||||||
|
|
||||||
create table rbac.permission
|
create table RbacPermission
|
||||||
(
|
(
|
||||||
uuid uuid primary key references rbac.reference (uuid) on delete cascade,
|
uuid uuid primary key references rbac.reference (uuid) on delete cascade,
|
||||||
objectUuid uuid not null references rbac.object,
|
objectUuid uuid not null references rbac.object,
|
||||||
@ -373,13 +373,13 @@ create table rbac.permission
|
|||||||
opTableName varchar(60)
|
opTableName varchar(60)
|
||||||
);
|
);
|
||||||
-- TODO.perf: check if these indexes are really useful
|
-- TODO.perf: check if these indexes are really useful
|
||||||
create index on rbac.permission (objectUuid, op);
|
create index on RbacPermission (objectUuid, op);
|
||||||
create index on rbac.permission (opTableName, op);
|
create index on RbacPermission (opTableName, op);
|
||||||
|
|
||||||
ALTER TABLE rbac.permission
|
ALTER TABLE RbacPermission
|
||||||
ADD CONSTRAINT RbacPermission_uc UNIQUE NULLS NOT DISTINCT (objectUuid, op, opTableName);
|
ADD CONSTRAINT RbacPermission_uc UNIQUE NULLS NOT DISTINCT (objectUuid, op, opTableName);
|
||||||
|
|
||||||
call base.create_journal('rbac.permission');
|
call base.create_journal('RbacPermission');
|
||||||
|
|
||||||
create or replace function createPermission(forObjectUuid uuid, forOp RbacOp, forOpTableName text = null)
|
create or replace function createPermission(forObjectUuid uuid, forOp RbacOp, forOpTableName text = null)
|
||||||
returns uuid
|
returns uuid
|
||||||
@ -398,19 +398,19 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
|
|
||||||
permissionUuid := (
|
permissionUuid := (
|
||||||
select uuid from rbac.permission
|
select uuid from RbacPermission
|
||||||
where objectUuid = forObjectUuid
|
where objectUuid = forObjectUuid
|
||||||
and op = forOp and opTableName is not distinct from forOpTableName);
|
and op = forOp and opTableName is not distinct from forOpTableName);
|
||||||
if (permissionUuid is null) then
|
if (permissionUuid is null) then
|
||||||
insert into rbac.reference ("type")
|
insert into rbac.reference ("type")
|
||||||
values ('rbac.permission')
|
values ('RbacPermission')
|
||||||
returning uuid into permissionUuid;
|
returning uuid into permissionUuid;
|
||||||
begin
|
begin
|
||||||
insert into rbac.permission (uuid, objectUuid, op, opTableName)
|
insert into RbacPermission (uuid, objectUuid, op, opTableName)
|
||||||
values (permissionUuid, forObjectUuid, forOp, forOpTableName);
|
values (permissionUuid, forObjectUuid, forOp, forOpTableName);
|
||||||
exception
|
exception
|
||||||
when others then
|
when others then
|
||||||
raise exception 'insert into rbac.permission (uuid, objectUuid, op, opTableName)
|
raise exception 'insert into RbacPermission (uuid, objectUuid, op, opTableName)
|
||||||
values (%, %, %, %);', permissionUuid, forObjectUuid, forOp, forOpTableName;
|
values (%, %, %, %);', permissionUuid, forObjectUuid, forOp, forOpTableName;
|
||||||
end;
|
end;
|
||||||
end if;
|
end if;
|
||||||
@ -423,7 +423,7 @@ create or replace function findEffectivePermissionId(forObjectUuid uuid, forOp R
|
|||||||
stable -- leakproof
|
stable -- leakproof
|
||||||
language sql as $$
|
language sql as $$
|
||||||
select uuid
|
select uuid
|
||||||
from rbac.permission p
|
from RbacPermission p
|
||||||
where p.objectUuid = forObjectUuid
|
where p.objectUuid = forObjectUuid
|
||||||
and (forOp = 'SELECT' or p.op = forOp) -- all other RbacOp include 'SELECT'
|
and (forOp = 'SELECT' or p.op = forOp) -- all other RbacOp include 'SELECT'
|
||||||
and p.opTableName = forOpTableName
|
and p.opTableName = forOpTableName
|
||||||
@ -435,7 +435,7 @@ create or replace function findPermissionId(forObjectUuid uuid, forOp RbacOp, fo
|
|||||||
stable -- leakproof
|
stable -- leakproof
|
||||||
language sql as $$
|
language sql as $$
|
||||||
select uuid
|
select uuid
|
||||||
from rbac.permission p
|
from RbacPermission p
|
||||||
where p.objectUuid = forObjectUuid
|
where p.objectUuid = forObjectUuid
|
||||||
and p.op = forOp
|
and p.op = forOp
|
||||||
and p.opTableName = forOpTableName
|
and p.opTableName = forOpTableName
|
||||||
@ -449,7 +449,7 @@ declare
|
|||||||
permissionUuid uuid;
|
permissionUuid uuid;
|
||||||
begin
|
begin
|
||||||
select uuid into permissionUuid
|
select uuid into permissionUuid
|
||||||
from rbac.permission p
|
from RbacPermission p
|
||||||
where p.objectUuid = forObjectUuid
|
where p.objectUuid = forObjectUuid
|
||||||
and p.op = forOp
|
and p.op = forOp
|
||||||
and forOpTableName is null or p.opTableName = forOpTableName;
|
and forOpTableName is null or p.opTableName = forOpTableName;
|
||||||
@ -470,8 +470,8 @@ declare
|
|||||||
subRoleIdName text;
|
subRoleIdName text;
|
||||||
superRoleIdName text;
|
superRoleIdName text;
|
||||||
begin
|
begin
|
||||||
select roleIdName from rbac.role_ev where uuid=subRoleId into subRoleIdName;
|
select roleIdName from rbacRole_ev where uuid=subRoleId into subRoleIdName;
|
||||||
select roleIdName from rbac.role_ev where uuid=superRoleId into superRoleIdName;
|
select roleIdName from rbacRole_ev where uuid=superRoleId into superRoleIdName;
|
||||||
raise exception '[400] Duplicate role grant detected: role % (%) already granted to % (%)', subRoleId, subRoleIdName, superRoleId, superRoleIdName;
|
raise exception '[400] Duplicate role grant detected: role % (%) already granted to % (%)', subRoleId, subRoleIdName, superRoleId, superRoleIdName;
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
@ -488,7 +488,7 @@ create table rbac.grants
|
|||||||
(
|
(
|
||||||
uuid uuid primary key default uuid_generate_v4(),
|
uuid uuid primary key default uuid_generate_v4(),
|
||||||
grantedByTriggerOf uuid references rbac.object (uuid) on delete cascade initially deferred ,
|
grantedByTriggerOf uuid references rbac.object (uuid) on delete cascade initially deferred ,
|
||||||
grantedByRoleUuid uuid references rbac.role (uuid),
|
grantedByRoleUuid uuid references RbacRole (uuid),
|
||||||
ascendantUuid uuid references rbac.reference (uuid),
|
ascendantUuid uuid references rbac.reference (uuid),
|
||||||
descendantUuid uuid references rbac.reference (uuid),
|
descendantUuid uuid references rbac.reference (uuid),
|
||||||
assumed boolean not null default true, -- auto assumed (true) vs. needs assumeRoles (false)
|
assumed boolean not null default true, -- auto assumed (true) vs. needs assumeRoles (false)
|
||||||
@ -581,7 +581,7 @@ create or replace function hasGlobalRoleGranted(forAscendantUuid uuid)
|
|||||||
select exists(
|
select exists(
|
||||||
select r.uuid
|
select r.uuid
|
||||||
from rbac.grants as g
|
from rbac.grants as g
|
||||||
join rbac.role as r on r.uuid = g.descendantuuid
|
join RbacRole as r on r.uuid = g.descendantuuid
|
||||||
join rbac.object as o on o.uuid = r.objectuuid
|
join rbac.object as o on o.uuid = r.objectuuid
|
||||||
where g.ascendantuuid = forAscendantUuid
|
where g.ascendantuuid = forAscendantUuid
|
||||||
and o.objecttable = 'rbac.global'
|
and o.objecttable = 'rbac.global'
|
||||||
@ -591,8 +591,8 @@ $$;
|
|||||||
create or replace procedure grantPermissionToRole(permissionUuid uuid, roleUuid uuid)
|
create or replace procedure grantPermissionToRole(permissionUuid uuid, roleUuid uuid)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
perform rbac.assertReferenceType('roleId (ascendant)', roleUuid, 'rbac.role');
|
perform rbac.assertReferenceType('roleId (ascendant)', roleUuid, 'RbacRole');
|
||||||
perform rbac.assertReferenceType('permissionId (descendant)', permissionUuid, 'rbac.permission');
|
perform rbac.assertReferenceType('permissionId (descendant)', permissionUuid, 'RbacPermission');
|
||||||
|
|
||||||
insert
|
insert
|
||||||
into rbac.grants (grantedByTriggerOf, ascendantUuid, descendantUuid, assumed)
|
into rbac.grants (grantedByTriggerOf, ascendantUuid, descendantUuid, assumed)
|
||||||
@ -611,8 +611,8 @@ $$;
|
|||||||
create or replace procedure grantRoleToRole(subRoleId uuid, superRoleId uuid, doAssume bool = true)
|
create or replace procedure grantRoleToRole(subRoleId uuid, superRoleId uuid, doAssume bool = true)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
perform rbac.assertReferenceType('superRoleId (ascendant)', superRoleId, 'rbac.role');
|
perform rbac.assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole');
|
||||||
perform rbac.assertReferenceType('subRoleId (descendant)', subRoleId, 'rbac.role');
|
perform rbac.assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole');
|
||||||
|
|
||||||
if isGranted(subRoleId, superRoleId) then
|
if isGranted(subRoleId, superRoleId) then
|
||||||
call raiseDuplicateRoleGrantException(subRoleId, superRoleId);
|
call raiseDuplicateRoleGrantException(subRoleId, superRoleId);
|
||||||
@ -639,8 +639,8 @@ begin
|
|||||||
superRoleId := findRoleId(superRole);
|
superRoleId := findRoleId(superRole);
|
||||||
subRoleId := findRoleId(subRole);
|
subRoleId := findRoleId(subRole);
|
||||||
|
|
||||||
perform rbac.assertReferenceType('superRoleId (ascendant)', superRoleId, 'rbac.role');
|
perform rbac.assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole');
|
||||||
perform rbac.assertReferenceType('subRoleId (descendant)', subRoleId, 'rbac.role');
|
perform rbac.assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole');
|
||||||
|
|
||||||
if isGranted(subRoleId, superRoleId) then
|
if isGranted(subRoleId, superRoleId) then
|
||||||
call raiseDuplicateRoleGrantException(subRoleId, superRoleId);
|
call raiseDuplicateRoleGrantException(subRoleId, superRoleId);
|
||||||
@ -661,8 +661,8 @@ begin
|
|||||||
superRoleId := findRoleId(superRole);
|
superRoleId := findRoleId(superRole);
|
||||||
subRoleId := findRoleId(subRole);
|
subRoleId := findRoleId(subRole);
|
||||||
|
|
||||||
perform rbac.assertReferenceType('superRoleId (ascendant)', superRoleId, 'rbac.role');
|
perform rbac.assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole');
|
||||||
perform rbac.assertReferenceType('subRoleId (descendant)', subRoleId, 'rbac.role');
|
perform rbac.assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole');
|
||||||
|
|
||||||
if (isGranted(superRoleId, subRoleId)) then
|
if (isGranted(superRoleId, subRoleId)) then
|
||||||
delete from rbac.grants where ascendantUuid = superRoleId and descendantUuid = subRoleId;
|
delete from rbac.grants where ascendantUuid = superRoleId and descendantUuid = subRoleId;
|
||||||
@ -682,15 +682,15 @@ declare
|
|||||||
begin
|
begin
|
||||||
superRoleId := findRoleId(superRole);
|
superRoleId := findRoleId(superRole);
|
||||||
|
|
||||||
perform rbac.assertReferenceType('superRoleId (ascendant)', superRoleId, 'rbac.role');
|
perform rbac.assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole');
|
||||||
perform rbac.assertReferenceType('permission (descendant)', permissionId, 'rbac.permission');
|
perform rbac.assertReferenceType('permission (descendant)', permissionId, 'RbacPermission');
|
||||||
|
|
||||||
if (isGranted(superRoleId, permissionId)) then
|
if (isGranted(superRoleId, permissionId)) then
|
||||||
delete from rbac.grants where ascendantUuid = superRoleId and descendantUuid = permissionId;
|
delete from rbac.grants where ascendantUuid = superRoleId and descendantUuid = permissionId;
|
||||||
else
|
else
|
||||||
select p.op, o.objectTable, o.uuid
|
select p.op, o.objectTable, o.uuid
|
||||||
from rbac.grants g
|
from rbac.grants g
|
||||||
join rbac.permission p on p.uuid=g.descendantUuid
|
join rbacPermission p on p.uuid=g.descendantUuid
|
||||||
join rbac.object o on o.uuid=p.objectUuid
|
join rbac.object o on o.uuid=p.objectUuid
|
||||||
where g.uuid=permissionId
|
where g.uuid=permissionId
|
||||||
into permissionOp, objectTable, objectUuid;
|
into permissionOp, objectTable, objectUuid;
|
||||||
@ -735,7 +735,7 @@ begin
|
|||||||
)
|
)
|
||||||
SELECT DISTINCT perm.objectUuid
|
SELECT DISTINCT perm.objectUuid
|
||||||
FROM granted
|
FROM granted
|
||||||
JOIN rbac.permission perm ON granted.descendantUuid = perm.uuid
|
JOIN RbacPermission perm ON granted.descendantUuid = perm.uuid
|
||||||
JOIN rbac.object obj ON obj.uuid = perm.objectUuid
|
JOIN rbac.object obj ON obj.uuid = perm.objectUuid
|
||||||
WHERE (requiredOp = 'SELECT' OR perm.op = requiredOp)
|
WHERE (requiredOp = 'SELECT' OR perm.op = requiredOp)
|
||||||
AND obj.objectTable = forObjectTable
|
AND obj.objectTable = forObjectTable
|
||||||
@ -759,7 +759,7 @@ $$;
|
|||||||
Returns all permissions accessible to the given subject UUID (subject or role).
|
Returns all permissions accessible to the given subject UUID (subject or role).
|
||||||
*/
|
*/
|
||||||
create or replace function queryPermissionsGrantedToSubjectId(subjectId uuid)
|
create or replace function queryPermissionsGrantedToSubjectId(subjectId uuid)
|
||||||
returns setof rbac.permission
|
returns setof RbacPermission
|
||||||
strict
|
strict
|
||||||
language sql as $$
|
language sql as $$
|
||||||
with recursive grants as (
|
with recursive grants as (
|
||||||
@ -772,7 +772,7 @@ with recursive grants as (
|
|||||||
inner join grants on grants.descendantUuid = g.ascendantUuid
|
inner join grants on grants.descendantUuid = g.ascendantUuid
|
||||||
)
|
)
|
||||||
select perm.*
|
select perm.*
|
||||||
from rbac.permission perm
|
from RbacPermission perm
|
||||||
where perm.uuid in (
|
where perm.uuid in (
|
||||||
select descendantUuid
|
select descendantUuid
|
||||||
from grants
|
from grants
|
||||||
|
@ -23,8 +23,8 @@ end; $$;
|
|||||||
create or replace procedure rbac.grantRoleToUserUnchecked(grantedByRoleUuid uuid, grantedRoleUuid uuid, subjectUuid uuid, doAssume boolean = true)
|
create or replace procedure rbac.grantRoleToUserUnchecked(grantedByRoleUuid uuid, grantedRoleUuid uuid, subjectUuid uuid, doAssume boolean = true)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
perform rbac.assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'rbac.role');
|
perform rbac.assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'RbacRole');
|
||||||
perform rbac.assertReferenceType('roleId (descendant)', grantedRoleUuid, 'rbac.role');
|
perform rbac.assertReferenceType('roleId (descendant)', grantedRoleUuid, 'RbacRole');
|
||||||
perform rbac.assertReferenceType('subjectUuid (ascendant)', subjectUuid, 'rbac.subject');
|
perform rbac.assertReferenceType('subjectUuid (ascendant)', subjectUuid, 'rbac.subject');
|
||||||
|
|
||||||
insert
|
insert
|
||||||
@ -40,8 +40,8 @@ declare
|
|||||||
grantedByRoleIdName text;
|
grantedByRoleIdName text;
|
||||||
grantedRoleIdName text;
|
grantedRoleIdName text;
|
||||||
begin
|
begin
|
||||||
perform rbac.assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'rbac.role');
|
perform rbac.assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'RbacRole');
|
||||||
perform rbac.assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'rbac.role');
|
perform rbac.assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'RbacRole');
|
||||||
perform rbac.assertReferenceType('subjectUuid (ascendant)', subjectUuid, 'rbac.subject');
|
perform rbac.assertReferenceType('subjectUuid (ascendant)', subjectUuid, 'rbac.subject');
|
||||||
|
|
||||||
assert grantedByRoleUuid is not null, 'grantedByRoleUuid must not be null';
|
assert grantedByRoleUuid is not null, 'grantedByRoleUuid must not be null';
|
||||||
@ -49,13 +49,13 @@ begin
|
|||||||
assert subjectUuid is not null, 'subjectUuid must not be null';
|
assert subjectUuid is not null, 'subjectUuid must not be null';
|
||||||
|
|
||||||
if NOT isGranted(rbac.currentSubjectOrAssumedRolesUuids(), grantedByRoleUuid) then
|
if NOT isGranted(rbac.currentSubjectOrAssumedRolesUuids(), grantedByRoleUuid) then
|
||||||
select roleIdName from rbac.role_ev where uuid=grantedByRoleUuid into grantedByRoleIdName;
|
select roleIdName from rbacRole_ev where uuid=grantedByRoleUuid into grantedByRoleIdName;
|
||||||
raise exception '[403] Access to granted-by-role % (%) forbidden for % (%)',
|
raise exception '[403] Access to granted-by-role % (%) forbidden for % (%)',
|
||||||
grantedByRoleIdName, grantedByRoleUuid, currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
|
grantedByRoleIdName, grantedByRoleUuid, currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
|
||||||
end if;
|
end if;
|
||||||
if NOT isGranted(grantedByRoleUuid, grantedRoleUuid) then
|
if NOT isGranted(grantedByRoleUuid, grantedRoleUuid) then
|
||||||
select roleIdName from rbac.role_ev where uuid=grantedByRoleUuid into grantedByRoleIdName;
|
select roleIdName from rbacRole_ev where uuid=grantedByRoleUuid into grantedByRoleIdName;
|
||||||
select roleIdName from rbac.role_ev where uuid=grantedRoleUuid into grantedRoleIdName;
|
select roleIdName from rbacRole_ev where uuid=grantedRoleUuid into grantedRoleIdName;
|
||||||
raise exception '[403] Access to granted role % (%) forbidden for % (%)',
|
raise exception '[403] Access to granted role % (%) forbidden for % (%)',
|
||||||
grantedRoleIdName, grantedRoleUuid, grantedByRoleIdName, grantedByRoleUuid;
|
grantedRoleIdName, grantedRoleUuid, grantedByRoleIdName, grantedByRoleUuid;
|
||||||
end if;
|
end if;
|
||||||
@ -77,8 +77,8 @@ end; $$;
|
|||||||
create or replace procedure rbac.checkRevokeRoleFromSubjectPreconditions(grantedByRoleUuid uuid, grantedRoleUuid uuid, subjectUuid uuid)
|
create or replace procedure rbac.checkRevokeRoleFromSubjectPreconditions(grantedByRoleUuid uuid, grantedRoleUuid uuid, subjectUuid uuid)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
perform rbac.assertReferenceType('grantedByRoleUuid', grantedByRoleUuid, 'rbac.role');
|
perform rbac.assertReferenceType('grantedByRoleUuid', grantedByRoleUuid, 'RbacRole');
|
||||||
perform rbac.assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'rbac.role');
|
perform rbac.assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'RbacRole');
|
||||||
perform rbac.assertReferenceType('subjectUuid (ascendant)', subjectUuid, 'rbac.subject');
|
perform rbac.assertReferenceType('subjectUuid (ascendant)', subjectUuid, 'rbac.subject');
|
||||||
|
|
||||||
if NOT isGranted(rbac.currentSubjectOrAssumedRolesUuids(), grantedByRoleUuid) then
|
if NOT isGranted(rbac.currentSubjectOrAssumedRolesUuids(), grantedByRoleUuid) then
|
||||||
|
@ -61,7 +61,7 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
|
|
||||||
select uuid
|
select uuid
|
||||||
from rbac.role r
|
from RbacRole r
|
||||||
where r.objectUuid = objectUuidToAssume
|
where r.objectUuid = objectUuidToAssume
|
||||||
and r.roleType = roleTypeToAssume
|
and r.roleType = roleTypeToAssume
|
||||||
into roleUuidToAssume;
|
into roleUuidToAssume;
|
||||||
|
@ -7,14 +7,14 @@
|
|||||||
Creates a view to the role table with additional columns
|
Creates a view to the role table with additional columns
|
||||||
for easier human readability.
|
for easier human readability.
|
||||||
*/
|
*/
|
||||||
drop view if exists rbac.role_ev;
|
drop view if exists rbacrole_ev;
|
||||||
create or replace view rbac.role_ev as
|
create or replace view rbacrole_ev as
|
||||||
select (objectTable || '#' || objectIdName || ':' || roleType) as roleIdName, *
|
select (objectTable || '#' || objectIdName || ':' || roleType) as roleIdName, *
|
||||||
-- @formatter:off
|
-- @formatter:off
|
||||||
from (
|
from (
|
||||||
select r.*,
|
select r.*,
|
||||||
o.objectTable, findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName
|
o.objectTable, findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName
|
||||||
from rbac.role as r
|
from rbacrole as r
|
||||||
join rbac.object as o on o.uuid = r.objectuuid
|
join rbac.object as o on o.uuid = r.objectuuid
|
||||||
) as unordered
|
) as unordered
|
||||||
-- @formatter:on
|
-- @formatter:on
|
||||||
@ -28,20 +28,20 @@ select (objectTable || '#' || objectIdName || ':' || roleType) as roleIdName, *
|
|||||||
Creates a view to the role table with row-level limitation
|
Creates a view to the role table with row-level limitation
|
||||||
based on the grants of the current user or assumed roles.
|
based on the grants of the current user or assumed roles.
|
||||||
*/
|
*/
|
||||||
drop view if exists rbac.role_rv;
|
drop view if exists rbacrole_rv;
|
||||||
create or replace view rbac.role_rv as
|
create or replace view rbacrole_rv as
|
||||||
select *
|
select *
|
||||||
-- @formatter:off
|
-- @formatter:off
|
||||||
from (
|
from (
|
||||||
select r.*, o.objectTable,
|
select r.*, o.objectTable,
|
||||||
findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName
|
findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName
|
||||||
from rbac.role as r
|
from rbacrole as r
|
||||||
join rbac.object as o on o.uuid = r.objectuuid
|
join rbac.object as o on o.uuid = r.objectuuid
|
||||||
where isGranted(rbac.currentSubjectOrAssumedRolesUuids(), r.uuid)
|
where isGranted(rbac.currentSubjectOrAssumedRolesUuids(), r.uuid)
|
||||||
) as unordered
|
) as unordered
|
||||||
-- @formatter:on
|
-- @formatter:on
|
||||||
order by objectTable || '#' || objectIdName || ':' || roleType;
|
order by objectTable || '#' || objectIdName || ':' || roleType;
|
||||||
grant all privileges on rbac.role_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
grant all privileges on rbacrole_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
@ -87,16 +87,16 @@ create or replace view rbacgrants_ev as
|
|||||||
dp.op, dp.optablename
|
dp.op, dp.optablename
|
||||||
from rbac.grants as g
|
from rbac.grants as g
|
||||||
|
|
||||||
left outer join rbac.role as ar on ar.uuid = g.ascendantUuid
|
left outer join rbacrole as ar on ar.uuid = g.ascendantUuid
|
||||||
left outer join rbac.object as aro on aro.uuid = ar.objectuuid
|
left outer join rbac.object as aro on aro.uuid = ar.objectuuid
|
||||||
left outer join rbac.subject as au on au.uuid = g.ascendantUuid
|
left outer join rbac.subject as au on au.uuid = g.ascendantUuid
|
||||||
|
|
||||||
left outer join rbac.role as dr on dr.uuid = g.descendantUuid
|
left outer join rbacrole as dr on dr.uuid = g.descendantUuid
|
||||||
left outer join rbac.object as dro on dro.uuid = dr.objectuuid
|
left outer join rbac.object as dro on dro.uuid = dr.objectuuid
|
||||||
left outer join rbac.permission dp on dp.uuid = g.descendantUuid
|
left outer join rbacpermission dp on dp.uuid = g.descendantUuid
|
||||||
left outer join rbac.object as dpo on dpo.uuid = dp.objectUuid
|
left outer join rbac.object as dpo on dpo.uuid = dp.objectUuid
|
||||||
) as x
|
) as x
|
||||||
left outer join rbac.role as r on r.uuid = grantedByRoleUuid
|
left outer join rbacrole as r on r.uuid = grantedByRoleUuid
|
||||||
left outer join rbac.subject u on u.uuid = x.ascendantuuid
|
left outer join rbac.subject u on u.uuid = x.ascendantuuid
|
||||||
left outer join rbac.object go on go.uuid = r.objectuuid
|
left outer join rbac.object go on go.uuid = r.objectuuid
|
||||||
|
|
||||||
@ -124,16 +124,16 @@ select o.objectTable || '#' || findIdNameByObjectUuid(o.objectTable, o.uuid) ||
|
|||||||
u.name as userName, o.objecttable, r.objectuuid, r.roletype,
|
u.name as userName, o.objecttable, r.objectuuid, r.roletype,
|
||||||
findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName
|
findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName
|
||||||
from rbac.grants as g
|
from rbac.grants as g
|
||||||
join rbac.role as r on r.uuid = g.descendantUuid
|
join rbacrole as r on r.uuid = g.descendantUuid
|
||||||
join rbac.object o on o.uuid = r.objectuuid
|
join rbac.object o on o.uuid = r.objectuuid
|
||||||
left outer join rbac.subject u on u.uuid = g.ascendantuuid
|
left outer join rbac.subject u on u.uuid = g.ascendantuuid
|
||||||
where isGranted(rbac.currentSubjectOrAssumedRolesUuids(), r.uuid)
|
where isGranted(rbac.currentSubjectOrAssumedRolesUuids(), r.uuid)
|
||||||
) as g
|
) as g
|
||||||
join rbac.role as r on r.uuid = grantedByRoleUuid
|
join RbacRole as r on r.uuid = grantedByRoleUuid
|
||||||
join rbac.object as o on o.uuid = r.objectUuid
|
join rbac.object as o on o.uuid = r.objectUuid
|
||||||
order by grantedRoleIdName;
|
order by grantedRoleIdName;
|
||||||
-- @formatter:on
|
-- @formatter:on
|
||||||
grant all privileges on rbac.role_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
grant all privileges on rbacrole_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
@ -212,7 +212,7 @@ select distinct *
|
|||||||
select usersInRolesOfcurrentSubject.*
|
select usersInRolesOfcurrentSubject.*
|
||||||
from rbac.subject as usersInRolesOfcurrentSubject
|
from rbac.subject as usersInRolesOfcurrentSubject
|
||||||
join rbac.grants as g on g.ascendantuuid = usersInRolesOfcurrentSubject.uuid
|
join rbac.grants as g on g.ascendantuuid = usersInRolesOfcurrentSubject.uuid
|
||||||
join rbac.role_ev as r on r.uuid = g.descendantuuid
|
join rbacrole_ev as r on r.uuid = g.descendantuuid
|
||||||
union
|
union
|
||||||
select users.*
|
select users.*
|
||||||
from rbac.subject as users
|
from rbac.subject as users
|
||||||
@ -237,7 +237,7 @@ create or replace view rbac.subject_rv as
|
|||||||
select usersInRolesOfcurrentSubject.*
|
select usersInRolesOfcurrentSubject.*
|
||||||
from rbac.subject as usersInRolesOfcurrentSubject
|
from rbac.subject as usersInRolesOfcurrentSubject
|
||||||
join rbac.grants as g on g.ascendantuuid = usersInRolesOfcurrentSubject.uuid
|
join rbac.grants as g on g.ascendantuuid = usersInRolesOfcurrentSubject.uuid
|
||||||
join rbac.role_rv as r on r.uuid = g.descendantuuid
|
join rbacrole_rv as r on r.uuid = g.descendantuuid
|
||||||
union
|
union
|
||||||
select users.*
|
select users.*
|
||||||
from rbac.subject as users
|
from rbac.subject as users
|
||||||
@ -329,9 +329,9 @@ create or replace view rbac.own_granted_permissions_rv as
|
|||||||
select r.uuid as roleuuid, p.uuid as permissionUuid,
|
select r.uuid as roleuuid, p.uuid as permissionUuid,
|
||||||
(r.objecttable || ':' || r.objectidname || ':' || r.roletype) as roleName, p.op,
|
(r.objecttable || ':' || r.objectidname || ':' || r.roletype) as roleName, p.op,
|
||||||
o.objecttable, r.objectidname, o.uuid as objectuuid
|
o.objecttable, r.objectidname, o.uuid as objectuuid
|
||||||
from rbac.role_rv r
|
from rbacrole_rv r
|
||||||
join rbac.grants g on g.ascendantuuid = r.uuid
|
join rbac.grants g on g.ascendantuuid = r.uuid
|
||||||
join rbac.permission p on p.uuid = g.descendantuuid
|
join rbacpermission p on p.uuid = g.descendantuuid
|
||||||
join rbac.object o on o.uuid = p.objectuuid;
|
join rbac.object o on o.uuid = p.objectuuid;
|
||||||
grant all privileges on rbac.own_granted_permissions_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
grant all privileges on rbac.own_granted_permissions_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||||
-- @formatter:om
|
-- @formatter:om
|
||||||
@ -372,7 +372,7 @@ begin
|
|||||||
from queryPermissionsGrantedToSubjectId( targetSubjectUuid) as p
|
from queryPermissionsGrantedToSubjectId( targetSubjectUuid) as p
|
||||||
join rbac.grants 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 rbac.object as po on po.uuid = p.objectUuid
|
||||||
join rbac.role_rv as r on r.uuid = g.ascendantUuid
|
join rbacrole_rv as r on r.uuid = g.ascendantUuid
|
||||||
join rbac.object as ro on ro.uuid = r.objectUuid
|
join rbac.object as ro on ro.uuid = r.objectUuid
|
||||||
where isGranted(targetSubjectUuid, r.uuid)
|
where isGranted(targetSubjectUuid, r.uuid)
|
||||||
) xp;
|
) xp;
|
||||||
|
@ -202,7 +202,7 @@ begin
|
|||||||
as valid)
|
as valid)
|
||||||
select distinct perm.objectuuid
|
select distinct perm.objectuuid
|
||||||
from recursive_grants
|
from recursive_grants
|
||||||
join rbac.permission perm on recursive_grants.descendantuuid = perm.uuid
|
join rbacpermission perm on recursive_grants.descendantuuid = perm.uuid
|
||||||
join rbac.object obj on obj.uuid = perm.objectuuid
|
join rbac.object obj on obj.uuid = perm.objectuuid
|
||||||
join count_check cc on cc.valid
|
join count_check cc on cc.valid
|
||||||
where obj.objectTable = '%1$s' -- 'SELECT' permission is included in all other permissions
|
where obj.objectTable = '%1$s' -- 'SELECT' permission is included in all other permissions
|
||||||
|
@ -11,10 +11,10 @@ select no, to_char("count", '9 999 999 999') as "count", "table"
|
|||||||
from rbac.subject
|
from rbac.subject
|
||||||
union
|
union
|
||||||
select 2 as no, count(*) as "count", 'roles' as "table"
|
select 2 as no, count(*) as "count", 'roles' as "table"
|
||||||
from rbac.role
|
from RbacRole
|
||||||
union
|
union
|
||||||
select 3 as no, count(*) as "count", 'permissions' as "table"
|
select 3 as no, count(*) as "count", 'permissions' as "table"
|
||||||
from rbac.permission
|
from RbacPermission
|
||||||
union
|
union
|
||||||
select 4 as no, count(*) as "count", 'references' as "table"
|
select 4 as no, count(*) as "count", 'references' as "table"
|
||||||
from rbac.reference
|
from rbac.reference
|
||||||
|
@ -10,7 +10,7 @@ import java.util.List;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(schema = "rbac", name = "role_ev")
|
@Table(name = "rbacrole_ev")
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@ToString
|
@ToString
|
||||||
|
@ -305,7 +305,7 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
|
|||||||
protected String[] roleNames(final String sqlLikeExpression) {
|
protected String[] roleNames(final String sqlLikeExpression) {
|
||||||
final var pattern = Pattern.compile(sqlLikeExpression);
|
final var pattern = Pattern.compile(sqlLikeExpression);
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
final List<Object[]> rows = (List<Object[]>) em.createNativeQuery("select * from rbac.role_ev where roleidname like 'hs_booking_project#%'")
|
final List<Object[]> rows = (List<Object[]>) em.createNativeQuery("select * from rbacrole_ev where roleidname like 'hs_booking_project#%'")
|
||||||
.getResultList();
|
.getResultList();
|
||||||
return rows.stream()
|
return rows.stream()
|
||||||
.map(row -> (row[0]).toString())
|
.map(row -> (row[0]).toString())
|
||||||
|
Loading…
Reference in New Issue
Block a user