improved role structure including comprised tenant sub roles
This commit is contained in:
208
sql/12-rbac-role-builder.sql
Normal file
208
sql/12-rbac-role-builder.sql
Normal file
@@ -0,0 +1,208 @@
|
||||
|
||||
|
||||
-- ========================================================
|
||||
-- Role-Hierarcy helper functions
|
||||
-- --------------------------------------------------------
|
||||
|
||||
CREATE TYPE RbacRoleType AS ENUM ('owner', 'admin', 'tenant');
|
||||
|
||||
-- PERMISSIONS --------------------------------------------
|
||||
|
||||
-- drop type RbacPermissions;
|
||||
CREATE TYPE RbacPermissions AS
|
||||
(
|
||||
permissionUuids uuid[]
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION grantingPermissions(forObjectUuid uuid, permitOps RbacOp[])
|
||||
RETURNS RbacPermissions
|
||||
LANGUAGE plpgsql STRICT AS $$
|
||||
BEGIN
|
||||
RETURN ROW(createPermissions(forObjectUuid, permitOps))::RbacPermissions;
|
||||
END; $$;
|
||||
|
||||
-- SUPER ROLES --------------------------------------------
|
||||
|
||||
-- drop type RbacSuperRoles;
|
||||
CREATE TYPE RbacSuperRoles AS
|
||||
(
|
||||
roleUuids uuid[]
|
||||
);
|
||||
|
||||
-- drop function beneathRoles(roleName varchar);
|
||||
CREATE OR REPLACE FUNCTION beneathRoles(roleNames varchar[])
|
||||
RETURNS RbacSuperRoles
|
||||
LANGUAGE plpgsql STRICT AS $$
|
||||
DECLARE
|
||||
superRoleName varchar;
|
||||
superRoleUuids uuid[] := ARRAY[]::uuid[];
|
||||
BEGIN
|
||||
FOREACH superRoleName IN ARRAY roleNames LOOP
|
||||
superRoleUuids := superRoleUuids || getRoleId(superRoleName, 'fail');
|
||||
END LOOP;
|
||||
|
||||
RETURN ROW(superRoleUuids)::RbacSuperRoles;
|
||||
END; $$;
|
||||
|
||||
-- drop function beneathRole(roleName varchar);
|
||||
CREATE OR REPLACE FUNCTION beneathRole(roleName varchar)
|
||||
RETURNS RbacSuperRoles
|
||||
LANGUAGE plpgsql STRICT AS $$
|
||||
BEGIN
|
||||
RETURN beneathRoles(ARRAY[roleName]);
|
||||
END; $$;
|
||||
|
||||
-- drop function beneathRole(roleUuid uuid);
|
||||
CREATE OR REPLACE FUNCTION beneathRole(roleUuid uuid)
|
||||
RETURNS RbacSuperRoles
|
||||
LANGUAGE plpgsql STRICT AS $$
|
||||
BEGIN
|
||||
RETURN ROW(ARRAY[roleUuid]::uuid[])::RbacSuperRoles;
|
||||
END; $$;
|
||||
|
||||
-- drop function asTopLevelRole(roleName varchar);
|
||||
CREATE OR REPLACE FUNCTION asTopLevelRole()
|
||||
RETURNS RbacSuperRoles
|
||||
LANGUAGE plpgsql STRICT AS $$
|
||||
BEGIN
|
||||
RETURN ROW(ARRAY[]::uuid[])::RbacSuperRoles;
|
||||
END; $$;
|
||||
|
||||
-- SUB ROLES ----------------------------------------------
|
||||
|
||||
CREATE TYPE RbacSubRoles AS
|
||||
(
|
||||
roleUuids uuid[]
|
||||
);
|
||||
|
||||
-- drop FUNCTION beingItselfA(roleUuid uuid)
|
||||
CREATE OR REPLACE FUNCTION beingItselfA(roleUuid uuid)
|
||||
RETURNS RbacSubRoles
|
||||
LANGUAGE plpgsql STRICT AS $$
|
||||
BEGIN
|
||||
RETURN ROW(ARRAY[roleUuid]::uuid[])::RbacSubRoles;
|
||||
END; $$;
|
||||
|
||||
-- drop FUNCTION beingItselfA(roleName varchar)
|
||||
CREATE OR REPLACE FUNCTION beingItselfA(roleName varchar)
|
||||
RETURNS RbacSubRoles
|
||||
LANGUAGE plpgsql STRICT AS $$
|
||||
BEGIN
|
||||
RETURN beingItselfA(getRoleId(roleName, 'fail'));
|
||||
END; $$;
|
||||
|
||||
-- USERS --------------------------------------------------
|
||||
|
||||
-- drop type RbacUsers;
|
||||
CREATE TYPE RbacUsers AS
|
||||
(
|
||||
userUuids uuid[]
|
||||
);
|
||||
|
||||
-- drop function withUsers(userNames varchar);
|
||||
CREATE OR REPLACE FUNCTION withUsers(userNames varchar[])
|
||||
RETURNS RbacUsers
|
||||
LANGUAGE plpgsql STRICT AS $$
|
||||
DECLARE
|
||||
userName varchar;
|
||||
userUuids uuid[] := ARRAY[]::uuid[];
|
||||
BEGIN
|
||||
FOREACH userName IN ARRAY userNames LOOP
|
||||
userUuids := userUuids || getRbacUserId(userName, 'fail');
|
||||
END LOOP;
|
||||
|
||||
RETURN ROW(userUuids)::RbacUsers;
|
||||
END; $$;
|
||||
|
||||
|
||||
-- DROP FUNCTION withUser(userName varchar, whenNotExists RbacWhenNotExists);
|
||||
CREATE OR REPLACE FUNCTION withUser(userName varchar, whenNotExists RbacWhenNotExists = 'fail')
|
||||
RETURNS RbacUsers
|
||||
RETURNS NULL ON NULL INPUT
|
||||
LANGUAGE plpgsql AS $$
|
||||
BEGIN
|
||||
RETURN ROW(ARRAY[getRbacUserId(userName, whenNotExists )]);
|
||||
END; $$;
|
||||
|
||||
-- ROLE NAME BUILDER --------------------------------------
|
||||
|
||||
CREATE OR REPLACE FUNCTION roleName(objectTable varchar, objectName varchar, roleType RbacRoleType )
|
||||
RETURNS varchar
|
||||
RETURNS NULL ON NULL INPUT
|
||||
STABLE LEAKPROOF
|
||||
LANGUAGE plpgsql AS $$
|
||||
BEGIN
|
||||
RETURN objectTable || '#' || objectName || '.' || roleType;
|
||||
END; $$;
|
||||
|
||||
|
||||
-- CREATE ROLE MAIN FUNCTION ------------------------------
|
||||
|
||||
CREATE OR REPLACE FUNCTION createRole(
|
||||
roleName varchar,
|
||||
permissions RbacPermissions,
|
||||
superRoles RbacSuperRoles,
|
||||
subRoles RbacSubRoles = null,
|
||||
users RbacUsers = null
|
||||
)
|
||||
RETURNS uuid
|
||||
CALLED ON NULL INPUT
|
||||
LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
roleUuid uuid;
|
||||
superRoleUuid uuid;
|
||||
subRoleUuid uuid;
|
||||
userUuid uuid;
|
||||
BEGIN
|
||||
RAISE NOTICE 'creating role: %', roleName;
|
||||
roleUuid = createRole(roleName);
|
||||
|
||||
call grantPermissionsToRole(roleUuid, permissions.permissionUuids);
|
||||
|
||||
IF superRoles IS NOT NULL THEN
|
||||
FOREACH superRoleUuid IN ARRAY superRoles.roleuUids LOOP
|
||||
call grantRoleToRole(roleUuid, superRoleUuid);
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
IF subRoles IS NOT NULL THEN
|
||||
FOREACH subRoleUuid IN ARRAY subRoles.roleuUids LOOP
|
||||
call grantRoleToRole(subRoleUuid, roleUuid);
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
IF users IS NOT NULL THEN
|
||||
FOREACH userUuid IN ARRAY users.useruUids LOOP
|
||||
call grantRoleToUser(roleUuid, userUuid);
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
RETURN roleUuid;
|
||||
END; $$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION createRole(
|
||||
roleName varchar,
|
||||
permissions RbacPermissions,
|
||||
users RbacUsers = null
|
||||
)
|
||||
RETURNS uuid
|
||||
CALLED ON NULL INPUT
|
||||
LANGUAGE plpgsql AS $$
|
||||
BEGIN
|
||||
RETURN createRole(roleName, permissions, null, null, users);
|
||||
END; $$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION createRole(
|
||||
roleName varchar,
|
||||
permissions RbacPermissions,
|
||||
subRoles RbacSubRoles,
|
||||
users RbacUsers = null
|
||||
)
|
||||
RETURNS uuid
|
||||
CALLED ON NULL INPUT
|
||||
LANGUAGE plpgsql AS $$
|
||||
BEGIN
|
||||
RETURN createRole(roleName, permissions, null, subRoles, users);
|
||||
END; $$;
|
||||
|
||||
|
Reference in New Issue
Block a user