add unixuser prototype as preparation for testability of grants

This commit is contained in:
Michael Hoennig 2022-08-14 16:44:26 +02:00
parent bc05fb1eeb
commit 7869d07d30
11 changed files with 443 additions and 206 deletions

View File

@ -629,19 +629,21 @@ create or replace function queryAllRbacUsersWithPermissionsFor(objectId uuid)
language sql as $$
select *
from RbacUser
where uuid in (with recursive grants as (select descendantUuid,
ascendantUuid
from RbacGrants
where descendantUuid = objectId
union all
select "grant".descendantUuid,
"grant".ascendantUuid
from RbacGrants "grant"
inner join grants recur on recur.ascendantUuid = "grant".descendantUuid)
select ascendantUuid
from grants);
where uuid in (
-- @formatter:off
with recursive grants as (
select descendantUuid, ascendantUuid
from RbacGrants
where descendantUuid = objectId
union all
select "grant".descendantUuid, "grant".ascendantUuid
from RbacGrants "grant"
inner join grants recur on recur.ascendantUuid = "grant".descendantUuid
)
-- @formatter:on
select ascendantUuid
from grants);
$$;
--//

View File

@ -19,7 +19,7 @@ select *
where isGranted(currentSubjectIds(), r.uuid)
) as unordered
-- @formatter:on
order by objectIdName;
order by objectTable || '#' || objectIdName || '.' || roleType;
grant all privileges on rbacrole_rv to restricted;
--//
@ -49,7 +49,7 @@ select userName, objectTable||'#'||objectIdName||'.'||roletype as roleIdName,
where isGranted(currentSubjectIds(), r.uuid)
) as unordered
-- @formatter:on
order by objectIdName;
order by roleIdName;
grant all privileges on rbacrole_rv to restricted;
--//

View File

@ -9,6 +9,6 @@ create table if not exists package
uuid uuid unique references RbacObject (uuid),
customerUuid uuid references customer (uuid),
name varchar(5),
description varchar(80)
description varchar(96)
);
--//

View File

@ -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)
);
--//

View File

@ -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;
--//

View File

@ -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;
$$;
--//

View File

@ -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;
$$;

View File

@ -30,6 +30,12 @@ databaseChangeLog:
- include:
file: db/changelog/2022-07-29-070-hs-package-rbac.sql
- 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

View File

@ -12,7 +12,7 @@ import org.springframework.boot.test.web.server.LocalServerPort;
import javax.persistence.EntityManager;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.*;
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
@ -50,14 +50,15 @@ class RbacRoleControllerAcceptanceTest {
.then().assertThat()
.statusCode(200)
.contentType("application/json")
.body("[0].roleName", is("customer#aaa.owner"))
.body("[1].roleName", is("customer#aaa.admin"))
.body("[0].roleName", is("customer#aaa.admin"))
.body("[1].roleName", is("customer#aaa.owner"))
.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( "size()", is(37));
.body("", hasItem(hasEntry("roleName", "global#hostsharing.admin")))
.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
}
@ -69,17 +70,18 @@ class RbacRoleControllerAcceptanceTest {
RestAssured
.given()
.header("current-user", "mike@hostsharing.net")
.header("assumed-roles", "package#aaa00.admin")
.header("assumed-roles", "package#aab00.admin")
.port(port)
.when()
.get("http://localhost/api/rbac-roles")
.then().assertThat()
.statusCode(200)
.contentType("application/json")
.body("[0].roleName", is("customer#aaa.tenant"))
.body("[1].roleName", is("package#aaa00.admin"))
.body("[2].roleName", is("package#aaa00.tenant"))
.body("size()", is(3));
.body("[0].roleName", is("customer#aab.tenant"))
.body("[1].roleName", is("package#aab00.admin"))
.body("[2].roleName", is("package#aab00.tenant"))
.body("[3].roleName", is("unixuser#aab00-aaaa.admin"))
.body("size()", is(7)); // increases with new test data
// @formatter:on
}
@ -90,17 +92,18 @@ class RbacRoleControllerAcceptanceTest {
// @formatter:off
RestAssured
.given()
.header("current-user", "aaa00@aaa.example.com")
.header("current-user", "aac00@aac.example.com")
.port(port)
.when()
.get("http://localhost/api/rbac-roles")
.then().assertThat()
.statusCode(200)
.contentType("application/json")
.body("[0].roleName", is("customer#aaa.tenant"))
.body("[1].roleName", is("package#aaa00.admin"))
.body("[2].roleName", is("package#aaa00.tenant"))
.body("size()", is(3));;
.body("[0].roleName", is("customer#aac.tenant"))
.body("[1].roleName", is("package#aac00.admin"))
.body("[2].roleName", is("package#aac00.tenant"))
.body("[3].roleName", is("unixuser#aac00-aaaa.admin"))
.body("size()", is(7)); // increases with new test data
// @formatter:on
}

