introduce referential integrity for role identification - part 1
This commit is contained in:
parent
6f6320565c
commit
1dde6b2609
@ -29,10 +29,21 @@ CREATE TABLE RbacUser
|
|||||||
name varchar(63) not null unique
|
name varchar(63) not null unique
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- DROP TABLE IF EXISTS RbacObject;
|
||||||
|
CREATE TABLE RbacObject
|
||||||
|
(
|
||||||
|
uuid uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
objectTable varchar(64) not null,
|
||||||
|
unique (objectTable, uuid)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TYPE RbacRoleType AS ENUM ('owner', 'admin', 'tenant');
|
||||||
|
|
||||||
CREATE TABLE RbacRole
|
CREATE TABLE RbacRole
|
||||||
(
|
(
|
||||||
uuid uuid primary key references RbacReference (uuid) ON DELETE CASCADE,
|
uuid uuid primary key references RbacReference (uuid) ON DELETE CASCADE,
|
||||||
name varchar(63) not null unique
|
objectUuid uuid references RbacObject(uuid) not null,
|
||||||
|
roleType RbacRoleType not null
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE RbacGrants
|
CREATE TABLE RbacGrants
|
||||||
@ -56,14 +67,6 @@ CREATE DOMAIN RbacOp AS VARCHAR(67)
|
|||||||
OR VALUE ~ '^add-[a-z]+$'
|
OR VALUE ~ '^add-[a-z]+$'
|
||||||
);
|
);
|
||||||
|
|
||||||
-- DROP TABLE IF EXISTS RbacObject;
|
|
||||||
CREATE TABLE RbacObject
|
|
||||||
(
|
|
||||||
uuid uuid UNIQUE DEFAULT uuid_generate_v4(),
|
|
||||||
objectTable varchar(64) not null,
|
|
||||||
unique (objectTable, uuid)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION createRbacObject()
|
CREATE OR REPLACE FUNCTION createRbacObject()
|
||||||
RETURNS trigger
|
RETURNS trigger
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
@ -144,7 +147,51 @@ BEGIN
|
|||||||
END;
|
END;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION createRole(roleName varchar)
|
CREATE TYPE RbacRoleDescriptor AS
|
||||||
|
(
|
||||||
|
objectTable varchar(63), -- TODO: needed? remove?
|
||||||
|
objectUuid uuid,
|
||||||
|
roleType RbacRoleType
|
||||||
|
);
|
||||||
|
|
||||||
|
-- TODO: this ...
|
||||||
|
CREATE OR REPLACE FUNCTION roleDescriptor(objectTable varchar(63), objectUuid uuid, roleType RbacRoleType )
|
||||||
|
RETURNS RbacRoleDescriptor
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
STABLE LEAKPROOF
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
RETURN ROW(objectTable, objectUuid, roleType);
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
CREATE FUNCTION new_emp() RETURNS emp AS $$
|
||||||
|
SELECT text 'None' AS name,
|
||||||
|
1000.0 AS salary,
|
||||||
|
25 AS age,
|
||||||
|
point '(2,2)' AS cubicle;
|
||||||
|
$$ LANGUAGE SQL;
|
||||||
|
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
DECLARE
|
||||||
|
roleDesc RbacRoleDescriptor;
|
||||||
|
BEGIN
|
||||||
|
select * FROM roleDescriptor('global', gen_random_uuid(), 'admin') into roleDesc;
|
||||||
|
RAISE NOTICE 'result: % % %', roleDesc.objecttable, roleDesc.objectuuid, roleDesc.roletype;
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
-- TODO: ... or that?
|
||||||
|
CREATE OR REPLACE FUNCTION roleDescriptor(objectTable varchar(63), objectUuid uuid, roleType RbacRoleType )
|
||||||
|
RETURNS RbacRoleDescriptor
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
-- STABLE LEAKPROOF
|
||||||
|
LANGUAGE sql AS $$
|
||||||
|
SELECT objectTable, objectUuid, roleType::RbacRoleType;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION createRole(roleDescriptor RbacRoleDescriptor)
|
||||||
RETURNS uuid
|
RETURNS uuid
|
||||||
RETURNS NULL ON NULL INPUT
|
RETURNS NULL ON NULL INPUT
|
||||||
LANGUAGE plpgsql AS $$
|
LANGUAGE plpgsql AS $$
|
||||||
@ -152,10 +199,7 @@ declare
|
|||||||
referenceId uuid;
|
referenceId uuid;
|
||||||
BEGIN
|
BEGIN
|
||||||
INSERT INTO RbacReference (type) VALUES ('RbacRole') RETURNING uuid INTO referenceId;
|
INSERT INTO RbacReference (type) VALUES ('RbacRole') RETURNING uuid INTO referenceId;
|
||||||
INSERT INTO RbacRole (uuid, name) VALUES (referenceId, roleName);
|
INSERT INTO RbacRole (uuid, objectUuid, roleType) VALUES (referenceId, roleDescriptor.objectUuid, roleDescriptor.roleType);
|
||||||
IF (referenceId IS NULL) THEN
|
|
||||||
RAISE EXCEPTION 'referenceId for roleName "%" is unexpectedly null', roleName;
|
|
||||||
end if;
|
|
||||||
return referenceId;
|
return referenceId;
|
||||||
END;
|
END;
|
||||||
$$;
|
$$;
|
||||||
@ -168,27 +212,27 @@ BEGIN
|
|||||||
END;
|
END;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION findRoleId(roleName varchar)
|
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 RbacRole WHERE name = roleName
|
SELECT uuid FROM RbacRole WHERE objectUuid = roleDescriptor.objectUuid AND roleType = roleDescriptor.roleType;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION getRoleId(roleName varchar, whenNotExists RbacWhenNotExists)
|
CREATE OR REPLACE FUNCTION getRoleId(roleDescriptor RbacRoleDescriptor, whenNotExists RbacWhenNotExists)
|
||||||
RETURNS uuid
|
RETURNS uuid
|
||||||
RETURNS NULL ON NULL INPUT
|
RETURNS NULL ON NULL INPUT
|
||||||
LANGUAGE plpgsql AS $$
|
LANGUAGE plpgsql AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
roleUuid uuid;
|
roleUuid uuid;
|
||||||
BEGIN
|
BEGIN
|
||||||
roleUuid = findRoleId(roleName);
|
roleUuid = findRoleId(roleDescriptor);
|
||||||
IF ( roleUuid IS NULL ) THEN
|
IF ( roleUuid IS NULL ) THEN
|
||||||
IF ( whenNotExists = 'fail') THEN
|
IF ( whenNotExists = 'fail') THEN
|
||||||
RAISE EXCEPTION 'RbacRole with name="%" not found', roleName;
|
RAISE EXCEPTION 'RbacRole "%#%.%" not found', roleDescriptor.objectTable, roleDescriptor.objectUuid, roleDescriptor.roleType;
|
||||||
END IF;
|
END IF;
|
||||||
IF ( whenNotExists = 'create') THEN
|
IF ( whenNotExists = 'create') THEN
|
||||||
roleUuid = createRole(roleName);
|
roleUuid = createRole(roleDescriptor);
|
||||||
END IF;
|
END IF;
|
||||||
END IF;
|
END IF;
|
||||||
return roleUuid;
|
return roleUuid;
|
||||||
@ -204,6 +248,7 @@ DECLARE
|
|||||||
refId uuid;
|
refId uuid;
|
||||||
permissionIds uuid[] = ARRAY[]::uuid[];
|
permissionIds uuid[] = ARRAY[]::uuid[];
|
||||||
BEGIN
|
BEGIN
|
||||||
|
RAISE NOTICE 'createPermission for: % %', forObjectUuid, permitOps;
|
||||||
IF ( forObjectUuid IS NULL ) THEN
|
IF ( forObjectUuid IS NULL ) THEN
|
||||||
RAISE EXCEPTION 'forObjectUuid must not be null';
|
RAISE EXCEPTION 'forObjectUuid must not be null';
|
||||||
END IF;
|
END IF;
|
||||||
@ -214,16 +259,20 @@ BEGIN
|
|||||||
FOR i IN array_lower(permitOps, 1)..array_upper(permitOps, 1) LOOP
|
FOR i IN array_lower(permitOps, 1)..array_upper(permitOps, 1) LOOP
|
||||||
refId = (SELECT uuid FROM RbacPermission WHERE objectUuid=forObjectUuid AND op=permitOps[i]);
|
refId = (SELECT uuid FROM RbacPermission WHERE objectUuid=forObjectUuid AND op=permitOps[i]);
|
||||||
IF (refId IS NULL) THEN
|
IF (refId IS NULL) THEN
|
||||||
|
RAISE NOTICE 'createPermission: % %', forObjectUuid, permitOps[i];
|
||||||
INSERT INTO RbacReference ("type") VALUES ('RbacPermission') RETURNING uuid INTO refId;
|
INSERT INTO RbacReference ("type") VALUES ('RbacPermission') RETURNING uuid INTO refId;
|
||||||
INSERT INTO RbacPermission (uuid, objectUuid, op) VALUES (refId, forObjectUuid, permitOps[i]);
|
INSERT INTO RbacPermission (uuid, objectUuid, op) VALUES (refId, forObjectUuid, permitOps[i]);
|
||||||
END IF;
|
END IF;
|
||||||
|
RAISE NOTICE 'addPermission: %', refId;
|
||||||
permissionIds = permissionIds || refId;
|
permissionIds = permissionIds || refId;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
|
|
||||||
|
RAISE NOTICE 'createPermissions returning: %', permissionIds;
|
||||||
return permissionIds;
|
return permissionIds;
|
||||||
END;
|
END;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION findPermissionId(forObjectTable varchar, forObjectUuid uuid, forOp RbacOp)
|
CREATE OR REPLACE FUNCTION findPermissionId(forObjectUuid uuid, forOp RbacOp)
|
||||||
RETURNS uuid
|
RETURNS uuid
|
||||||
RETURNS NULL ON NULL INPUT
|
RETURNS NULL ON NULL INPUT
|
||||||
STABLE LEAKPROOF
|
STABLE LEAKPROOF
|
||||||
@ -248,6 +297,7 @@ END; $$;
|
|||||||
CREATE OR REPLACE PROCEDURE grantPermissionsToRole(roleUuid uuid, permissionIds uuid[])
|
CREATE OR REPLACE PROCEDURE grantPermissionsToRole(roleUuid uuid, permissionIds uuid[])
|
||||||
LANGUAGE plpgsql AS $$
|
LANGUAGE plpgsql AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
|
RAISE NOTICE 'grantPermissionsToRole: % -> %', roleUuid, permissionIds;
|
||||||
FOR i IN array_lower(permissionIds, 1)..array_upper(permissionIds, 1) LOOP
|
FOR i IN array_lower(permissionIds, 1)..array_upper(permissionIds, 1) LOOP
|
||||||
perform assertReferenceType('roleId (ascendant)', roleUuid, 'RbacRole');
|
perform assertReferenceType('roleId (ascendant)', roleUuid, 'RbacRole');
|
||||||
perform assertReferenceType('permissionId (descendant)', permissionIds[i], 'RbacPermission');
|
perform assertReferenceType('permissionId (descendant)', permissionIds[i], 'RbacPermission');
|
||||||
@ -295,21 +345,6 @@ BEGIN
|
|||||||
ON CONFLICT DO NOTHING ; -- TODO: remove?
|
ON CONFLICT DO NOTHING ; -- TODO: remove?
|
||||||
END; $$;
|
END; $$;
|
||||||
|
|
||||||
abort;
|
|
||||||
set local session authorization default;
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION nextLevel(level integer, maxDepth integer)
|
|
||||||
RETURNS INTEGER
|
|
||||||
LANGUAGE plpgsql AS $$
|
|
||||||
BEGIN
|
|
||||||
IF (level > maxDepth) THEN
|
|
||||||
RAISE WARNING 'Role assignment depth exceeded %/%.', level, maxDepth;
|
|
||||||
END IF;
|
|
||||||
RETURN level+1;
|
|
||||||
END;
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
abort;
|
abort;
|
||||||
set local session authorization default;
|
set local session authorization default;
|
||||||
|
|
||||||
@ -444,7 +479,7 @@ begin transaction;
|
|||||||
end transaction;
|
end transaction;
|
||||||
|
|
||||||
---
|
---
|
||||||
|
/*
|
||||||
CREATE OR REPLACE FUNCTION queryAllPermissionsOfSubjectId(subjectId uuid) -- TODO: remove?
|
CREATE OR REPLACE FUNCTION queryAllPermissionsOfSubjectId(subjectId uuid) -- TODO: remove?
|
||||||
RETURNS SETOF RbacPermission
|
RETURNS SETOF RbacPermission
|
||||||
RETURNS NULL ON NULL INPUT
|
RETURNS NULL ON NULL INPUT
|
||||||
@ -469,7 +504,7 @@ CREATE OR REPLACE FUNCTION queryAllPermissionsOfSubjectId(subjectId uuid) -- TOD
|
|||||||
FROM
|
FROM
|
||||||
grants
|
grants
|
||||||
);
|
);
|
||||||
$$;
|
$$;*/
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -643,43 +678,39 @@ CREATE OR REPLACE FUNCTION currentSubjectIds()
|
|||||||
STABLE LEAKPROOF
|
STABLE LEAKPROOF
|
||||||
LANGUAGE plpgsql AS $$
|
LANGUAGE plpgsql AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
assumedRoles VARCHAR(63)[];
|
currentUserId uuid;
|
||||||
currentUserId uuid;
|
roleNames VARCHAR(63)[];
|
||||||
assumedRoleIds uuid[];
|
roleName VARCHAR(63);
|
||||||
assumedRoleId uuid;
|
objectTableToAssume VARCHAR(63);
|
||||||
|
objectNameToAssume VARCHAR(63);
|
||||||
|
objectUuidToAssume uuid;
|
||||||
|
roleTypeToAssume RbacRoleType;
|
||||||
|
roleIdsToAssume uuid[];
|
||||||
|
roleUuidToAssume uuid;
|
||||||
BEGIN
|
BEGIN
|
||||||
currentUserId := currentUserId();
|
currentUserId := currentUserId();
|
||||||
assumedRoles := assumedRoles();
|
roleNames := assumedRoles();
|
||||||
IF ( CARDINALITY(assumedRoles) = 0 ) THEN
|
IF ( CARDINALITY(roleNames) = 0 ) THEN
|
||||||
RETURN ARRAY[currentUserId];
|
RETURN ARRAY[currentUserId];
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
RAISE NOTICE 'assuming roles: %', assumedRoles;
|
RAISE NOTICE 'assuming roles: %', roleNames;
|
||||||
|
|
||||||
SELECT ARRAY_AGG(uuid) FROM RbacRole WHERE name = ANY(assumedRoles) INTO assumedRoleIds;
|
FOREACH roleName IN ARRAY roleNames LOOP
|
||||||
IF assumedRoleIds IS NOT NULL THEN
|
roleName = overlay(roleName placing '#' from length(roleName) + 1 - strpos(reverse(roleName), '.'));
|
||||||
FOREACH assumedRoleId IN ARRAY assumedRoleIds LOOP
|
objectTableToAssume = split_part(roleName, '#', 1);
|
||||||
IF ( NOT isGranted(currentUserId, assumedRoleId) ) THEN
|
objectNameToAssume = split_part(roleName, '#', 2);
|
||||||
RAISE EXCEPTION 'user % has no permission to assume role %', currentUser(), assumedRoleId;
|
roleTypeToAssume = split_part(roleName, '#', 3);
|
||||||
END IF;
|
|
||||||
END LOOP;
|
|
||||||
END IF;
|
|
||||||
RETURN assumedRoleIds;
|
|
||||||
END; $$;
|
|
||||||
|
|
||||||
rollback;
|
-- TODO: either the result needs to be cached at least per transaction or we need to get rid of SELCT in a loop
|
||||||
set session authorization default;
|
SELECT uuid AS roleuuidToAssume
|
||||||
CREATE OR REPLACE FUNCTION maxGrantDepth()
|
FROM RbacRole r
|
||||||
RETURNS integer
|
WHERE r.objectUuid=objectUuidToAssume AND r.roleType=roleTypeToAssume INTO roleUuidToAssume;
|
||||||
STABLE LEAKPROOF
|
IF ( NOT isGranted(currentUserId, roleUuidToAssume) ) THEN
|
||||||
LANGUAGE plpgsql AS $$
|
RAISE EXCEPTION 'user % has no permission to assume role %', currentUser(), roleUuidToAssume;
|
||||||
DECLARE
|
END IF;
|
||||||
maxGrantDepth VARCHAR(63);
|
roleIdsToAssume := roleIdsToAssume || roleUuidToAssume;
|
||||||
BEGIN
|
END LOOP;
|
||||||
BEGIN
|
|
||||||
maxGrantDepth := current_setting('hsadminng.maxGrantDepth');
|
RETURN roleIdsToAssume;
|
||||||
EXCEPTION WHEN OTHERS THEN
|
|
||||||
maxGrantDepth := NULL;
|
|
||||||
END;
|
|
||||||
RETURN coalesce(maxGrantDepth, '8')::integer;
|
|
||||||
END; $$;
|
END; $$;
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
-- Role-Hierarcy helper functions
|
-- Role-Hierarcy helper functions
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
CREATE TYPE RbacRoleType AS ENUM ('owner', 'admin', 'tenant');
|
|
||||||
|
|
||||||
-- PERMISSIONS --------------------------------------------
|
-- PERMISSIONS --------------------------------------------
|
||||||
|
|
||||||
-- drop type RbacPermissions;
|
-- drop type RbacPermissions;
|
||||||
@ -29,27 +27,27 @@ CREATE TYPE RbacSuperRoles AS
|
|||||||
roleUuids uuid[]
|
roleUuids uuid[]
|
||||||
);
|
);
|
||||||
|
|
||||||
-- drop function beneathRoles(roleName varchar);
|
-- drop function beneathRoles(roleDescriptors RbacRoleDescriptor[])
|
||||||
CREATE OR REPLACE FUNCTION beneathRoles(roleNames varchar[])
|
CREATE OR REPLACE FUNCTION beneathRoles(roleDescriptors RbacRoleDescriptor[])
|
||||||
RETURNS RbacSuperRoles
|
RETURNS RbacSuperRoles
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
superRoleName varchar;
|
superRoleDescriptor RbacRoleDescriptor;
|
||||||
superRoleUuids uuid[] := ARRAY[]::uuid[];
|
superRoleUuids uuid[] := ARRAY[]::uuid[];
|
||||||
BEGIN
|
BEGIN
|
||||||
FOREACH superRoleName IN ARRAY roleNames LOOP
|
FOREACH superRoleDescriptor IN ARRAY roleDescriptors LOOP
|
||||||
superRoleUuids := superRoleUuids || getRoleId(superRoleName, 'fail');
|
superRoleUuids := superRoleUuids || getRoleId(superRoleDescriptor, 'fail');
|
||||||
END LOOP;
|
END LOOP;
|
||||||
|
|
||||||
RETURN ROW(superRoleUuids)::RbacSuperRoles;
|
RETURN ROW(superRoleUuids)::RbacSuperRoles;
|
||||||
END; $$;
|
END; $$;
|
||||||
|
|
||||||
-- drop function beneathRole(roleName varchar);
|
-- drop function beneathRole(roleDescriptor RbacRoleDescriptor)
|
||||||
CREATE OR REPLACE FUNCTION beneathRole(roleName varchar)
|
CREATE OR REPLACE FUNCTION beneathRole(roleDescriptor RbacRoleDescriptor)
|
||||||
RETURNS RbacSuperRoles
|
RETURNS RbacSuperRoles
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN beneathRoles(ARRAY[roleName]);
|
RETURN beneathRoles(ARRAY[roleDescriptor]);
|
||||||
END; $$;
|
END; $$;
|
||||||
|
|
||||||
-- drop function beneathRole(roleUuid uuid);
|
-- drop function beneathRole(roleUuid uuid);
|
||||||
@ -83,12 +81,12 @@ BEGIN
|
|||||||
RETURN ROW(ARRAY[roleUuid]::uuid[])::RbacSubRoles;
|
RETURN ROW(ARRAY[roleUuid]::uuid[])::RbacSubRoles;
|
||||||
END; $$;
|
END; $$;
|
||||||
|
|
||||||
-- drop FUNCTION beingItselfA(roleName varchar)
|
-- drop FUNCTION beingItselfA(roleDescriptor RbacRoleDescriptor)
|
||||||
CREATE OR REPLACE FUNCTION beingItselfA(roleName varchar)
|
CREATE OR REPLACE FUNCTION beingItselfA(roleDescriptor RbacRoleDescriptor)
|
||||||
RETURNS RbacSubRoles
|
RETURNS RbacSubRoles
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN beingItselfA(getRoleId(roleName, 'fail'));
|
RETURN beingItselfA(getRoleId(roleDescriptor, 'fail'));
|
||||||
END; $$;
|
END; $$;
|
||||||
|
|
||||||
-- USERS --------------------------------------------------
|
-- USERS --------------------------------------------------
|
||||||
@ -126,20 +124,11 @@ END; $$;
|
|||||||
|
|
||||||
-- ROLE NAME BUILDER --------------------------------------
|
-- 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 ROLE MAIN FUNCTION ------------------------------
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION createRole(
|
CREATE OR REPLACE FUNCTION createRole(
|
||||||
roleName varchar,
|
roleDescriptor RbacRoleDescriptor,
|
||||||
permissions RbacPermissions,
|
permissions RbacPermissions,
|
||||||
superRoles RbacSuperRoles,
|
superRoles RbacSuperRoles,
|
||||||
subRoles RbacSubRoles = null,
|
subRoles RbacSubRoles = null,
|
||||||
@ -154,8 +143,9 @@ DECLARE
|
|||||||
subRoleUuid uuid;
|
subRoleUuid uuid;
|
||||||
userUuid uuid;
|
userUuid uuid;
|
||||||
BEGIN
|
BEGIN
|
||||||
RAISE NOTICE 'creating role: %', roleName;
|
RAISE NOTICE 'will createRole for %', roleDescriptor;
|
||||||
roleUuid = createRole(roleName);
|
RAISE NOTICE 'will createRole for % % %', roleDescriptor.objecttable, roleDescriptor.objectuuid, roleDescriptor.roletype;
|
||||||
|
roleUuid = createRole(roleDescriptor);
|
||||||
|
|
||||||
call grantPermissionsToRole(roleUuid, permissions.permissionUuids);
|
call grantPermissionsToRole(roleUuid, permissions.permissionUuids);
|
||||||
|
|
||||||
@ -181,7 +171,7 @@ BEGIN
|
|||||||
END; $$;
|
END; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION createRole(
|
CREATE OR REPLACE FUNCTION createRole(
|
||||||
roleName varchar,
|
roleDescriptor RbacRoleDescriptor,
|
||||||
permissions RbacPermissions,
|
permissions RbacPermissions,
|
||||||
users RbacUsers = null
|
users RbacUsers = null
|
||||||
)
|
)
|
||||||
@ -189,11 +179,11 @@ CREATE OR REPLACE FUNCTION createRole(
|
|||||||
CALLED ON NULL INPUT
|
CALLED ON NULL INPUT
|
||||||
LANGUAGE plpgsql AS $$
|
LANGUAGE plpgsql AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN createRole(roleName, permissions, null, null, users);
|
RETURN createRole(roleDescriptor, permissions, null, null, users);
|
||||||
END; $$;
|
END; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION createRole(
|
CREATE OR REPLACE FUNCTION createRole(
|
||||||
roleName varchar,
|
roleDescriptor RbacRoleDescriptor,
|
||||||
permissions RbacPermissions,
|
permissions RbacPermissions,
|
||||||
subRoles RbacSubRoles,
|
subRoles RbacSubRoles,
|
||||||
users RbacUsers = null
|
users RbacUsers = null
|
||||||
@ -202,7 +192,7 @@ CREATE OR REPLACE FUNCTION createRole(
|
|||||||
CALLED ON NULL INPUT
|
CALLED ON NULL INPUT
|
||||||
LANGUAGE plpgsql AS $$
|
LANGUAGE plpgsql AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN createRole(roleName, permissions, null, subRoles, users);
|
RETURN createRole(roleDescriptor, permissions, null, subRoles, users);
|
||||||
END; $$;
|
END; $$;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,10 +1,30 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE Hostsharing
|
||||||
|
(
|
||||||
|
uuid uuid PRIMARY KEY REFERENCES RbacObject(uuid)
|
||||||
|
);
|
||||||
|
CREATE UNIQUE INDEX Hostsharing_Singleton ON Hostsharing ((0));
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO RbacObject (objecttable) VALUES ('hostsharing');
|
||||||
|
INSERT INTO Hostsharing (uuid) VALUES ((SELECT uuid FROM RbacObject WHERE objectTable='hostsharing'));
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION hostsharingAdmin()
|
||||||
|
RETURNS RbacRoleDescriptor
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
STABLE LEAKPROOF
|
||||||
|
LANGUAGE sql AS $$
|
||||||
|
SELECT 'global', (SELECT uuid FROM RbacObject WHERE objectTable='hostsharing'), 'admin'::RbacRoleType;
|
||||||
|
$$;
|
||||||
|
|
||||||
-- create administrators role with two assigned users
|
-- create administrators role with two assigned users
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
admins uuid ;
|
admins uuid ;
|
||||||
begin
|
begin
|
||||||
admins = createRole('administrators');
|
admins = createRole(hostsharingAdmin());
|
||||||
call grantRoleToUser(admins, createRbacUser('mike@hostsharing.net'));
|
call grantRoleToUser(admins, createRbacUser('mike@hostsharing.net'));
|
||||||
call grantRoleToUser(admins, createRbacUser('sven@hostsharing.net'));
|
call grantRoleToUser(admins, createRbacUser('sven@hostsharing.net'));
|
||||||
commit;
|
commit;
|
||||||
|
@ -17,25 +17,25 @@ CREATE TRIGGER createRbacObjectForCustomer_Trigger
|
|||||||
BEFORE INSERT ON customer
|
BEFORE INSERT ON customer
|
||||||
FOR EACH ROW EXECUTE PROCEDURE createRbacObject();
|
FOR EACH ROW EXECUTE PROCEDURE createRbacObject();
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION customerOwner(customerName varchar)
|
CREATE OR REPLACE FUNCTION customerOwner(customer customer)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
begin
|
begin
|
||||||
return roleName('customer', customerName, 'owner');
|
return roleDescriptor('customer', customer.uuid, 'owner');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION customerAdmin(customerName varchar)
|
CREATE OR REPLACE FUNCTION customerAdmin(customer customer)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
begin
|
begin
|
||||||
return roleName('customer', customerName, 'admin');
|
return roleDescriptor('customer', customer.uuid, 'admin');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION customerTenant(customerName varchar)
|
CREATE OR REPLACE FUNCTION customerTenant(customer customer)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
begin
|
begin
|
||||||
return roleName('customer', customerName, 'tenant');
|
return roleDescriptor('customer', customer.uuid, 'tenant');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
|
|
||||||
@ -52,14 +52,14 @@ BEGIN
|
|||||||
|
|
||||||
-- the owner role with full access for Hostsharing administrators
|
-- the owner role with full access for Hostsharing administrators
|
||||||
customerOwnerUuid = createRole(
|
customerOwnerUuid = createRole(
|
||||||
customerOwner(NEW.prefix),
|
customerOwner(NEW),
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']),
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']),
|
||||||
beneathRole('administrators')
|
beneathRole(hostsharingAdmin())
|
||||||
);
|
);
|
||||||
|
|
||||||
-- the admin role for the customer's admins, who can view and add products
|
-- the admin role for the customer's admins, who can view and add products
|
||||||
customerAdminUuid = createRole(
|
customerAdminUuid = createRole(
|
||||||
customerAdmin(NEW.prefix),
|
customerAdmin(NEW),
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['view', 'add-package']),
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['view', 'add-package']),
|
||||||
-- NO auto follow for customer owner to avoid exploding permissions for administrators
|
-- NO auto follow for customer owner to avoid exploding permissions for administrators
|
||||||
withUser(NEW.adminUserName, 'create') -- implicitly ignored if null
|
withUser(NEW.adminUserName, 'create') -- implicitly ignored if null
|
||||||
@ -70,7 +70,7 @@ BEGIN
|
|||||||
|
|
||||||
-- the tenant role which later can be used by owners+admins of sub-objects
|
-- the tenant role which later can be used by owners+admins of sub-objects
|
||||||
perform createRole(
|
perform createRole(
|
||||||
customerTenant(NEW.prefix),
|
customerTenant(NEW),
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['view'])
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['view'])
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ DO LANGUAGE plpgsql $$
|
|||||||
BEGIN
|
BEGIN
|
||||||
SET hsadminng.currentUser TO '';
|
SET hsadminng.currentUser TO '';
|
||||||
|
|
||||||
FOR t IN 0..6999 LOOP
|
FOR t IN 0..9 LOOP
|
||||||
currentTask = 'creating RBAC test customer #' || t;
|
currentTask = 'creating RBAC test customer #' || t;
|
||||||
SET LOCAL hsadminng.currentUser TO 'mike@hostsharing.net';
|
SET LOCAL hsadminng.currentUser TO 'mike@hostsharing.net';
|
||||||
SET LOCAL hsadminng.assumedRoles = '';
|
SET LOCAL hsadminng.assumedRoles = '';
|
||||||
|
@ -11,25 +11,30 @@ CREATE TABLE IF NOT EXISTS package (
|
|||||||
customerUuid uuid REFERENCES customer(uuid)
|
customerUuid uuid REFERENCES customer(uuid)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION packageOwner(packageName varchar)
|
CREATE OR REPLACE FUNCTION packageOwner(pac package)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
declare
|
||||||
|
roleDesc RbacRoleDescriptor;
|
||||||
begin
|
begin
|
||||||
return roleName('package', packageName, 'owner');
|
return roleDescriptor('package', pac.uuid, 'admin');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION packageAdmin(packageName varchar)
|
CREATE OR REPLACE FUNCTION packageAdmin(pac package)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
begin
|
begin
|
||||||
return roleName('package', packageName, 'admin');
|
return roleDescriptor('package', pac.uuid, 'admin');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION packageTenant(packageName varchar)
|
CREATE OR REPLACE FUNCTION packageTenant(pac package)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
begin
|
begin
|
||||||
return roleName('package', packageName, 'tenant');
|
return roleDescriptor('package', pac.uuid, 'tenant');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
|
|
||||||
@ -54,24 +59,24 @@ BEGIN
|
|||||||
|
|
||||||
-- an owner role is created and assigned to the customer's admin role
|
-- an owner role is created and assigned to the customer's admin role
|
||||||
packageOwnerRoleUuid = createRole(
|
packageOwnerRoleUuid = createRole(
|
||||||
packageOwner(NEW.name),
|
packageOwner(NEW),
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']),
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']),
|
||||||
beneathRole(customerAdmin(parentCustomer.prefix))
|
beneathRole(customerAdmin(parentCustomer))
|
||||||
);
|
);
|
||||||
|
|
||||||
-- an owner role is created and assigned to the package owner role
|
-- an owner role is created and assigned to the package owner role
|
||||||
packageAdminRoleUuid = createRole(
|
packageAdminRoleUuid = createRole(
|
||||||
packageAdmin(NEW.name),
|
packageAdmin(NEW),
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['edit', 'add-unixuser']),
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['edit', 'add-unixuser', 'add-domain']),
|
||||||
beneathRole(packageOwnerRoleUuid)
|
beneathRole(packageOwnerRoleUuid)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- and a package tenant role is created and assigned to the package admin as well
|
-- and a package tenant role is created and assigned to the package admin as well
|
||||||
perform createRole(
|
perform createRole(
|
||||||
packageTenant(NEW.name),
|
packageTenant(NEW),
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY ['view']),
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY ['view']),
|
||||||
beneathRole(packageAdminRoleUuid),
|
beneathRole(packageAdminRoleUuid),
|
||||||
beingItselfA(customerTenant(parentCustomer.prefix))
|
beingItselfA(customerTenant(parentCustomer))
|
||||||
);
|
);
|
||||||
|
|
||||||
RETURN NEW;
|
RETURN NEW;
|
||||||
|
@ -12,25 +12,28 @@ CREATE TABLE IF NOT EXISTS UnixUser (
|
|||||||
packageUuid uuid REFERENCES package(uuid)
|
packageUuid uuid REFERENCES package(uuid)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION unixUserOwner(unixUserName varchar)
|
CREATE OR REPLACE FUNCTION unixUserOwner(uu UnixUser)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
begin
|
begin
|
||||||
return roleName('unixuser', unixUserName, 'owner');
|
return roleDescriptor('unixuser', uu.uuid, 'owner');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION unixUserAdmin(unixUserName varchar)
|
CREATE OR REPLACE FUNCTION unixUserAdmin(uu UnixUser)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
begin
|
begin
|
||||||
return roleName('unixuser', unixUserName, 'admin');
|
return roleDescriptor('unixuser', uu.uuid, 'admin');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION unixUserTenant(unixUserName varchar)
|
CREATE OR REPLACE FUNCTION unixUserTenant(uu UnixUser)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
begin
|
begin
|
||||||
return roleName('unixuser', unixUserName, 'tenant');
|
return roleDescriptor('unixuser', uu.uuid, 'tenant');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION createUnixUserTenantRoleIfNotExists(unixUser UnixUser)
|
CREATE OR REPLACE FUNCTION createUnixUserTenantRoleIfNotExists(unixUser UnixUser)
|
||||||
@ -38,19 +41,19 @@ CREATE OR REPLACE FUNCTION createUnixUserTenantRoleIfNotExists(unixUser UnixUser
|
|||||||
RETURNS NULL ON NULL INPUT
|
RETURNS NULL ON NULL INPUT
|
||||||
LANGUAGE plpgsql AS $$
|
LANGUAGE plpgsql AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
unixUserTenantRoleName varchar;
|
unixUserTenantRoleDesc RbacRoleDescriptor;
|
||||||
unixUserTenantRoleUuid uuid;
|
unixUserTenantRoleUuid uuid;
|
||||||
BEGIN
|
BEGIN
|
||||||
unixUserTenantRoleName = unixUserTenant(unixUser.name);
|
unixUserTenantRoleDesc = unixUserTenant(unixUser);
|
||||||
unixUserTenantRoleUuid = findRoleId(unixUserTenantRoleName);
|
unixUserTenantRoleUuid = findRoleId(unixUserTenantRoleDesc);
|
||||||
IF unixUserTenantRoleUuid IS NOT NULL THEN
|
IF unixUserTenantRoleUuid IS NOT NULL THEN
|
||||||
RETURN unixUserTenantRoleUuid;
|
RETURN unixUserTenantRoleUuid;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
RETURN createRole(
|
RETURN createRole(
|
||||||
unixUserTenantRoleName,
|
unixUserTenantRoleDesc,
|
||||||
grantingPermissions(forObjectUuid => unixUser.uuid, permitOps => ARRAY['edit', 'add-domain']),
|
grantingPermissions(forObjectUuid => unixUser.uuid, permitOps => ARRAY['view']),
|
||||||
beneathRole(unixUserAdmin(unixUser.name))
|
beneathRole(unixUserAdmin(unixUser))
|
||||||
);
|
);
|
||||||
END; $$;
|
END; $$;
|
||||||
|
|
||||||
@ -76,17 +79,17 @@ BEGIN
|
|||||||
|
|
||||||
-- an owner role is created and assigned to the package's admin group
|
-- an owner role is created and assigned to the package's admin group
|
||||||
unixuserOwnerRoleId = createRole(
|
unixuserOwnerRoleId = createRole(
|
||||||
unixUserOwner(NEW.name),
|
unixUserOwner(NEW),
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']),
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']),
|
||||||
beneathRole(packageAdmin(parentPackage.name))
|
beneathRole(packageAdmin(parentPackage))
|
||||||
);
|
);
|
||||||
|
|
||||||
-- and a unixuser admin role is created and assigned to the unixuser owner as well
|
-- and a unixuser admin role is created and assigned to the unixuser owner as well
|
||||||
unixuserAdminRoleId = createRole(
|
unixuserAdminRoleId = createRole(
|
||||||
unixUserAdmin(NEW.name),
|
unixUserAdmin(NEW),
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['edit', 'add-domain']),
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['edit']),
|
||||||
beneathRole(unixuserOwnerRoleId),
|
beneathRole(unixuserOwnerRoleId),
|
||||||
beingItselfA(packageTenant(parentPackage.name))
|
beingItselfA(packageTenant(parentPackage))
|
||||||
);
|
);
|
||||||
|
|
||||||
-- a tenent role is only created on demand
|
-- a tenent role is only created on demand
|
||||||
|
@ -16,25 +16,28 @@ CREATE TRIGGER createRbacObjectForDomain_Trigger
|
|||||||
BEFORE INSERT ON Domain
|
BEFORE INSERT ON Domain
|
||||||
FOR EACH ROW EXECUTE PROCEDURE createRbacObject();
|
FOR EACH ROW EXECUTE PROCEDURE createRbacObject();
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION domainOwner(unixUserName varchar, domainName varchar)
|
CREATE OR REPLACE FUNCTION domainOwner(dom Domain)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
begin
|
begin
|
||||||
return roleName('domain', unixUserName || '/' || domainName, 'owner');
|
return roleDescriptor('domain', dom.uuid, 'owner');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION domainAdmin(unixUserName varchar, domainName varchar)
|
CREATE OR REPLACE FUNCTION domainAdmin(dom Domain)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
begin
|
begin
|
||||||
return roleName('domain', unixUserName || '/' || domainName, 'admin');
|
return roleDescriptor('domain', dom.uuid, 'admin');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION domainTenant(unixUserName varchar, domainName varchar)
|
CREATE OR REPLACE FUNCTION domainTenant(dom Domain)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
begin
|
begin
|
||||||
return roleName('domain', unixUserName || '/' || domainName, 'tenant');
|
return roleDescriptor('domain', dom.uuid, 'tenant');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
|
|
||||||
@ -42,7 +45,8 @@ CREATE OR REPLACE FUNCTION createRbacRulesForDomain()
|
|||||||
RETURNS trigger
|
RETURNS trigger
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
parentUser unixuser;
|
parentUser UnixUser;
|
||||||
|
parentPackage package;
|
||||||
domainOwnerRoleUuid uuid;
|
domainOwnerRoleUuid uuid;
|
||||||
domainAdminRoleUuid uuid;
|
domainAdminRoleUuid uuid;
|
||||||
BEGIN
|
BEGIN
|
||||||
@ -50,25 +54,26 @@ BEGIN
|
|||||||
RAISE EXCEPTION 'invalid usage of TRIGGER AFTER INSERT';
|
RAISE EXCEPTION 'invalid usage of TRIGGER AFTER INSERT';
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
SELECT * FROM unixuser WHERE uuid=NEW.unixUserUuid into parentUser;
|
SELECT * FROM UnixUser WHERE uuid=NEW.unixUserUuid into parentUser;
|
||||||
|
SELECT * FROM Package WHERE uuid=parentUser.packageuuid into parentPackage;
|
||||||
|
|
||||||
-- a domain owner role is created and assigned to the unixuser's admin role
|
-- a domain owner role is created and assigned to the unixuser's admin role
|
||||||
domainOwnerRoleUuid = createRole(
|
domainOwnerRoleUuid = createRole(
|
||||||
domainOwner(parentUser.name, NEW.name),
|
domainOwner(NEW),
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']),
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']),
|
||||||
beneathRole(unixUserAdmin(parentUser.name))
|
beneathRole(packageAdmin(parentPackage))
|
||||||
);
|
);
|
||||||
|
|
||||||
-- a domain admin role is created and assigned to the domain's owner role
|
-- a domain admin role is created and assigned to the domain's owner role
|
||||||
domainAdminRoleUuid = createRole(
|
domainAdminRoleUuid = createRole(
|
||||||
domainAdmin(parentUser.name, NEW.name),
|
domainAdmin(NEW),
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['edit', 'add-emailaddress']),
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['edit', 'add-emailaddress']),
|
||||||
beneathRole(domainOwnerRoleUuid)
|
beneathRole(domainOwnerRoleUuid)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- and a domain tenant role is created and assigned to the domain's admiin role
|
-- and a domain tenant role is created and assigned to the domain's admiin role
|
||||||
perform createRole(
|
perform createRole(
|
||||||
domainTenant(parentUser.name, NEW.name),
|
domainTenant(NEW),
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']),
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']),
|
||||||
beneathRole(domainAdminRoleUuid),
|
beneathRole(domainAdminRoleUuid),
|
||||||
beingItselfA(createUnixUserTenantRoleIfNotExists(parentUser))
|
beingItselfA(createUnixUserTenantRoleIfNotExists(parentUser))
|
||||||
|
@ -16,50 +16,51 @@ CREATE TRIGGER createRbacObjectForEMailAddress_Trigger
|
|||||||
BEFORE INSERT ON EMailAddress
|
BEFORE INSERT ON EMailAddress
|
||||||
FOR EACH ROW EXECUTE PROCEDURE createRbacObject();
|
FOR EACH ROW EXECUTE PROCEDURE createRbacObject();
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION emailAddressOwner(emailAddress varchar)
|
CREATE OR REPLACE FUNCTION emailAddressOwner(emAddr EMailAddress)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
begin
|
begin
|
||||||
return roleName('emailaddress', emailAddress, 'owner');
|
return roleDescriptor('emailaddress', emAddr.uuid, 'owner');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION emailAddressAdmin(emailAddress varchar)
|
CREATE OR REPLACE FUNCTION emailAddressAdmin(emAddr EMailAddress)
|
||||||
RETURNS varchar
|
RETURNS RbacRoleDescriptor
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
begin
|
begin
|
||||||
return roleName('emailaddress', emailAddress, 'admin');
|
return roleDescriptor('emailaddress', emAddr.uuid, 'admin');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION createRbacRulesForEMailAddress()
|
CREATE OR REPLACE FUNCTION createRbacRulesForEMailAddress()
|
||||||
RETURNS trigger
|
RETURNS trigger
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
parentDomain record;
|
parentDomain Domain;
|
||||||
eMailAddress varchar;
|
|
||||||
eMailAddressOwnerRoleUuid uuid;
|
eMailAddressOwnerRoleUuid uuid;
|
||||||
BEGIN
|
BEGIN
|
||||||
IF TG_OP <> 'INSERT' THEN
|
IF TG_OP <> 'INSERT' THEN
|
||||||
RAISE EXCEPTION 'invalid usage of TRIGGER AFTER INSERT';
|
RAISE EXCEPTION 'invalid usage of TRIGGER AFTER INSERT';
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
SELECT d.name as name, u.name as unixUserName FROM domain d
|
SELECT d.*
|
||||||
LEFT JOIN unixuser u ON u.uuid = d.unixuseruuid
|
FROM domain d
|
||||||
WHERE d.uuid=NEW.domainUuid into parentDomain;
|
LEFT JOIN unixuser u ON u.uuid = d.unixuseruuid
|
||||||
eMailAddress = NEW.localPart || '@' || parentDomain.name;
|
WHERE d.uuid=NEW.domainUuid INTO parentDomain;
|
||||||
|
|
||||||
-- an owner role is created and assigned to the domains's admin group
|
-- an owner role is created and assigned to the domains's admin group
|
||||||
eMailAddressOwnerRoleUuid = createRole(
|
eMailAddressOwnerRoleUuid = createRole(
|
||||||
emailAddressOwner(eMailAddress),
|
emailAddressOwner(NEW),
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']),
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']),
|
||||||
beneathRole(domainAdmin( parentDomain.unixUserName, parentDomain.name))
|
beneathRole(domainAdmin( parentDomain))
|
||||||
);
|
);
|
||||||
|
|
||||||
-- and an admin role is created and assigned to the unixuser owner as well
|
-- and an admin role is created and assigned to the unixuser owner as well
|
||||||
perform createRole(
|
perform createRole(
|
||||||
emailAddressAdmin(eMailAddress),
|
emailAddressAdmin(NEW),
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['edit']),
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['edit']),
|
||||||
beneathRole(eMailAddressOwnerRoleUuid),
|
beneathRole(eMailAddressOwnerRoleUuid),
|
||||||
beingItselfA(domainTenant(parentDomain.unixUserName, parentDomain.name))
|
beingItselfA(domainTenant(parentDomain))
|
||||||
);
|
);
|
||||||
|
|
||||||
RETURN NEW;
|
RETURN NEW;
|
||||||
|
Loading…
Reference in New Issue
Block a user