hs.hsadmin.ng/src/main/resources/db/changelog/080-rbac-global.sql

159 lines
5.5 KiB
MySQL
Raw Normal View History

--liquibase formatted sql
-- ============================================================================
--changeset rbac-global-GLOBAL-OBJECT:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
The purpose of this table is provide root business objects
which can be referenced from global roles.
Without this table, these columns needed to be nullable and
many queries would be more complicated.
In production databases, there is only a single row in this table,
in test stages, there can be one row for each test data realm.
*/
create table Global
(
uuid uuid primary key references RbacObject (uuid) on delete cascade,
name varchar(63) unique
);
create unique index Global_Singleton on Global ((0));
grant select on global to restricted;
--//
-- ============================================================================
--changeset rbac-global-HAS-GLOBAL-PERMISSION:1 endDelimiter:--//
-- ------------------------------------------------------------------
create or replace function hasGlobalPermission(op RbacOp)
returns boolean
language sql as
$$
2022-09-07 12:25:12 +02:00
-- TODO.perf: this could to be optimized
select (select uuid from global) in
(select queryAccessibleObjectUuidsOfSubjectIds(op, 'global', currentSubjectsUuids()));
$$;
--//
-- ============================================================================
--changeset rbac-global-GLOBAL-IDENTITY-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Creates a view to the global object table which maps the identifying name to the objectUuid.
*/
drop view if exists global_iv;
create or replace view global_iv as
select target.uuid, target.name as idName
from global as target;
grant all privileges on global_iv to restricted;
/*
Returns the objectUuid for a given identifying name (in this case the idName).
*/
create or replace function globalUuidByIdName(idName varchar)
returns uuid
language sql
strict as $$
select uuid from global_iv iv where iv.idName = globalUuidByIdName.idName;
$$;
/*
Returns the identifying name for a given objectUuid (in this case the idName).
*/
create or replace function globalIdNameByUuid(uuid uuid)
returns varchar
language sql
strict as $$
select idName from global_iv iv where iv.uuid = globalIdNameByUuid.uuid;
$$;
--//
--liquibase formatted sql
-- ============================================================================
--changeset rbac-global-PSEUDO-OBJECT:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/**
A single row to be referenced as a global object.
*/
begin transaction;
call defineContext('initializing table "global"', null, null, null);
insert
into RbacObject (objecttable) values ('global');
insert
into Global (uuid, name) values ((select uuid from RbacObject where objectTable = 'global'), 'global');
commit;
--//
-- ============================================================================
--changeset rbac-global-ADMIN-ROLE:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
A global administrator role.
*/
create or replace function globalAdmin()
returns RbacRoleDescriptor
returns null on null input
stable leakproof
language sql as $$
select 'global', (select uuid from RbacObject where objectTable = 'global'), 'admin'::RbacRoleType;
$$;
begin transaction;
call defineContext('creating global admin role', null, null, null);
select createRole(globalAdmin());
commit;
-- ============================================================================
--changeset rbac-global-ADMIN-USERS:1 context:dev,tc endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Create two users and assign both to the administrators role.
*/
do language plpgsql $$
declare
admins uuid ;
begin
call defineContext('creating fake test-realm admin users', null, null, null);
admins = findRoleId(globalAdmin());
call grantRoleToUserUnchecked(admins, admins, createRbacUser('superuser-alex@hostsharing.net'));
call grantRoleToUserUnchecked(admins, admins, createRbacUser('superuser-fran@hostsharing.net'));
perform createRbacUser('selfregistered-user-drew@hostsharing.org');
perform createRbacUser('selfregistered-test-user@hostsharing.org');
end;
$$;
--//
-- ============================================================================
--changeset rbac-global-TEST:1 context:dev,tc runAlways:true endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Tests if currentUserUuid() can fetch the user from the session variable.
*/
do language plpgsql $$
declare
userName varchar;
begin
call defineContext('testing currentUserUuid', null, 'superuser-fran@hostsharing.net', null);
select userName from RbacUser where uuid = currentUserUuid() into userName;
if userName <> 'superuser-fran@hostsharing.net' then
raise exception 'setting or fetching initial currentUser failed, got: %', userName;
end if;
call defineContext('testing currentUserUuid', null, 'superuser-alex@hostsharing.net', null);
select userName from RbacUser where uuid = currentUserUuid() into userName;
if userName = 'superuser-alex@hostsharing.net' then
raise exception 'currentUser should not change in one transaction, but did change, got: %', userName;
end if;
end; $$;
--//