View File

@ -59,7 +59,7 @@ class RbacRoleRepositoryIntegrationTest {
final var result = rbacRoleRepository.findAll();
// then
exactlyTheseRbacRolesAreReturned(result, ALL_TEST_DATA_ROLES);
allTheseRbacRolesAreReturned(result, ALL_TEST_DATA_ROLES);
}
@Test
@ -72,7 +72,7 @@ class RbacRoleRepositoryIntegrationTest {
final var result = rbacRoleRepository.findAll();
then:
exactlyTheseRbacRolesAreReturned(result, ALL_TEST_DATA_ROLES);
allTheseRbacRolesAreReturned(result, ALL_TEST_DATA_ROLES);
}
@Test
@ -84,13 +84,33 @@ class RbacRoleRepositoryIntegrationTest {
final var result = rbacRoleRepository.findAll();
// then:
exactlyTheseRbacRolesAreReturned(
allTheseRbacRolesAreReturned(
result,
// @formatter:off
"customer#aaa.admin", "customer#aaa.tenant",
"package#aaa00.admin", "package#aaa00.owner", "package#aaa00.tenant",
"package#aaa01.admin", "package#aaa01.owner", "package#aaa01.tenant",
"package#aaa02.admin", "package#aaa02.owner", "package#aaa02.tenant"
"customer#aaa.admin",
"customer#aaa.tenant",
"package#aaa00.admin",
"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
);
}
@ -102,7 +122,15 @@ class RbacRoleRepositoryIntegrationTest {
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
@ -191,4 +219,16 @@ class RbacRoleRepositoryIntegrationTest {
.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);
}
}

View File

@ -237,7 +237,7 @@ class RbacUserRepositoryIntegrationTest {
final var result = rbacUserRepository.findPermissionsOfUser("mike@hostsharing.net");
// then
exactlyTheseRbacPermissionsAreReturned(result, ALL_USER_PERMISSIONS);
allTheseRbacPermissionsAreReturned(result, ALL_USER_PERMISSIONS);
}
@Test
@ -266,7 +266,7 @@ class RbacUserRepositoryIntegrationTest {
final var result = rbacUserRepository.findPermissionsOfUser("admin@aaa.example.com");
// then
exactlyTheseRbacPermissionsAreReturned(
allTheseRbacPermissionsAreReturned(
result,
// @formatter:off
"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-unixuser",
"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-unixuser",
"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-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
);
}
@ -313,14 +324,29 @@ class RbacUserRepositoryIntegrationTest {
final var result = rbacUserRepository.findPermissionsOfUser("aaa00@aaa.example.com");
// then
exactlyTheseRbacPermissionsAreReturned(
allTheseRbacPermissionsAreReturned(
result,
// @formatter:off
"customer#aaa.tenant -> customer#aaa: view",
// "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-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
);
}
@ -346,7 +372,7 @@ class RbacUserRepositoryIntegrationTest {
final var result = rbacUserRepository.findPermissionsOfUser("aaa00@aaa.example.com");
// then
exactlyTheseRbacPermissionsAreReturned(
allTheseRbacPermissionsAreReturned(
result,
// @formatter:off
"customer#aaa.tenant -> customer#aaa: view",
@ -356,6 +382,22 @@ class RbacUserRepositoryIntegrationTest {
"package#aaa00.tenant -> package#aaa00: view"
// @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);
}
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);
}
}