-- ======================================================== -- Domain example with RBAC -- -------------------------------------------------------- set session session authorization default; create table if not exists Domain ( uuid uuid unique references RbacObject (uuid), name character varying(32), domainUuid uuid references domain (uuid) ); drop trigger if exists createRbacObjectForDomain_Trigger on Domain; create trigger createRbacObjectForDomain_Trigger before insert on Domain for each row execute procedure createRbacObject(); create or replace function domainOwner(dom Domain) returns RbacRoleDescriptor returns null on null input language plpgsql as $$ begin return roleDescriptor('domain', dom.uuid, 'owner'); end; $$; create or replace function domainAdmin(dom Domain) returns RbacRoleDescriptor returns null on null input language plpgsql as $$ begin return roleDescriptor('domain', dom.uuid, 'admin'); end; $$; create or replace function domainTenant(dom Domain) returns RbacRoleDescriptor returns null on null input language plpgsql as $$ begin return roleDescriptor('domain', dom.uuid, 'tenant'); end; $$; create or replace function createRbacRulesForDomain() returns trigger language plpgsql strict as $$ declare parentUser domain; parentPackage package; domainOwnerRoleUuid uuid; domainAdminRoleUuid uuid; begin if TG_OP <> 'INSERT' then raise exception 'invalid usage of TRIGGER AFTER INSERT'; end if; select * from domain where uuid = NEW.domainUuid into parentUser; select * from Package where uuid = parentUser.packageuuid into parentPackage; -- a domain owner role is created and assigned to the domain's admin role domainOwnerRoleUuid = createRole( domainOwner(NEW), grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['*']), beneathRole(testPackageAdmin(parentPackage)) ); -- a domain admin role is created and assigned to the domain's owner role domainAdminRoleUuid = createRole( domainAdmin(NEW), grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['edit', 'add-emailaddress']), beneathRole(domainOwnerRoleUuid) ); -- and a domain tenant role is created and assigned to the domain's admiin role perform createRole( domainTenant(NEW), grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['*']), beneathRole(domainAdminRoleUuid), beingItselfA(createdomainTenantRoleIfNotExists(parentUser)) ); return NEW; end; $$; drop trigger if exists createRbacRulesForDomain_Trigger on Domain; create trigger createRbacRulesForDomain_Trigger after insert on Domain for each row execute procedure createRbacRulesForDomain(); -- TODO: CREATE OR REPLACE FUNCTION deleteRbacRulesForDomain() -- create RBAC-restricted view set session session authorization default; -- ALTER TABLE Domain ENABLE ROW LEVEL SECURITY; drop view if exists domain_rv; create or replace view domain_rv as select target.* from Domain as target where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'domain', currentSubjectsUuids())); grant all privileges on domain_rv to restricted; -- generate Domain test data do language plpgsql $$ declare uu record; pac package; pacAdmin varchar; currentTask varchar; begin set hsadminng.currentUser to ''; for uu in (select u.uuid, u.name, u.packageuuid, c.reference from domain u join package p on u.packageuuid = p.uuid join customer c on p.customeruuid = c.uuid -- WHERE c.reference >= 18000 ) loop if (random() < 0.3) then for t in 0..1 loop currentTask = 'creating RBAC test Domain #' || t || ' for domain ' || uu.name || ' #' || uu.uuid; raise notice 'task: %', currentTask; select * from package where uuid = uu.packageUuid into pac; pacAdmin = 'admin@' || pac.name || '.example.com'; execute format('set local hsadminng.currentTask to %L', currentTask); execute format('set local hsadminng.currentUser to %L', pacAdmin); set local hsadminng.assumedRoles = ''; insert into Domain (name, domainUuid) values ('dom-' || t || '.' || uu.name || '.example.org', uu.uuid); commit; end loop; end if; end loop; end; $$;