add unixuser prototype as preparation for testability of grants
This commit is contained in:
parent
bc05fb1eeb
commit
7869d07d30
@ -629,19 +629,21 @@ create or replace function queryAllRbacUsersWithPermissionsFor(objectId uuid)
|
|||||||
language sql as $$
|
language sql as $$
|
||||||
select *
|
select *
|
||||||
from RbacUser
|
from RbacUser
|
||||||
where uuid in (with recursive grants as (select descendantUuid,
|
where uuid in (
|
||||||
ascendantUuid
|
-- @formatter:off
|
||||||
from RbacGrants
|
with recursive grants as (
|
||||||
where descendantUuid = objectId
|
select descendantUuid, ascendantUuid
|
||||||
union all
|
from RbacGrants
|
||||||
select "grant".descendantUuid,
|
where descendantUuid = objectId
|
||||||
"grant".ascendantUuid
|
union all
|
||||||
from RbacGrants "grant"
|
select "grant".descendantUuid, "grant".ascendantUuid
|
||||||
inner join grants recur on recur.ascendantUuid = "grant".descendantUuid)
|
from RbacGrants "grant"
|
||||||
select ascendantUuid
|
inner join grants recur on recur.ascendantUuid = "grant".descendantUuid
|
||||||
from grants);
|
)
|
||||||
|
-- @formatter:on
|
||||||
|
select ascendantUuid
|
||||||
|
from grants);
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ select *
|
|||||||
where isGranted(currentSubjectIds(), r.uuid)
|
where isGranted(currentSubjectIds(), r.uuid)
|
||||||
) as unordered
|
) as unordered
|
||||||
-- @formatter:on
|
-- @formatter:on
|
||||||
order by objectIdName;
|
order by objectTable || '#' || objectIdName || '.' || roleType;
|
||||||
grant all privileges on rbacrole_rv to restricted;
|
grant all privileges on rbacrole_rv to restricted;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ select userName, objectTable||'#'||objectIdName||'.'||roletype as roleIdName,
|
|||||||
where isGranted(currentSubjectIds(), r.uuid)
|
where isGranted(currentSubjectIds(), r.uuid)
|
||||||
) as unordered
|
) as unordered
|
||||||
-- @formatter:on
|
-- @formatter:on
|
||||||
order by objectIdName;
|
order by roleIdName;
|
||||||
grant all privileges on rbacrole_rv to restricted;
|
grant all privileges on rbacrole_rv to restricted;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -9,6 +9,6 @@ create table if not exists package
|
|||||||
uuid uuid unique references RbacObject (uuid),
|
uuid uuid unique references RbacObject (uuid),
|
||||||
customerUuid uuid references customer (uuid),
|
customerUuid uuid references customer (uuid),
|
||||||
name varchar(5),
|
name varchar(5),
|
||||||
description varchar(80)
|
description varchar(96)
|
||||||
);
|
);
|
||||||
--//
|
--//
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
--liquibase formatted sql
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs-unixuser-MAIN-TABLE:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
create table if not exists UnixUser
|
||||||
|
(
|
||||||
|
uuid uuid unique references RbacObject (uuid),
|
||||||
|
packageUuid uuid references package (uuid),
|
||||||
|
name character varying(32),
|
||||||
|
description character varying(96)
|
||||||
|
);
|
||||||
|
--//
|
@ -0,0 +1,211 @@
|
|||||||
|
--liquibase formatted sql
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs-package-rbac-CREATE-OBJECT:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
Creates the related RbacObject through a BEFORE INSERT TRIGGER.
|
||||||
|
*/
|
||||||
|
drop trigger if exists createRbacObjectForUnixUser_Trigger on UnixUser;
|
||||||
|
create trigger createRbacObjectForUnixUser_Trigger
|
||||||
|
before insert
|
||||||
|
on UnixUser
|
||||||
|
for each row
|
||||||
|
execute procedure createRbacObject();
|
||||||
|
--//
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs-unixuser-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
create or replace function unixUserOwner(uu UnixUser)
|
||||||
|
returns RbacRoleDescriptor
|
||||||
|
returns null on null input
|
||||||
|
language plpgsql as $$
|
||||||
|
begin
|
||||||
|
return roleDescriptor('unixuser', uu.uuid, 'owner');
|
||||||
|
end; $$;
|
||||||
|
|
||||||
|
create or replace function unixUserAdmin(uu UnixUser)
|
||||||
|
returns RbacRoleDescriptor
|
||||||
|
returns null on null input
|
||||||
|
language plpgsql as $$
|
||||||
|
begin
|
||||||
|
return roleDescriptor('unixuser', uu.uuid, 'admin');
|
||||||
|
end; $$;
|
||||||
|
|
||||||
|
create or replace function unixUserTenant(uu UnixUser)
|
||||||
|
returns RbacRoleDescriptor
|
||||||
|
returns null on null input
|
||||||
|
language plpgsql as $$
|
||||||
|
begin
|
||||||
|
return roleDescriptor('unixuser', uu.uuid, 'tenant');
|
||||||
|
end; $$;
|
||||||
|
|
||||||
|
create or replace function createUnixUserTenantRoleIfNotExists(unixUser UnixUser)
|
||||||
|
returns uuid
|
||||||
|
returns null on null input
|
||||||
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
unixUserTenantRoleDesc RbacRoleDescriptor;
|
||||||
|
unixUserTenantRoleUuid uuid;
|
||||||
|
begin
|
||||||
|
unixUserTenantRoleDesc = unixUserTenant(unixUser);
|
||||||
|
unixUserTenantRoleUuid = findRoleId(unixUserTenantRoleDesc);
|
||||||
|
if unixUserTenantRoleUuid is not null then
|
||||||
|
return unixUserTenantRoleUuid;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return createRole(
|
||||||
|
unixUserTenantRoleDesc,
|
||||||
|
grantingPermissions(forObjectUuid => unixUser.uuid, permitOps => array ['view']),
|
||||||
|
beneathRole(unixUserAdmin(unixUser))
|
||||||
|
);
|
||||||
|
end; $$;
|
||||||
|
--//
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs-unixuser-rbac-ROLES-CREATION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
Creates the roles and their assignments for a new UnixUser for the AFTER INSERT TRIGGER.
|
||||||
|
*/
|
||||||
|
|
||||||
|
create or replace function createRbacRulesForUnixUser()
|
||||||
|
returns trigger
|
||||||
|
language plpgsql
|
||||||
|
strict as $$
|
||||||
|
declare
|
||||||
|
parentPackage package;
|
||||||
|
unixuserOwnerRoleId uuid;
|
||||||
|
unixuserAdminRoleId uuid;
|
||||||
|
begin
|
||||||
|
if TG_OP <> 'INSERT' then
|
||||||
|
raise exception 'invalid usage of TRIGGER AFTER INSERT';
|
||||||
|
end if;
|
||||||
|
|
||||||
|
select * from package where uuid = NEW.packageUuid into parentPackage;
|
||||||
|
|
||||||
|
-- an owner role is created and assigned to the package's admin group
|
||||||
|
unixuserOwnerRoleId = createRole(
|
||||||
|
unixUserOwner(NEW),
|
||||||
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['*']),
|
||||||
|
beneathRole(packageAdmin(parentPackage))
|
||||||
|
);
|
||||||
|
|
||||||
|
-- and a unixuser admin role is created and assigned to the unixuser owner as well
|
||||||
|
unixuserAdminRoleId = createRole(
|
||||||
|
unixUserAdmin(NEW),
|
||||||
|
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['edit']),
|
||||||
|
beneathRole(unixuserOwnerRoleId),
|
||||||
|
beingItselfA(packageTenant(parentPackage))
|
||||||
|
);
|
||||||
|
|
||||||
|
-- a tenent role is only created on demand
|
||||||
|
|
||||||
|
return NEW;
|
||||||
|
end; $$;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
An AFTER INSERT TRIGGER which creates the role structure for a new UnixUser.
|
||||||
|
*/
|
||||||
|
drop trigger if exists createRbacRulesForUnixUser_Trigger on UnixUser;
|
||||||
|
create trigger createRbacRulesForUnixUser_Trigger
|
||||||
|
after insert
|
||||||
|
on UnixUser
|
||||||
|
for each row
|
||||||
|
execute procedure createRbacRulesForUnixUser();
|
||||||
|
--//
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs-unixuser-rbac-ROLES-REMOVAL:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
Deletes the roles and their assignments of a deleted UnixUser for the BEFORE DELETE TRIGGER.
|
||||||
|
*/
|
||||||
|
|
||||||
|
create or replace function deleteRbacRulesForUnixUser()
|
||||||
|
returns trigger
|
||||||
|
language plpgsql
|
||||||
|
strict as $$
|
||||||
|
begin
|
||||||
|
if TG_OP = 'DELETE' then
|
||||||
|
call deleteRole(findRoleId(unixUserOwner(OLD)));
|
||||||
|
call deleteRole(findRoleId(unixUserAdmin(OLD)));
|
||||||
|
call deleteRole(findRoleId(unixUserTenant(OLD)));
|
||||||
|
else
|
||||||
|
raise exception 'invalid usage of TRIGGER BEFORE DELETE';
|
||||||
|
end if;
|
||||||
|
end; $$;
|
||||||
|
|
||||||
|
/*
|
||||||
|
An BEFORE DELETE TRIGGER which deletes the role structure of a UnixUser.
|
||||||
|
*/
|
||||||
|
|
||||||
|
drop trigger if exists deleteRbacRulesForUnixUser_Trigger on package;
|
||||||
|
create trigger deleteRbacRulesForUnixUser_Trigger
|
||||||
|
before delete
|
||||||
|
on UnixUser
|
||||||
|
for each row
|
||||||
|
execute procedure deleteRbacRulesForUnixUser();
|
||||||
|
--//
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs-unixuser-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
Creates a view to the UnixUser main table which maps the identifying name
|
||||||
|
(in this case, actually the column `name`) to the objectUuid.
|
||||||
|
*/
|
||||||
|
drop view if exists UnixUser_iv;
|
||||||
|
create or replace view UnixUser_iv as
|
||||||
|
select distinct target.uuid, target.name as idName
|
||||||
|
from UnixUser as target;
|
||||||
|
-- TODO: Is it ok that everybody has access to this information?
|
||||||
|
grant all privileges on UnixUser_iv to restricted;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns the objectUuid for a given identifying name (in this case, actually the column `name`).
|
||||||
|
*/
|
||||||
|
create or replace function unixUserUuidByIdName(idName varchar)
|
||||||
|
returns uuid
|
||||||
|
language sql
|
||||||
|
strict as $$
|
||||||
|
select uuid from UnixUser_iv iv where iv.idName = unixUserUuidByIdName.idName;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns the identifying name for a given objectUuid (in this case the name).
|
||||||
|
*/
|
||||||
|
create or replace function unixUserIdNameByUuid(uuid uuid)
|
||||||
|
returns varchar
|
||||||
|
stable leakproof
|
||||||
|
language sql
|
||||||
|
strict as $$
|
||||||
|
select idName from UnixUser_iv iv where iv.uuid = unixUserIdNameByUuid.uuid;
|
||||||
|
$$;
|
||||||
|
--//
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs-package-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
Creates a view to the customer main table which maps the identifying name
|
||||||
|
(in this case, the prefix) to the objectUuid.
|
||||||
|
*/
|
||||||
|
drop view if exists unixuser_rv;
|
||||||
|
create or replace view unixuser_rv as
|
||||||
|
select target.*
|
||||||
|
from unixuser as target
|
||||||
|
where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'unixuser', currentSubjectIds()));
|
||||||
|
grant all privileges on unixuser_rv to restricted;
|
||||||
|
--//
|
@ -0,0 +1,62 @@
|
|||||||
|
--liquibase formatted sql
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs-unixuser-TEST-DATA-GENERATOR:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
Creates test data for the package main table.
|
||||||
|
*/
|
||||||
|
create or replace procedure createUnixUserTestData(
|
||||||
|
minCustomerReference integer, -- skip customers with reference below this
|
||||||
|
unixUserPerPackage integer, -- create this many unix users for each package
|
||||||
|
doCommitAfterEach boolean -- only for mass data creation outside of Liquibase
|
||||||
|
)
|
||||||
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
pac record;
|
||||||
|
pacAdmin varchar;
|
||||||
|
currentTask varchar;
|
||||||
|
begin
|
||||||
|
set hsadminng.currentUser to '';
|
||||||
|
|
||||||
|
for pac in
|
||||||
|
(select p.uuid, p.name
|
||||||
|
from package p
|
||||||
|
join customer c on p.customeruuid = c.uuid
|
||||||
|
where c.reference >= minCustomerReference)
|
||||||
|
loop
|
||||||
|
|
||||||
|
for t in 0..(unixUserPerPackage-1)
|
||||||
|
loop
|
||||||
|
currentTask = 'creating RBAC test unixuser #' || t || ' for package ' || pac.name || ' #' || pac.uuid;
|
||||||
|
raise notice 'task: %', currentTask;
|
||||||
|
pacAdmin = 'admin@' || pac.name || '.example.com';
|
||||||
|
set local hsadminng.currentUser to 'mike@hostsharing.net'; -- TODO: use a package-admin
|
||||||
|
set local hsadminng.assumedRoles = '';
|
||||||
|
set local hsadminng.currentTask to currentTask;
|
||||||
|
|
||||||
|
insert
|
||||||
|
into unixuser (name, packageUuid)
|
||||||
|
values (pac.name || '-' || intToVarChar(t, 4), pac.uuid);
|
||||||
|
|
||||||
|
if doCommitAfterEach then
|
||||||
|
commit;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
end;
|
||||||
|
$$;
|
||||||
|
--//
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs-unixuser-TEST-DATA-GENERATION:1 –context=dev,tc endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
do language plpgsql $$
|
||||||
|
begin
|
||||||
|
call createUnixUserTestData(0, 2, false);
|
||||||
|
end;
|
||||||
|
$$;
|
||||||
|
--//
|
@ -1,159 +0,0 @@
|
|||||||
-- ========================================================
|
|
||||||
-- UnixUser example with RBAC
|
|
||||||
-- --------------------------------------------------------
|
|
||||||
|
|
||||||
set session session authorization default;
|
|
||||||
|
|
||||||
create table if not exists UnixUser
|
|
||||||
(
|
|
||||||
uuid uuid unique references RbacObject (uuid),
|
|
||||||
name character varying(32),
|
|
||||||
comment character varying(96),
|
|
||||||
packageUuid uuid references package (uuid)
|
|
||||||
);
|
|
||||||
|
|
||||||
create or replace function unixUserOwner(uu UnixUser)
|
|
||||||
returns RbacRoleDescriptor
|
|
||||||
returns null on null input
|
|
||||||
language plpgsql as $$
|
|
||||||
begin
|
|
||||||
return roleDescriptor('unixuser', uu.uuid, 'owner');
|
|
||||||
end; $$;
|
|
||||||
|
|
||||||
create or replace function unixUserAdmin(uu UnixUser)
|
|
||||||
returns RbacRoleDescriptor
|
|
||||||
returns null on null input
|
|
||||||
language plpgsql as $$
|
|
||||||
begin
|
|
||||||
return roleDescriptor('unixuser', uu.uuid, 'admin');
|
|
||||||
end; $$;
|
|
||||||
|
|
||||||
create or replace function unixUserTenant(uu UnixUser)
|
|
||||||
returns RbacRoleDescriptor
|
|
||||||
returns null on null input
|
|
||||||
language plpgsql as $$
|
|
||||||
begin
|
|
||||||
return roleDescriptor('unixuser', uu.uuid, 'tenant');
|
|
||||||
end; $$;
|
|
||||||
|
|
||||||
create or replace function createUnixUserTenantRoleIfNotExists(unixUser UnixUser)
|
|
||||||
returns uuid
|
|
||||||
returns null on null input
|
|
||||||
language plpgsql as $$
|
|
||||||
declare
|
|
||||||
unixUserTenantRoleDesc RbacRoleDescriptor;
|
|
||||||
unixUserTenantRoleUuid uuid;
|
|
||||||
begin
|
|
||||||
unixUserTenantRoleDesc = unixUserTenant(unixUser);
|
|
||||||
unixUserTenantRoleUuid = findRoleId(unixUserTenantRoleDesc);
|
|
||||||
if unixUserTenantRoleUuid is not null then
|
|
||||||
return unixUserTenantRoleUuid;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
return createRole(
|
|
||||||
unixUserTenantRoleDesc,
|
|
||||||
grantingPermissions(forObjectUuid => unixUser.uuid, permitOps => array ['view']),
|
|
||||||
beneathRole(unixUserAdmin(unixUser))
|
|
||||||
);
|
|
||||||
end; $$;
|
|
||||||
|
|
||||||
|
|
||||||
drop trigger if exists createRbacObjectForUnixUser_Trigger on UnixUser;
|
|
||||||
create trigger createRbacObjectForUnixUser_Trigger
|
|
||||||
before insert
|
|
||||||
on UnixUser
|
|
||||||
for each row
|
|
||||||
execute procedure createRbacObject();
|
|
||||||
|
|
||||||
create or replace function createRbacRulesForUnixUser()
|
|
||||||
returns trigger
|
|
||||||
language plpgsql
|
|
||||||
strict as $$
|
|
||||||
declare
|
|
||||||
parentPackage package;
|
|
||||||
unixuserOwnerRoleId uuid;
|
|
||||||
unixuserAdminRoleId uuid;
|
|
||||||
begin
|
|
||||||
if TG_OP <> 'INSERT' then
|
|
||||||
raise exception 'invalid usage of TRIGGER AFTER INSERT';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
select * from package where uuid = NEW.packageUuid into parentPackage;
|
|
||||||
|
|
||||||
-- an owner role is created and assigned to the package's admin group
|
|
||||||
unixuserOwnerRoleId = createRole(
|
|
||||||
unixUserOwner(NEW),
|
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['*']),
|
|
||||||
beneathRole(packageAdmin(parentPackage))
|
|
||||||
);
|
|
||||||
|
|
||||||
-- and a unixuser admin role is created and assigned to the unixuser owner as well
|
|
||||||
unixuserAdminRoleId = createRole(
|
|
||||||
unixUserAdmin(NEW),
|
|
||||||
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['edit']),
|
|
||||||
beneathRole(unixuserOwnerRoleId),
|
|
||||||
beingItselfA(packageTenant(parentPackage))
|
|
||||||
);
|
|
||||||
|
|
||||||
-- a tenent role is only created on demand
|
|
||||||
|
|
||||||
return NEW;
|
|
||||||
end; $$;
|
|
||||||
|
|
||||||
drop trigger if exists createRbacRulesForUnixUser_Trigger on UnixUser;
|
|
||||||
create trigger createRbacRulesForUnixUser_Trigger
|
|
||||||
after insert
|
|
||||||
on UnixUser
|
|
||||||
for each row
|
|
||||||
execute procedure createRbacRulesForUnixUser();
|
|
||||||
|
|
||||||
-- TODO: CREATE OR REPLACE FUNCTION deleteRbacRulesForUnixUser()
|
|
||||||
|
|
||||||
|
|
||||||
-- create RBAC-restricted view
|
|
||||||
set session session authorization default;
|
|
||||||
-- ALTER TABLE unixuser ENABLE ROW LEVEL SECURITY;
|
|
||||||
drop view if exists unixuser_rv;
|
|
||||||
create or replace view unixuser_rv as
|
|
||||||
select target.*
|
|
||||||
from unixuser as target
|
|
||||||
where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'unixuser', currentSubjectIds()));
|
|
||||||
grant all privileges on unixuser_rv to restricted;
|
|
||||||
|
|
||||||
|
|
||||||
-- generate UnixUser test data
|
|
||||||
|
|
||||||
do language plpgsql $$
|
|
||||||
declare
|
|
||||||
pac record;
|
|
||||||
pacAdmin varchar;
|
|
||||||
currentTask varchar;
|
|
||||||
begin
|
|
||||||
set hsadminng.currentUser to '';
|
|
||||||
|
|
||||||
for pac in (select p.uuid, p.name
|
|
||||||
from package p
|
|
||||||
join customer c on p.customeruuid = c.uuid
|
|
||||||
-- WHERE c.reference >= 18000
|
|
||||||
)
|
|
||||||
loop
|
|
||||||
|
|
||||||
for t in 0..9
|
|
||||||
loop
|
|
||||||
currentTask = 'creating RBAC test unixuser #' || t || ' for package ' || pac.name || ' #' || pac.uuid;
|
|
||||||
raise notice 'task: %', currentTask;
|
|
||||||
pacAdmin = 'admin@' || pac.name || '.example.com';
|
|
||||||
set local hsadminng.currentUser to 'mike@hostsharing.net'; -- TODO: use a package-admin
|
|
||||||
set local hsadminng.assumedRoles = '';
|
|
||||||
set local hsadminng.currentTask to currentTask;
|
|
||||||
|
|
||||||
insert
|
|
||||||
into unixuser (name, packageUuid)
|
|
||||||
values (pac.name || '-' || intToVarChar(t, 4), pac.uuid);
|
|
||||||
|
|
||||||
commit;
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
end;
|
|
||||||
$$;
|
|
@ -30,6 +30,12 @@ databaseChangeLog:
|
|||||||
- include:
|
- include:
|
||||||
file: db/changelog/2022-07-29-070-hs-package-rbac.sql
|
file: db/changelog/2022-07-29-070-hs-package-rbac.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/2022-07-29-070-hs-package-test-data.sql
|
file: db/changelog/2022-07-29-070-hs-package-test-data.sql
|
||||||
|
- include:
|
||||||
|
file: db/changelog/2022-08-14-080-hs-unixuser.sql
|
||||||
|
- include:
|
||||||
|
file: db/changelog/2022-08-14-081-hs-unixuser-rbac.sql
|
||||||
|
- include:
|
||||||
|
file: db/changelog/2022-08-14-082-hs-unixuser-test-data.sql
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import org.springframework.boot.test.web.server.LocalServerPort;
|
|||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
@ -50,14 +50,15 @@ class RbacRoleControllerAcceptanceTest {
|
|||||||
.then().assertThat()
|
.then().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("[0].roleName", is("customer#aaa.owner"))
|
.body("[0].roleName", is("customer#aaa.admin"))
|
||||||
.body("[1].roleName", is("customer#aaa.admin"))
|
.body("[1].roleName", is("customer#aaa.owner"))
|
||||||
.body("[2].roleName", is("customer#aaa.tenant"))
|
.body("[2].roleName", is("customer#aaa.tenant"))
|
||||||
.body("[3].roleName", is("package#aaa00.owner"))
|
|
||||||
.body("[4].roleName", is("package#aaa00.tenant"))
|
|
||||||
// ...
|
// ...
|
||||||
.body("[36].roleName", is("global#hostsharing.admin"))
|
.body("", hasItem(hasEntry("roleName", "global#hostsharing.admin")))
|
||||||
.body( "size()", is(37));
|
.body("", hasItem(hasEntry("roleName", "customer#aab.admin")))
|
||||||
|
.body("", hasItem(hasEntry("roleName", "package#aab00.admin")))
|
||||||
|
.body("", hasItem(hasEntry("roleName", "unixuser#aab00-aaaa.owner")))
|
||||||
|
.body( "size()", is(73)); // increases with new test data
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,17 +70,18 @@ class RbacRoleControllerAcceptanceTest {
|
|||||||
RestAssured
|
RestAssured
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "mike@hostsharing.net")
|
.header("current-user", "mike@hostsharing.net")
|
||||||
.header("assumed-roles", "package#aaa00.admin")
|
.header("assumed-roles", "package#aab00.admin")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/rbac-roles")
|
.get("http://localhost/api/rbac-roles")
|
||||||
.then().assertThat()
|
.then().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("[0].roleName", is("customer#aaa.tenant"))
|
.body("[0].roleName", is("customer#aab.tenant"))
|
||||||
.body("[1].roleName", is("package#aaa00.admin"))
|
.body("[1].roleName", is("package#aab00.admin"))
|
||||||
.body("[2].roleName", is("package#aaa00.tenant"))
|
.body("[2].roleName", is("package#aab00.tenant"))
|
||||||
.body("size()", is(3));
|
.body("[3].roleName", is("unixuser#aab00-aaaa.admin"))
|
||||||
|
.body("size()", is(7)); // increases with new test data
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,17 +92,18 @@ class RbacRoleControllerAcceptanceTest {
|
|||||||
// @formatter:off
|
// @formatter:off
|
||||||
RestAssured
|
RestAssured
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "aaa00@aaa.example.com")
|
.header("current-user", "aac00@aac.example.com")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/rbac-roles")
|
.get("http://localhost/api/rbac-roles")
|
||||||
.then().assertThat()
|
.then().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("[0].roleName", is("customer#aaa.tenant"))
|
.body("[0].roleName", is("customer#aac.tenant"))
|
||||||
.body("[1].roleName", is("package#aaa00.admin"))
|
.body("[1].roleName", is("package#aac00.admin"))
|
||||||
.body("[2].roleName", is("package#aaa00.tenant"))
|
.body("[2].roleName", is("package#aac00.tenant"))
|
||||||
.body("size()", is(3));;
|
.body("[3].roleName", is("unixuser#aac00-aaaa.admin"))
|
||||||
|
.body("size()", is(7)); // increases with new test data
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ class RbacRoleRepositoryIntegrationTest {
|
|||||||
final var result = rbacRoleRepository.findAll();
|
final var result = rbacRoleRepository.findAll();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseRbacRolesAreReturned(result, ALL_TEST_DATA_ROLES);
|
allTheseRbacRolesAreReturned(result, ALL_TEST_DATA_ROLES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -72,7 +72,7 @@ class RbacRoleRepositoryIntegrationTest {
|
|||||||
final var result = rbacRoleRepository.findAll();
|
final var result = rbacRoleRepository.findAll();
|
||||||
|
|
||||||
then:
|
then:
|
||||||
exactlyTheseRbacRolesAreReturned(result, ALL_TEST_DATA_ROLES);
|
allTheseRbacRolesAreReturned(result, ALL_TEST_DATA_ROLES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -84,13 +84,33 @@ class RbacRoleRepositoryIntegrationTest {
|
|||||||
final var result = rbacRoleRepository.findAll();
|
final var result = rbacRoleRepository.findAll();
|
||||||
|
|
||||||
// then:
|
// then:
|
||||||
exactlyTheseRbacRolesAreReturned(
|
allTheseRbacRolesAreReturned(
|
||||||
result,
|
result,
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
"customer#aaa.admin", "customer#aaa.tenant",
|
"customer#aaa.admin",
|
||||||
"package#aaa00.admin", "package#aaa00.owner", "package#aaa00.tenant",
|
"customer#aaa.tenant",
|
||||||
"package#aaa01.admin", "package#aaa01.owner", "package#aaa01.tenant",
|
"package#aaa00.admin",
|
||||||
"package#aaa02.admin", "package#aaa02.owner", "package#aaa02.tenant"
|
"package#aaa00.owner",
|
||||||
|
"package#aaa00.tenant",
|
||||||
|
"package#aaa01.admin",
|
||||||
|
"package#aaa01.owner",
|
||||||
|
"package#aaa01.tenant",
|
||||||
|
// ...
|
||||||
|
"unixuser#aaa00-aaaa.admin",
|
||||||
|
"unixuser#aaa00-aaaa.owner",
|
||||||
|
// ..
|
||||||
|
"unixuser#aaa01-aaaa.admin",
|
||||||
|
"unixuser#aaa01-aaaa.owner"
|
||||||
|
// @formatter:on
|
||||||
|
);
|
||||||
|
noneOfTheseRbacRolesIsReturned(
|
||||||
|
result,
|
||||||
|
// @formatter:off
|
||||||
|
"global#hostsharing.admin",
|
||||||
|
"customer#aaa.owner",
|
||||||
|
"package#aab00.admin",
|
||||||
|
"package#aab00.owner",
|
||||||
|
"package#aab00.tenant"
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -102,7 +122,15 @@ class RbacRoleRepositoryIntegrationTest {
|
|||||||
|
|
||||||
final var result = rbacRoleRepository.findAll();
|
final var result = rbacRoleRepository.findAll();
|
||||||
|
|
||||||
exactlyTheseRbacRolesAreReturned(result, "customer#aaa.tenant", "package#aaa00.tenant", "package#aaa00.admin");
|
exactlyTheseRbacRolesAreReturned(
|
||||||
|
result,
|
||||||
|
"customer#aaa.tenant",
|
||||||
|
"package#aaa00.admin",
|
||||||
|
"package#aaa00.tenant",
|
||||||
|
"unixuser#aaa00-aaaa.admin",
|
||||||
|
"unixuser#aaa00-aaaa.owner",
|
||||||
|
"unixuser#aaa00-aaab.admin",
|
||||||
|
"unixuser#aaa00-aaab.owner");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -191,4 +219,16 @@ class RbacRoleRepositoryIntegrationTest {
|
|||||||
.containsExactlyInAnyOrder(expectedRoleNames);
|
.containsExactlyInAnyOrder(expectedRoleNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void allTheseRbacRolesAreReturned(final List<RbacRoleEntity> actualResult, final String... expectedRoleNames) {
|
||||||
|
assertThat(actualResult)
|
||||||
|
.extracting(RbacRoleEntity::getRoleName)
|
||||||
|
.contains(expectedRoleNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
void noneOfTheseRbacRolesIsReturned(final List<RbacRoleEntity> actualResult, final String... unexpectedRoleNames) {
|
||||||
|
assertThat(actualResult)
|
||||||
|
.extracting(RbacRoleEntity::getRoleName)
|
||||||
|
.doesNotContain(unexpectedRoleNames);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ class RbacUserRepositoryIntegrationTest {
|
|||||||
final var result = rbacUserRepository.findPermissionsOfUser("mike@hostsharing.net");
|
final var result = rbacUserRepository.findPermissionsOfUser("mike@hostsharing.net");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseRbacPermissionsAreReturned(result, ALL_USER_PERMISSIONS);
|
allTheseRbacPermissionsAreReturned(result, ALL_USER_PERMISSIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -266,7 +266,7 @@ class RbacUserRepositoryIntegrationTest {
|
|||||||
final var result = rbacUserRepository.findPermissionsOfUser("admin@aaa.example.com");
|
final var result = rbacUserRepository.findPermissionsOfUser("admin@aaa.example.com");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseRbacPermissionsAreReturned(
|
allTheseRbacPermissionsAreReturned(
|
||||||
result,
|
result,
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
"customer#aaa.admin -> customer#aaa: add-package",
|
"customer#aaa.admin -> customer#aaa: add-package",
|
||||||
@ -276,14 +276,25 @@ class RbacUserRepositoryIntegrationTest {
|
|||||||
"package#aaa00.admin -> package#aaa00: add-domain",
|
"package#aaa00.admin -> package#aaa00: add-domain",
|
||||||
"package#aaa00.admin -> package#aaa00: add-unixuser",
|
"package#aaa00.admin -> package#aaa00: add-unixuser",
|
||||||
"package#aaa00.tenant -> package#aaa00: view",
|
"package#aaa00.tenant -> package#aaa00: view",
|
||||||
|
"unixuser#aaa00-aaaa.owner -> unixuser#aaa00-aaaa: *",
|
||||||
|
|
||||||
"package#aaa01.admin -> package#aaa01: add-domain",
|
"package#aaa01.admin -> package#aaa01: add-domain",
|
||||||
"package#aaa01.admin -> package#aaa01: add-unixuser",
|
"package#aaa01.admin -> package#aaa01: add-unixuser",
|
||||||
"package#aaa01.tenant -> package#aaa01: view",
|
"package#aaa01.tenant -> package#aaa01: view",
|
||||||
|
"unixuser#aaa01-aaaa.owner -> unixuser#aaa01-aaaa: *",
|
||||||
|
|
||||||
"package#aaa02.admin -> package#aaa02: add-domain",
|
"package#aaa02.admin -> package#aaa02: add-domain",
|
||||||
"package#aaa02.admin -> package#aaa02: add-unixuser",
|
"package#aaa02.admin -> package#aaa02: add-unixuser",
|
||||||
"package#aaa02.tenant -> package#aaa02: view"
|
"package#aaa02.tenant -> package#aaa02: view",
|
||||||
|
"unixuser#aaa02-aaaa.owner -> unixuser#aaa02-aaaa: *"
|
||||||
|
// @formatter:on
|
||||||
|
);
|
||||||
|
noneOfTheseRbacPermissionsAreReturned(
|
||||||
|
result,
|
||||||
|
// @formatter:off
|
||||||
|
"customer#aab.admin -> customer#aab: add-package",
|
||||||
|
"customer#aab.admin -> customer#aab: view",
|
||||||
|
"customer#aab.tenant -> customer#aab: view"
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -313,14 +324,29 @@ class RbacUserRepositoryIntegrationTest {
|
|||||||
final var result = rbacUserRepository.findPermissionsOfUser("aaa00@aaa.example.com");
|
final var result = rbacUserRepository.findPermissionsOfUser("aaa00@aaa.example.com");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseRbacPermissionsAreReturned(
|
allTheseRbacPermissionsAreReturned(
|
||||||
result,
|
result,
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
"customer#aaa.tenant -> customer#aaa: view",
|
"customer#aaa.tenant -> customer#aaa: view",
|
||||||
// "customer#aaa.admin -> customer#aaa: view" - Not permissions through the customer admin!
|
// "customer#aaa.admin -> customer#aaa: view" - Not permissions through the customer admin!
|
||||||
"package#aaa00.admin -> package#aaa00: add-unixuser",
|
"package#aaa00.admin -> package#aaa00: add-unixuser",
|
||||||
"package#aaa00.admin -> package#aaa00: add-domain",
|
"package#aaa00.admin -> package#aaa00: add-domain",
|
||||||
"package#aaa00.tenant -> package#aaa00: view"
|
"package#aaa00.tenant -> package#aaa00: view",
|
||||||
|
"unixuser#aaa00-aaaa.owner -> unixuser#aaa00-aaaa: *",
|
||||||
|
"unixuser#aaa00-aaab.owner -> unixuser#aaa00-aaab: *"
|
||||||
|
// @formatter:on
|
||||||
|
);
|
||||||
|
noneOfTheseRbacPermissionsAreReturned(
|
||||||
|
result,
|
||||||
|
// @formatter:off
|
||||||
|
"customer#aab.admin -> customer#aab: add-package",
|
||||||
|
"customer#aab.admin -> customer#aab: view",
|
||||||
|
"customer#aab.tenant -> customer#aab: view",
|
||||||
|
"package#aab00.admin -> package#aab00: add-unixuser",
|
||||||
|
"package#aab00.admin -> package#aab00: add-domain",
|
||||||
|
"package#aab00.tenant -> package#aab00: view",
|
||||||
|
"unixuser#aab00-aaaa.owner -> unixuser#aab00-aaaa: *",
|
||||||
|
"unixuser#aab00-aaab.owner -> unixuser#aab00-aaab: *"
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -346,7 +372,7 @@ class RbacUserRepositoryIntegrationTest {
|
|||||||
final var result = rbacUserRepository.findPermissionsOfUser("aaa00@aaa.example.com");
|
final var result = rbacUserRepository.findPermissionsOfUser("aaa00@aaa.example.com");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyTheseRbacPermissionsAreReturned(
|
allTheseRbacPermissionsAreReturned(
|
||||||
result,
|
result,
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
"customer#aaa.tenant -> customer#aaa: view",
|
"customer#aaa.tenant -> customer#aaa: view",
|
||||||
@ -356,6 +382,22 @@ class RbacUserRepositoryIntegrationTest {
|
|||||||
"package#aaa00.tenant -> package#aaa00: view"
|
"package#aaa00.tenant -> package#aaa00: view"
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
);
|
);
|
||||||
|
noneOfTheseRbacPermissionsAreReturned(
|
||||||
|
result,
|
||||||
|
// @formatter:off
|
||||||
|
// no customer admin permissions
|
||||||
|
"customer#aaa.admin -> customer#aaa: add-package",
|
||||||
|
// no permissions on other customer's objects
|
||||||
|
"customer#aab.admin -> customer#aab: add-package",
|
||||||
|
"customer#aab.admin -> customer#aab: view",
|
||||||
|
"customer#aab.tenant -> customer#aab: view",
|
||||||
|
"package#aab00.admin -> package#aab00: add-unixuser",
|
||||||
|
"package#aab00.admin -> package#aab00: add-domain",
|
||||||
|
"package#aab00.tenant -> package#aab00: view",
|
||||||
|
"unixuser#aab00-aaaa.owner -> unixuser#aab00-aaaa: *",
|
||||||
|
"unixuser#aab00-aaab.owner -> unixuser#aab00-aaab: *"
|
||||||
|
// @formatter:on
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,4 +433,20 @@ class RbacUserRepositoryIntegrationTest {
|
|||||||
.containsExactlyInAnyOrder(expectedRoleNames);
|
.containsExactlyInAnyOrder(expectedRoleNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void allTheseRbacPermissionsAreReturned(
|
||||||
|
final List<RbacUserPermission> actualResult,
|
||||||
|
final String... expectedRoleNames) {
|
||||||
|
assertThat(actualResult)
|
||||||
|
.extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp())
|
||||||
|
.contains(expectedRoleNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
void noneOfTheseRbacPermissionsAreReturned(
|
||||||
|
final List<RbacUserPermission> actualResult,
|
||||||
|
final String... unexpectedRoleNames) {
|
||||||
|
assertThat(actualResult)
|
||||||
|
.extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp())
|
||||||
|
.doesNotContain(unexpectedRoleNames);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user