WIP: introduce separate database schemas #102

Closed
hsh-michaelhoennig wants to merge 57 commits from introduce-separate-database-schemas into master
45 changed files with 576 additions and 502 deletions
Showing only changes of commit 79a81692db - Show all commits

View File

@ -82,7 +82,7 @@ If you have at least Docker and the Java JDK installed in appropriate versions a
# the following command should return a JSON array with just all packages visible for the admin of the customer yyy:
curl \
-H 'current-subject: superuser-alex@hostsharing.net' -H 'assumed-roles: test_customer#yyy:ADMIN' \
-H 'current-subject: superuser-alex@hostsharing.net' -H 'assumed-roles: test.customer#yyy:ADMIN' \
http://localhost:8080/api/test/packages
# add a new customer

View File

@ -3,28 +3,28 @@
-- --------------------------------------------------------
select rbac.isGranted(findRoleId('administrators'), findRoleId('test_package#aaa00:OWNER'));
select rbac.isGranted(findRoleId('test_package#aaa00:OWNER'), findRoleId('administrators'));
-- call rbac.grantRoleToRole(findRoleId('test_package#aaa00:OWNER'), findRoleId('administrators'));
-- call rbac.grantRoleToRole(findRoleId('administrators'), findRoleId('test_package#aaa00:OWNER'));
select rbac.isGranted(rbac.findRoleId('administrators'), rbac.findRoleId('test.package#aaa00:OWNER'));
select rbac.isGranted(rbac.findRoleId('test.package#aaa00:OWNER'), rbac.findRoleId('administrators'));
-- call rbac.grantRoleToRole(findRoleId('test.package#aaa00:OWNER'), findRoleId('administrators'));
-- call rbac.grantRoleToRole(findRoleId('administrators'), findRoleId('test.package#aaa00:OWNER'));
select count(*)
FROM queryAllPermissionsOfSubjectIdForObjectUuids(findRbacSubject('superuser-fran@hostsharing.net'),
ARRAY(select uuid from customer where reference < 1100000));
FROM rbac.queryAllPermissionsOfSubjectIdForObjectUuids(rbac.findRbacSubject('superuser-fran@hostsharing.net'),
ARRAY(select uuid from test.customer where reference < 1100000));
select count(*)
FROM queryAllPermissionsOfSubjectId(findRbacSubject('superuser-fran@hostsharing.net'));
FROM rbac.queryAllPermissionsOfSubjectId(findRbacSubject('superuser-fran@hostsharing.net'));
select *
FROM queryAllPermissionsOfSubjectId(findRbacSubject('alex@example.com'));
FROM rbac.queryAllPermissionsOfSubjectId(findRbacSubject('alex@example.com'));
select *
FROM queryAllPermissionsOfSubjectId(findRbacSubject('rosa@example.com'));
FROM rbac.queryAllPermissionsOfSubjectId(findRbacSubject('rosa@example.com'));
select *
FROM rbac.queryAllRbacSubjectsWithPermissionsFor(rbac.findEffectivePermissionId('customer',
(SELECT uuid FROM RbacObject WHERE objectTable = 'customer' LIMIT 1),
(SELECT uuid FROM rbac.RbacObject WHERE objectTable = 'customer' LIMIT 1),
'add-package'));
select *
FROM rbac.queryAllRbacSubjectsWithPermissionsFor(rbac.findEffectivePermissionId('package',
(SELECT uuid FROM RbacObject WHERE objectTable = 'package' LIMIT 1),
(SELECT uuid FROM rbac.RbacObject WHERE objectTable = 'package' LIMIT 1),
'DELETE'));
DO LANGUAGE plpgsql

View File

@ -20,7 +20,7 @@ CREATE POLICY customer_policy ON customer
TO restricted
USING (
-- id=1000
rbac.isPermissionGrantedToSubject(rbac.findEffectivePermissionId('test_customer', id, 'SELECT'), rbac.currentSubjectUuid())
rbac.isPermissionGrantedToSubject(rbac.findEffectivePermissionId('test.customer', id, 'SELECT'), rbac.currentSubjectUuid())
);
SET SESSION AUTHORIZATION restricted;
@ -31,28 +31,28 @@ SELECT * from customer;
SET SESSION SESSION AUTHORIZATION DEFAULT;
DROP VIEW cust_view;
CREATE VIEW cust_view AS
SELECT * FROM customer;
SELECT * FROM test.customer;
CREATE OR REPLACE RULE "_RETURN" AS
ON SELECT TO cust_view
DO INSTEAD
SELECT * FROM customer WHERE rbac.isPermissionGrantedToSubject(rbac.findEffectivePermissionId('test_customer', id, 'SELECT'), rbac.currentSubjectUuid());
SELECT * FROM test.customer WHERE rbac.isPermissionGrantedToSubject(rbac.findEffectivePermissionId('test.customer', id, 'SELECT'), rbac.currentSubjectUuid());
SELECT * from cust_view LIMIT 10;
select queryAllPermissionsOfSubjectId(findRbacSubject('superuser-alex@hostsharing.net'));
select rbac.queryAllPermissionsOfSubjectId(findRbacSubject('superuser-alex@hostsharing.net'));
-- access control via view-rule with join to recursive permissions - really fast (38ms for 1 million rows)
SET SESSION SESSION AUTHORIZATION DEFAULT;
ALTER TABLE customer ENABLE ROW LEVEL SECURITY;
ALTER TABLE test.customer ENABLE ROW LEVEL SECURITY;
DROP VIEW IF EXISTS cust_view;
CREATE OR REPLACE VIEW cust_view AS
SELECT *
FROM customer;
FROM test.customer;
CREATE OR REPLACE RULE "_RETURN" AS
ON SELECT TO cust_view
DO INSTEAD
SELECT c.uuid, c.reference, c.prefix FROM customer AS c
JOIN queryAllPermissionsOfSubjectId(rbac.currentSubjectUuid()) AS p
ON p.objectTable='test_customer' AND p.objectUuid=c.uuid;
SELECT c.uuid, c.reference, c.prefix FROM test.customer AS c
JOIN rbac.queryAllPermissionsOfSubjectId(rbac.currentSubjectUuid()) AS p
ON p.objectTable='test.customer' AND p.objectUuid=c.uuid;
GRANT ALL PRIVILEGES ON cust_view TO restricted;
SET SESSION SESSION AUTHORIZATION restricted;
@ -77,13 +77,13 @@ SET hsadminng.currentSubject TO 'superuser-alex@hostsharing.net';
-- SET hsadminng.currentSubject TO 'aaaaouq@example.com';
SELECT * from cust_view where reference=1144150;
select rr.uuid, rr.type from RbacGrants g
join RbacReference RR on g.ascendantUuid = RR.uuid
select rr.uuid, rr.type from rbac.RbacGrants g
join rbac.RbacReference RR on g.ascendantUuid = RR.uuid
where g.descendantUuid in (
select uuid from queryAllPermissionsOfSubjectId(findRbacSubject('alex@example.com'))
where objectTable='test_customer');
select uuid from rbac.queryAllPermissionsOfSubjectId(findRbacSubject('alex@example.com'))
where objectTable='test.customer');
call grantRoleToUser(findRoleId('test_customer#aaa:ADMIN'), findRbacSubject('aaaaouq@example.com'));
call rbac.grantRoleToUser(rbac.findRoleId('test.customer#aaa:ADMIN'), rbac.findRbacSubject('aaaaouq@example.com'));
select queryAllPermissionsOfSubjectId(findRbacSubject('aaaaouq@example.com'));
select rbac.queryAllPermissionsOfSubjectId(findRbacSubject('aaaaouq@example.com'));

View File

@ -114,7 +114,7 @@ public class InsertTriggerGenerator {
end; $$;
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
create trigger z_new_${rawSubTable}_grants_after_insert_tg
create trigger z_new_${rawSubTableName}_grants_after_insert_tg
after insert on ${rawSuperTableWithSchema}
for each row
execute procedure ${rawSuperTableSchemaName}new_${rawSubTableShortName}_grants_insert_to_${rawSuperTableShortName}_tf();
@ -132,6 +132,7 @@ public class InsertTriggerGenerator {
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
with("rawSuperTableSchemaName", g.getSuperRoleDef().getEntityAlias().getRawTableSchemaPrefix()),
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableNameWithSchema()),
with("rawSubTableName", g.getPermDef().getEntityAlias().getRawTableName()),
with("rawSubTableShortName", g.getPermDef().getEntityAlias().getRawTableShortName()));
});
@ -154,15 +155,16 @@ public class InsertTriggerGenerator {
returns trigger
language plpgsql as $$
begin
raise exception '[403] insert into ${rawSubTable} values(%) not allowed regardless of current subject, no insert permissions granted at all', NEW;
raise exception '[403] insert into ${rawSubTableWithSchema} values(%) not allowed regardless of current subject, no insert permissions granted at all', NEW;
end; $$;
create trigger ${rawSubTable}_insert_permission_check_tg
before insert on ${rawSubTable}
for each row
execute procedure ${rawSubTable}_insert_permission_missing_tf();
execute procedure ${rawSubTableWithSchema}_insert_permission_missing_tf();
""",
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
with("rawSubTableWithSchema", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()),
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
plPgSql.writeLn("--//");
}
@ -258,17 +260,18 @@ public class InsertTriggerGenerator {
private void generateInsertPermissionsChecksFooter(final StringWriter plPgSql) {
plPgSql.writeLn();
plPgSql.writeLn("""
raise exception '[403] insert into ${rawSubTable} values(%) not allowed for current subjects % (%)',
raise exception '[403] insert into ${rawSubTableWithSchema} values(%) not allowed for current subjects % (%)',
NEW, base.currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end; $$;
create trigger ${rawSubTable}_insert_permission_check_tg
before insert on ${rawSubTable}
before insert on ${rawSubTableWithSchema}
for each row
execute procedure ${rawSubTable}_insert_permission_check_tf();
execute procedure ${rawSubTableWithSchema}_insert_permission_check_tf();
--//
""",
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
with("rawSubTableWithSchema", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()),
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
}
private String toStringList(final Set<RbacView.CaseDef> cases) {

View File

@ -90,11 +90,11 @@ public class RbacView {
* @param <E>
* a JPA entity class extending RbacObject
*/
public static <E extends BaseEntity> RbacView rbacViewFor(final String alias, final Class<E> entityClass) {
public static <E extends BaseEntity<?>> RbacView rbacViewFor(final String alias, final Class<E> entityClass) {
return new RbacView(alias, entityClass);
}
RbacView(final String alias, final Class<? extends BaseEntity> entityClass) {
RbacView(final String alias, final Class<? extends BaseEntity<?>> entityClass) {
rootEntityAlias = new EntityAlias(alias, entityClass);
entityAliases.put(alias, rootEntityAlias);
new RbacSubjectReference(CREATOR);
@ -121,7 +121,7 @@ public class RbacView {
* <p>An identity view is a view which maps an objectUuid to an idName.
* The idName should be a human-readable representation of the row, but as short as possible.
* The idName must only consist of letters (A-Z, a-z), digits (0-9), dash (-), dot (.) and unserscore '_'.
* It's used to create the object-specific-role-names like test_customer#abc:ADMIN - here 'abc' is the idName.
* It's used to create the object-specific-role-names like test.customer#abc:ADMIN - here 'abc' is the idName.
* The idName not necessarily unique in a table, but it should be avoided.
* </p>
*
@ -287,9 +287,9 @@ public class RbacView {
* @param <EC>
* a JPA entity class extending RbacObject
*/
public <EC extends BaseEntity> RbacView importRootEntityAliasProxy(
public <EC extends BaseEntity<?>> RbacView importRootEntityAliasProxy(
final String aliasName,
final Class<? extends BaseEntity> entityClass,
final Class<? extends BaseEntity<?>> entityClass,
final ColumnValue forCase,
final SQL fetchSql,
final Column dependsOnColum) {
@ -313,7 +313,7 @@ public class RbacView {
* a JPA entity class extending RbacObject
*/
public RbacView importSubEntityAlias(
final String aliasName, final Class<? extends BaseEntity> entityClass,
final String aliasName, final Class<? extends BaseEntity<?>> entityClass,
final SQL fetchSql, final Column dependsOnColum) {
importEntityAliasImpl(aliasName, entityClass, usingDefaultCase(), fetchSql, dependsOnColum, true, NOT_NULL);
return this;
@ -350,14 +350,14 @@ public class RbacView {
* a JPA entity class extending RbacObject
*/
public RbacView importEntityAlias(
final String aliasName, final Class<? extends BaseEntity> entityClass, final ColumnValue usingCase,
final String aliasName, final Class<? extends BaseEntity<?>> entityClass, final ColumnValue usingCase,
final Column dependsOnColum, final SQL fetchSql, final Nullable nullable) {
importEntityAliasImpl(aliasName, entityClass, usingCase, fetchSql, dependsOnColum, false, nullable);
return this;
}
private EntityAlias importEntityAliasImpl(
final String aliasName, final Class<? extends BaseEntity> entityClass, final ColumnValue usingCase,
final String aliasName, final Class<? extends BaseEntity<?>> entityClass, final ColumnValue usingCase,
final SQL fetchSql, final Column dependsOnColum, boolean asSubEntity, final Nullable nullable) {
final var entityAlias = ofNullable(entityAliases.get(aliasName))
@ -911,13 +911,13 @@ public class RbacView {
return distinctGrantDef;
}
record EntityAlias(String aliasName, Class<? extends BaseEntity> entityClass, ColumnValue usingCase, SQL fetchSql, Column dependsOnColum, boolean isSubEntity, Nullable nullable) {
record EntityAlias(String aliasName, Class<? extends BaseEntity<?>> entityClass, ColumnValue usingCase, SQL fetchSql, Column dependsOnColum, boolean isSubEntity, Nullable nullable) {
public EntityAlias(final String aliasName) {
this(aliasName, null, null, null, null, false, null);
}
public EntityAlias(final String aliasName, final Class<? extends BaseEntity> entityClass) {
public EntityAlias(final String aliasName, final Class<? extends BaseEntity<?>> entityClass) {
this(aliasName, entityClass, null, null, null, false, null);
}
@ -964,7 +964,7 @@ public class RbacView {
if ( aliasName.equals("rbac.global")) {
return "rbac.global"; // TODO: maybe we should introduce a GlobalEntity class?
}
return withoutRvSuffix(entityClass.getAnnotation(Table.class).name());
return qualifiedRealTableName(entityClass);
}
String getRawTableSchemaPrefix() {
@ -1010,8 +1010,12 @@ public class RbacView {
}
}
public static String withoutRvSuffix(final String tableName) {
return tableName.substring(0, tableName.length() - "_rv".length());
public static String qualifiedRealTableName(final Class<? extends BaseEntity<?>> entityClass) {
final var tableAnnotation = entityClass.getAnnotation(Table.class);
final var schema = tableAnnotation.schema();
final var tableName = tableAnnotation.name();
final var realTableName = tableName.substring(0, tableName.length() - "_rv".length());
return (schema.isEmpty() ? "" : (schema + ".")) + realTableName;
}
public enum Role {

View File

@ -19,9 +19,11 @@ public class StringWriter {
writeLn();
}
void writeLn(final String text, final VarDef... varDefs) {
string.append( indented( new VarReplacer(varDefs).apply(text) ));
String writeLn(final String text, final VarDef... varDefs) {
final var insertText = indented(new VarReplacer(varDefs).apply(text));
string.append(insertText);
writeLn();
return insertText;
}
void writeLn() {

View File

@ -20,7 +20,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity
@Table(name = "test_customer_rv")
@Table(schema = "test", name = "customer_rv")
@Getter
@Setter
@NoArgsConstructor

View File

@ -22,7 +22,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetc
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity
@Table(name = "test_domain_rv")
@Table(schema = "test", name = "domain_rv")
@Getter
@Setter
@NoArgsConstructor

View File

@ -22,7 +22,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity
@Table(name = "test_package_rv")
@Table(schema = "test", name = "package_rv")
@Getter
@Setter
@NoArgsConstructor

View File

@ -4,5 +4,5 @@
-- ============================================================================
--changeset base-SCHEMA:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
CREATE SCHEMA base;
CREATE SCHEMA IF NOT EXISTS base;
--//

View File

@ -6,15 +6,34 @@
--changeset table-columns-function:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
create or replace function base.tableColumnNames( tableName text )
create or replace function base.tableColumnNames( ofTableName text )
returns text
stable
language 'plpgsql' as $$
declare columns text[];
declare
ofTableName text default 'test.customer';
tableName text;
tableSchema text;
columns text[];
columnNames text;
begin
tableSchema := CASE
WHEN position('.' in ofTableName) > 0 THEN split_part(ofTableName, '.', 1)
END;
assert tableSchema = 'test', 'schema <> test';
tableName := CASE
WHEN position('.' in ofTableName) > 0 THEN split_part(ofTableName, '.', 2)
ELSE ofTableName
END;
assert tableName = 'customer', 'name <> customer';
columns := (select array(select column_name::text
from information_schema.columns
where table_name = tableName));
from information_schema.columns
where table_name = tableName
and table_schema is not distinct from tableSchema));
assert cardinality(columns) > 0, 'cannot determine columns of table ' || ofTableName ||
'("' || tableSchema || '"."' || tableName || '")';
return array_to_string(columns, ', ');
end; $$
--//

View File

@ -0,0 +1,18 @@
--liquibase formatted sql
-- ============================================================================
--changeset base-COMBINE-TABLE-SCHEMA-AND-NAME:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
create or replace function base.combine_table_schema_and_name(tableSchema name, tableName name)
returns text
language plpgsql as $$
begin
if tableSchema is null or tableSchema = 'public' or tableSchema = '' then
return tableName::text;
else
return tableSchema::text || '.' || tableName::text;
end if;
end; $$;
--//

View File

@ -77,9 +77,11 @@ create or replace function base.tx_journal_trigger()
declare
curTask text;
curTxId xid8;
tableSchemaAndName text;
begin
curTask := base.currentTask();
curTxId := pg_current_xact_id();
tableSchemaAndName := base.combine_table_schema_and_name(tg_table_schema, tg_table_name);
insert
into base.tx_context (txId, txTimestamp, currentSubject, assumedRoles, currentTask, currentRequest)
@ -90,20 +92,20 @@ begin
case tg_op
when 'INSERT' then insert
into base.tx_journal
values (curTxId,
tg_table_name, new.uuid, tg_op::base.tx_operation,
values (curTxId, tableSchemaAndName,
new.uuid, tg_op::base.tx_operation,
to_jsonb(new));
when 'UPDATE' then insert
into base.tx_journal
values (curTxId,
tg_table_name, old.uuid, tg_op::base.tx_operation,
values (curTxId, tableSchemaAndName,
old.uuid, tg_op::base.tx_operation,
base.jsonb_changes_delta(to_jsonb(old), to_jsonb(new)));
when 'DELETE' then insert
into base.tx_journal
values (curTxId,
tg_table_name, old.uuid, 'DELETE'::base.tx_operation,
values (curTxId,tableSchemaAndName,
old.uuid, 'DELETE'::base.tx_operation,
null::jsonb);
else raise exception 'Trigger op % not supported for %.', tg_op, tg_table_name;
else raise exception 'Trigger op % not supported for %.', tg_op, tableSchemaAndName;
end case;
return null;
end; $$;

View File

@ -81,8 +81,8 @@ begin
"alive" := false;
end if;
sql := format('INSERT INTO %3$I_ex VALUES (DEFAULT, pg_current_xact_id(), %1$L, %2$L, $1.*)', TG_OP, alive, TG_TABLE_NAME);
raise notice 'sql: %', sql;
sql := format('INSERT INTO %3$I_ex VALUES (DEFAULT, pg_current_xact_id(), %1$L, %2$L, $1.*)',
TG_OP, alive, base.combine_table_schema_and_name(tg_table_schema, tg_table_name)::name);
execute sql using "row";
return "row";

View File

@ -4,5 +4,5 @@
-- ============================================================================
--changeset rbac-SCHEMA:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
CREATE SCHEMA rbac;
CREATE SCHEMA IF NOT EXISTS rbac;
--//

View File

@ -3,9 +3,7 @@
-- ============================================================================
--changeset rbac-base-REFERENCE:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
*/
create type rbac.ReferenceType as enum ('rbac.subject', 'rbac.role', 'rbac.permission');
create table rbac.reference
@ -120,18 +118,20 @@ create or replace function rbac.insert_related_object()
strict as $$
declare
objectUuid uuid;
tableSchemaAndName text;
begin
tableSchemaAndName := base.combine_table_schema_and_name(TG_TABLE_SCHEMA, TG_TABLE_NAME);
if TG_OP = 'INSERT' then
if NEW.uuid is null then
insert
into rbac.object (objectTable)
values (TG_TABLE_NAME)
values (tableSchemaAndName)
returning uuid into objectUuid;
NEW.uuid = objectUuid;
else
insert
into rbac.object (uuid, objectTable)
values (NEW.uuid, TG_TABLE_NAME)
values (NEW.uuid, tableSchemaAndName)
returning uuid into objectUuid;
end if;
return NEW;

View File

@ -8,26 +8,40 @@
create or replace procedure rbac.generateRelatedRbacObject(targetTable varchar)
language plpgsql as $$
declare
targetTableName text;
targetSchemaPrefix text;
createInsertTriggerSQL text;
createDeleteTriggerSQL text;
begin
if POSITION('.' IN targetTable) > 0 then
targetSchemaPrefix := SPLIT_PART(targetTable, '.', 1) || '.';
targetTableName := SPLIT_PART(targetTable, '.', 2);
else
targetSchemaPrefix := '';
targetTableName := targetTable;
end if;
if targetSchemaPrefix = '' and targetTableName = 'customer' then
raise exception 'missing targetShemaPrefix: %', targetTable;
end if;
createInsertTriggerSQL = format($sql$
create trigger createRbacObjectFor_%s_Trigger
before insert on %s
create trigger createRbacObjectFor_%s_insert_tg_1058_25
before insert on %s%s
for each row
execute procedure rbac.insert_related_object();
$sql$, targetTable, targetTable);
$sql$, targetTableName, targetSchemaPrefix, targetTableName);
execute createInsertTriggerSQL;
createDeleteTriggerSQL = format($sql$
create trigger delete_related_rbac_rules_for_%s_tg
after delete
on %s
create trigger createRbacObjectFor_%s_delete_tg_1058_35
after delete on %s%s
for each row
execute procedure rbac.delete_related_rbac_rules_tf();
$sql$, targetTable, targetTable);
$sql$, targetTableName, targetSchemaPrefix, targetTableName);
execute createDeleteTriggerSQL;
end; $$;
end;
$$;
--//
@ -176,7 +190,7 @@ begin
*/
sql := format($sql$
create or replace view %1$s_rv as
with accessible_%1$s_uuids as (
with accessible_uuids as (
with recursive
recursive_grants as
(select distinct rbac.grants.descendantuuid,
@ -209,7 +223,7 @@ begin
)
select target.*
from %1$s as target
where target.uuid in (select * from accessible_%1$s_uuids)
where target.uuid in (select * from accessible_uuids)
order by %2$s;
grant all privileges on %1$s_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
@ -219,7 +233,7 @@ begin
/**
Instead of insert trigger function for the restricted view.
*/
newColumns := 'new.' || replace(columnNames, ',', ', new.');
newColumns := 'new.' || replace(columnNames, ', ', ', new.');
sql := format($sql$
create or replace function %1$sInsert()
returns trigger
@ -240,7 +254,7 @@ begin
Creates an instead of insert trigger for the restricted view.
*/
sql := format($sql$
create trigger %1$sInsert_tg
create trigger instead_of_insert_tg
instead of insert
on %1$s_rv
for each row
@ -269,7 +283,7 @@ begin
Creates an instead of delete trigger for the restricted view.
*/
sql := format($sql$
create trigger %1$sDelete_tg
create trigger instead_of_delete_tg
instead of delete
on %1$s_rv
for each row
@ -302,7 +316,7 @@ begin
Creates an instead of delete trigger for the restricted view.
*/
sql = format($sql$
create trigger %1$sUpdate_tg
create trigger instead_of_update_tg
instead of update
on %1$s_rv
for each row

View File

@ -0,0 +1,8 @@
--liquibase formatted sql
-- ============================================================================
--changeset test-SCHEMA:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
CREATE SCHEMA IF NOT EXISTS test;
--//

View File

@ -4,10 +4,10 @@
--changeset test-customer-MAIN-TABLE:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
create table if not exists test_customer
create table if not exists test.customer
(
uuid uuid unique references rbac.object (uuid),
version int not null default 0,
version int not null default 0,
reference int not null unique check (reference between 10000 and 99999),
prefix character(3) unique,
adminUserName varchar(63)

View File

@ -3,21 +3,21 @@
-- ============================================================================
--changeset test-customer-rbac-OBJECT:1 endDelimiter:--//
--changeset test.customer-rbac-OBJECT:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRelatedRbacObject('test_customer');
call rbac.generateRelatedRbacObject('test.customer');
--//
-- ============================================================================
--changeset test-customer-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
--changeset test.customer-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRbacRoleDescriptors('testCustomer', 'test_customer');
call rbac.generateRbacRoleDescriptors('testCustomer', 'test.customer');
--//
-- ============================================================================
--changeset test-customer-rbac-insert-trigger:1 endDelimiter:--//
--changeset test.customer-rbac-insert-trigger:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
@ -25,7 +25,7 @@ call rbac.generateRbacRoleDescriptors('testCustomer', 'test_customer');
*/
create or replace procedure buildRbacSystemForTestCustomer(
NEW test_customer
NEW test.customer
)
language plpgsql as $$
@ -57,7 +57,7 @@ begin
end; $$;
/*
AFTER INSERT TRIGGER to create the role+grant structure for a new test_customer row.
AFTER INSERT TRIGGER to create the role+grant structure for a new test.customer row.
*/
create or replace function insertTriggerForTestCustomer_tf()
@ -70,68 +70,68 @@ begin
end; $$;
create trigger insertTriggerForTestCustomer_tg
after insert on test_customer
after insert on test.customer
for each row
execute procedure insertTriggerForTestCustomer_tf();
--//
-- ============================================================================
--changeset test-customer-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
--changeset test.customer-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
-- granting INSERT permission to rbac.global ----------------------------
/*
Grants INSERT INTO test_customer permissions to specified role of pre-existing rbac.global rows.
Grants INSERT INTO test.customer permissions to specified role of pre-existing rbac.global rows.
*/
do language plpgsql $$
declare
row rbac.global;
begin
call base.defineContext('create INSERT INTO test_customer permissions for pre-exising rbac.global rows');
call base.defineContext('create INSERT INTO test.customer permissions for pre-exising rbac.global rows');
FOR row IN SELECT * FROM rbac.global
-- unconditional for all rows in that table
LOOP
call rbac.grantPermissionToRole(
rbac.createPermission(row.uuid, 'INSERT', 'test_customer'),
rbac.createPermission(row.uuid, 'INSERT', 'test.customer'),
rbac.globalADMIN());
END LOOP;
end;
$$;
/**
Grants test_customer INSERT permission to specified role of new global rows.
Grants test.customer INSERT permission to specified role of new global rows.
*/
create or replace function rbac.new_test_customer_grants_insert_to_global_tf()
create or replace function rbac.new_customer_grants_insert_to_global_tf()
returns trigger
language plpgsql
strict as $$
begin
-- unconditional for all rows in that table
call rbac.grantPermissionToRole(
rbac.createPermission(NEW.uuid, 'INSERT', 'test_customer'),
rbac.createPermission(NEW.uuid, 'INSERT', 'test.customer'),
rbac.globalADMIN());
-- end.
return NEW;
end; $$;
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
create trigger z_new_test_customer_grants_after_insert_tg
create trigger z_new_customer_grants_after_insert_tg
after insert on rbac.global
for each row
execute procedure rbac.new_test_customer_grants_insert_to_global_tf();
execute procedure rbac.new_customer_grants_insert_to_global_tf();
-- ============================================================================
--changeset test_customer-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
--changeset test.customer-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/**
Checks if the user respectively the assumed roles are allowed to insert a row to test_customer.
Checks if the user respectively the assumed roles are allowed to insert a row to test.customer.
*/
create or replace function test_customer_insert_permission_check_tf()
create or replace function test.customer_insert_permission_check_tf()
returns trigger
language plpgsql as $$
declare
@ -142,22 +142,22 @@ begin
return NEW;
end if;
raise exception '[403] insert into test_customer values(%) not allowed for current subjects % (%)',
raise exception '[403] insert into test.customer values(%) not allowed for current subjects % (%)',
NEW, base.currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end; $$;
create trigger test_customer_insert_permission_check_tg
before insert on test_customer
create trigger customer_insert_permission_check_tg
before insert on test.customer
for each row
execute procedure test_customer_insert_permission_check_tf();
execute procedure test.customer_insert_permission_check_tf();
--//
-- ============================================================================
--changeset test-customer-rbac-IDENTITY-VIEW:1 endDelimiter:--//
--changeset test.customer-rbac-IDENTITY-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRbacIdentityViewFromProjection('test_customer',
call rbac.generateRbacIdentityViewFromProjection('test.customer',
$idName$
prefix
$idName$);
@ -165,9 +165,9 @@ call rbac.generateRbacIdentityViewFromProjection('test_customer',
-- ============================================================================
--changeset test-customer-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
--changeset test.customer-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRbacRestrictedView('test_customer',
call rbac.generateRbacRestrictedView('test.customer',
$orderBy$
reference
$orderBy$,

View File

@ -28,18 +28,18 @@ declare
custRowId uuid;
custAdminName varchar;
custAdminUuid uuid;
newCust test_customer;
newCust test.customer;
begin
custRowId = uuid_generate_v4();
custAdminName = 'customer-admin@' || custPrefix || '.example.com';
custAdminUuid = rbac.create_subject(custAdminName);
insert
into test_customer (reference, prefix, adminUserName)
into test.customer (reference, prefix, adminUserName)
values (custReference, custPrefix, custAdminName);
select * into newCust
from test_customer where reference=custReference;
from test.customer where reference=custReference;
call rbac.grantRoleToSubject(
rbac.getRoleId(testCustomerOwner(newCust)),
rbac.getRoleId(testCustomerAdmin(newCust)),

View File

@ -4,11 +4,11 @@
--changeset test-package-MAIN-TABLE:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
create table if not exists test_package
create table if not exists test.package
(
uuid uuid unique references rbac.object (uuid),
version int not null default 0,
customerUuid uuid references test_customer (uuid),
customerUuid uuid references test.customer (uuid),
name varchar(5),
description varchar(96)
);

View File

@ -3,21 +3,21 @@
-- ============================================================================
--changeset test-package-rbac-OBJECT:1 endDelimiter:--//
--changeset test.package-rbac-OBJECT:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRelatedRbacObject('test_package');
call rbac.generateRelatedRbacObject('test.package');
--//
-- ============================================================================
--changeset test-package-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
--changeset test.package-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRbacRoleDescriptors('testPackage', 'test_package');
call rbac.generateRbacRoleDescriptors('testPackage', 'test.package');
--//
-- ============================================================================
--changeset test-package-rbac-insert-trigger:1 endDelimiter:--//
--changeset test.package-rbac-insert-trigger:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
@ -25,17 +25,17 @@ call rbac.generateRbacRoleDescriptors('testPackage', 'test_package');
*/
create or replace procedure buildRbacSystemForTestPackage(
NEW test_package
NEW test.package
)
language plpgsql as $$
declare
newCustomer test_customer;
newCustomer test.customer;
begin
call rbac.enterTriggerForObjectUuid(NEW.uuid);
SELECT * FROM test_customer WHERE uuid = NEW.customerUuid INTO newCustomer;
SELECT * FROM test.customer WHERE uuid = NEW.customerUuid INTO newCustomer;
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s', NEW.customerUuid);
@ -61,7 +61,7 @@ begin
end; $$;
/*
AFTER INSERT TRIGGER to create the role+grant structure for a new test_package row.
AFTER INSERT TRIGGER to create the role+grant structure for a new test.package row.
*/
create or replace function insertTriggerForTestPackage_tf()
@ -74,14 +74,14 @@ begin
end; $$;
create trigger insertTriggerForTestPackage_tg
after insert on test_package
after insert on test.package
for each row
execute procedure insertTriggerForTestPackage_tf();
--//
-- ============================================================================
--changeset test-package-rbac-update-trigger:1 endDelimiter:--//
--changeset test.package-rbac-update-trigger:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
@ -89,22 +89,22 @@ execute procedure insertTriggerForTestPackage_tf();
*/
create or replace procedure updateRbacRulesForTestPackage(
OLD test_package,
NEW test_package
OLD test.package,
NEW test.package
)
language plpgsql as $$
declare
oldCustomer test_customer;
newCustomer test_customer;
oldCustomer test.customer;
newCustomer test.customer;
begin
call rbac.enterTriggerForObjectUuid(NEW.uuid);
SELECT * FROM test_customer WHERE uuid = OLD.customerUuid INTO oldCustomer;
SELECT * FROM test.customer WHERE uuid = OLD.customerUuid INTO oldCustomer;
assert oldCustomer.uuid is not null, format('oldCustomer must not be null for OLD.customerUuid = %s', OLD.customerUuid);
SELECT * FROM test_customer WHERE uuid = NEW.customerUuid INTO newCustomer;
SELECT * FROM test.customer WHERE uuid = NEW.customerUuid INTO newCustomer;
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s', NEW.customerUuid);
@ -122,7 +122,7 @@ begin
end; $$;
/*
AFTER INSERT TRIGGER to re-wire the grant structure for a new test_package row.
AFTER INSERT TRIGGER to re-wire the grant structure for a new test.package row.
*/
create or replace function updateTriggerForTestPackage_tf()
@ -135,94 +135,94 @@ begin
end; $$;
create trigger updateTriggerForTestPackage_tg
after update on test_package
after update on test.package
for each row
execute procedure updateTriggerForTestPackage_tf();
--//
-- ============================================================================
--changeset test-package-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
--changeset test.package-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
-- granting INSERT permission to test_customer ----------------------------
-- granting INSERT permission to test.customer ----------------------------
/*
Grants INSERT INTO test_package permissions to specified role of pre-existing test_customer rows.
Grants INSERT INTO test.package permissions to specified role of pre-existing test.customer rows.
*/
do language plpgsql $$
declare
row test_customer;
row test.customer;
begin
call base.defineContext('create INSERT INTO test_package permissions for pre-exising test_customer rows');
call base.defineContext('create INSERT INTO test.package permissions for pre-exising test.customer rows');
FOR row IN SELECT * FROM test_customer
FOR row IN SELECT * FROM test.customer
-- unconditional for all rows in that table
LOOP
call rbac.grantPermissionToRole(
rbac.createPermission(row.uuid, 'INSERT', 'test_package'),
rbac.createPermission(row.uuid, 'INSERT', 'test.package'),
testCustomerADMIN(row));
END LOOP;
end;
$$;
/**
Grants test_package INSERT permission to specified role of new test_customer rows.
Grants test.package INSERT permission to specified role of new customer rows.
*/
create or replace function new_test_package_grants_insert_to_test_customer_tf()
create or replace function test.new_package_grants_insert_to_customer_tf()
returns trigger
language plpgsql
strict as $$
begin
-- unconditional for all rows in that table
call rbac.grantPermissionToRole(
rbac.createPermission(NEW.uuid, 'INSERT', 'test_package'),
rbac.createPermission(NEW.uuid, 'INSERT', 'test.package'),
testCustomerADMIN(NEW));
-- end.
return NEW;
end; $$;
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
create trigger z_new_test_package_grants_after_insert_tg
after insert on test_customer
create trigger z_new_package_grants_after_insert_tg
after insert on test.customer
for each row
execute procedure new_test_package_grants_insert_to_test_customer_tf();
execute procedure test.new_package_grants_insert_to_customer_tf();
-- ============================================================================
--changeset test_package-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
--changeset test.package-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/**
Checks if the user respectively the assumed roles are allowed to insert a row to test_package.
Checks if the user respectively the assumed roles are allowed to insert a row to test.package.
*/
create or replace function test_package_insert_permission_check_tf()
create or replace function test.package_insert_permission_check_tf()
returns trigger
language plpgsql as $$
declare
superObjectUuid uuid;
begin
-- check INSERT permission via direct foreign key: NEW.customerUuid
if rbac.hasInsertPermission(NEW.customerUuid, 'test_package') then
if rbac.hasInsertPermission(NEW.customerUuid, 'test.package') then
return NEW;
end if;
raise exception '[403] insert into test_package values(%) not allowed for current subjects % (%)',
raise exception '[403] insert into test.package values(%) not allowed for current subjects % (%)',
NEW, base.currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end; $$;
create trigger test_package_insert_permission_check_tg
before insert on test_package
create trigger package_insert_permission_check_tg
before insert on test.package
for each row
execute procedure test_package_insert_permission_check_tf();
execute procedure test.package_insert_permission_check_tf();
--//
-- ============================================================================
--changeset test-package-rbac-IDENTITY-VIEW:1 endDelimiter:--//
--changeset test.package-rbac-IDENTITY-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRbacIdentityViewFromProjection('test_package',
call rbac.generateRbacIdentityViewFromProjection('test.package',
$idName$
name
$idName$);
@ -230,9 +230,9 @@ call rbac.generateRbacIdentityViewFromProjection('test_package',
-- ============================================================================
--changeset test-package-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
--changeset test.package-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRbacRestrictedView('test_package',
call rbac.generateRbacRestrictedView('test.package',
$orderBy$
name
$orderBy$,

View File

@ -9,23 +9,23 @@
create or replace procedure createPackageTestData(customerPrefix varchar, pacCount int)
language plpgsql as $$
declare
cust test_customer;
cust test.customer;
custAdminUser varchar;
custAdminRole varchar;
pacName varchar;
pac test_package;
pac test.package;
begin
select * from test_customer where test_customer.prefix = customerPrefix into cust;
select * from test.customer where test.customer.prefix = customerPrefix into cust;
for t in 0..(pacCount-1)
loop
pacName = cust.prefix || to_char(t, 'fm00');
custAdminUser = 'customer-admin@' || cust.prefix || '.example.com';
custAdminRole = 'test_customer#' || cust.prefix || ':ADMIN';
custAdminRole = 'test.customer#' || cust.prefix || ':ADMIN';
call base.defineContext('creating RBAC test package', null, 'superuser-fran@hostsharing.net', custAdminRole);
insert
into test_package (customerUuid, name, description)
into test.package (customerUuid, name, description)
values (cust.uuid, pacName, 'Here you can add your own description of package ' || pacName || '.')
returning * into pac;
@ -44,9 +44,9 @@ end; $$;
create or replace procedure createPackageTestData()
language plpgsql as $$
declare
cust test_customer;
cust test.customer;
begin
for cust in (select * from test_customer)
for cust in (select * from test.customer)
loop
continue when cust.reference >= 90000; -- reserved for functional testing
call createPackageTestData(cust.prefix, 3);

View File

@ -4,10 +4,10 @@
--changeset test-domain-MAIN-TABLE:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
create table if not exists test_domain
create table if not exists test.domain
(
uuid uuid unique references rbac.object (uuid),
packageUuid uuid references test_package (uuid),
packageUuid uuid references test.package (uuid),
name character varying(253),
description character varying(96)
);

View File

@ -3,21 +3,21 @@
-- ============================================================================
--changeset test-domain-rbac-OBJECT:1 endDelimiter:--//
--changeset test.domain-rbac-OBJECT:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRelatedRbacObject('test_domain');
call rbac.generateRelatedRbacObject('test.domain');
--//
-- ============================================================================
--changeset test-domain-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
--changeset test.domain-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRbacRoleDescriptors('testDomain', 'test_domain');
call rbac.generateRbacRoleDescriptors('testDomain', 'test.domain');
--//
-- ============================================================================
--changeset test-domain-rbac-insert-trigger:1 endDelimiter:--//
--changeset test.domain-rbac-insert-trigger:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
@ -25,17 +25,17 @@ call rbac.generateRbacRoleDescriptors('testDomain', 'test_domain');
*/
create or replace procedure buildRbacSystemForTestDomain(
NEW test_domain
NEW test.domain
)
language plpgsql as $$
declare
newPackage test_package;
newPackage test.package;
begin
call rbac.enterTriggerForObjectUuid(NEW.uuid);
SELECT * FROM test_package WHERE uuid = NEW.packageUuid INTO newPackage;
SELECT * FROM test.package WHERE uuid = NEW.packageUuid INTO newPackage;
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s', NEW.packageUuid);
@ -57,7 +57,7 @@ begin
end; $$;
/*
AFTER INSERT TRIGGER to create the role+grant structure for a new test_domain row.
AFTER INSERT TRIGGER to create the role+grant structure for a new test.domain row.
*/
create or replace function insertTriggerForTestDomain_tf()
@ -70,14 +70,14 @@ begin
end; $$;
create trigger insertTriggerForTestDomain_tg
after insert on test_domain
after insert on test.domain
for each row
execute procedure insertTriggerForTestDomain_tf();
--//
-- ============================================================================
--changeset test-domain-rbac-update-trigger:1 endDelimiter:--//
--changeset test.domain-rbac-update-trigger:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
@ -85,22 +85,22 @@ execute procedure insertTriggerForTestDomain_tf();
*/
create or replace procedure updateRbacRulesForTestDomain(
OLD test_domain,
NEW test_domain
OLD test.domain,
NEW test.domain
)
language plpgsql as $$
declare
oldPackage test_package;
newPackage test_package;
oldPackage test.package;
newPackage test.package;
begin
call rbac.enterTriggerForObjectUuid(NEW.uuid);
SELECT * FROM test_package WHERE uuid = OLD.packageUuid INTO oldPackage;
SELECT * FROM test.package WHERE uuid = OLD.packageUuid INTO oldPackage;
assert oldPackage.uuid is not null, format('oldPackage must not be null for OLD.packageUuid = %s', OLD.packageUuid);
SELECT * FROM test_package WHERE uuid = NEW.packageUuid INTO newPackage;
SELECT * FROM test.package WHERE uuid = NEW.packageUuid INTO newPackage;
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s', NEW.packageUuid);
@ -121,7 +121,7 @@ begin
end; $$;
/*
AFTER INSERT TRIGGER to re-wire the grant structure for a new test_domain row.
AFTER INSERT TRIGGER to re-wire the grant structure for a new test.domain row.
*/
create or replace function updateTriggerForTestDomain_tf()
@ -134,94 +134,94 @@ begin
end; $$;
create trigger updateTriggerForTestDomain_tg
after update on test_domain
after update on test.domain
for each row
execute procedure updateTriggerForTestDomain_tf();
--//
-- ============================================================================
--changeset test-domain-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
--changeset test.domain-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
-- granting INSERT permission to test_package ----------------------------
-- granting INSERT permission to test.package ----------------------------
/*
Grants INSERT INTO test_domain permissions to specified role of pre-existing test_package rows.
Grants INSERT INTO test.domain permissions to specified role of pre-existing test.package rows.
*/
do language plpgsql $$
declare
row test_package;
row test.package;
begin
call base.defineContext('create INSERT INTO test_domain permissions for pre-exising test_package rows');
call base.defineContext('create INSERT INTO test.domain permissions for pre-exising test.package rows');
FOR row IN SELECT * FROM test_package
FOR row IN SELECT * FROM test.package
-- unconditional for all rows in that table
LOOP
call rbac.grantPermissionToRole(
rbac.createPermission(row.uuid, 'INSERT', 'test_domain'),
rbac.createPermission(row.uuid, 'INSERT', 'test.domain'),
testPackageADMIN(row));
END LOOP;
end;
$$;
/**
Grants test_domain INSERT permission to specified role of new test_package rows.
Grants test.domain INSERT permission to specified role of new package rows.
*/
create or replace function new_test_domain_grants_insert_to_test_package_tf()
create or replace function test.new_domain_grants_insert_to_package_tf()
returns trigger
language plpgsql
strict as $$
begin
-- unconditional for all rows in that table
call rbac.grantPermissionToRole(
rbac.createPermission(NEW.uuid, 'INSERT', 'test_domain'),
rbac.createPermission(NEW.uuid, 'INSERT', 'test.domain'),
testPackageADMIN(NEW));
-- end.
return NEW;
end; $$;
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
create trigger z_new_test_domain_grants_after_insert_tg
after insert on test_package
create trigger z_new_domain_grants_after_insert_tg
after insert on test.package
for each row
execute procedure new_test_domain_grants_insert_to_test_package_tf();
execute procedure test.new_domain_grants_insert_to_package_tf();
-- ============================================================================
--changeset test_domain-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
--changeset test.domain-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/**
Checks if the user respectively the assumed roles are allowed to insert a row to test_domain.
Checks if the user respectively the assumed roles are allowed to insert a row to test.domain.
*/
create or replace function test_domain_insert_permission_check_tf()
create or replace function test.domain_insert_permission_check_tf()
returns trigger
language plpgsql as $$
declare
superObjectUuid uuid;
begin
-- check INSERT permission via direct foreign key: NEW.packageUuid
if rbac.hasInsertPermission(NEW.packageUuid, 'test_domain') then
if rbac.hasInsertPermission(NEW.packageUuid, 'test.domain') then
return NEW;
end if;
raise exception '[403] insert into test_domain values(%) not allowed for current subjects % (%)',
raise exception '[403] insert into test.domain values(%) not allowed for current subjects % (%)',
NEW, base.currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end; $$;
create trigger test_domain_insert_permission_check_tg
before insert on test_domain
create trigger domain_insert_permission_check_tg
before insert on test.domain
for each row
execute procedure test_domain_insert_permission_check_tf();
execute procedure test.domain_insert_permission_check_tf();
--//
-- ============================================================================
--changeset test-domain-rbac-IDENTITY-VIEW:1 endDelimiter:--//
--changeset test.domain-rbac-IDENTITY-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRbacIdentityViewFromProjection('test_domain',
call rbac.generateRbacIdentityViewFromProjection('test.domain',
$idName$
name
$idName$);
@ -229,9 +229,9 @@ call rbac.generateRbacIdentityViewFromProjection('test_domain',
-- ============================================================================
--changeset test-domain-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
--changeset test.domain-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRbacRestrictedView('test_domain',
call rbac.generateRbacRestrictedView('test.domain',
$orderBy$
name
$orderBy$,

View File

@ -13,8 +13,8 @@ declare
pacAdmin varchar;
begin
select p.uuid, p.name, c.prefix as custPrefix
from test_package p
join test_customer c on p.customeruuid = c.uuid
from test.package p
join test.customer c on p.customeruuid = c.uuid
where p.name = packageName
into pac;
@ -24,7 +24,7 @@ begin
call base.defineContext('creating RBAC test domain', null, pacAdmin, null);
insert
into test_domain (name, packageUuid)
into test.domain (name, packageUuid)
values (pac.name || '-' || base.intToVarChar(t, 4), pac.uuid);
end loop;
end; $$;
@ -41,8 +41,8 @@ declare
begin
for pac in
(select p.uuid, p.name
from test_package p
join test_customer c on p.customeruuid = c.uuid
from test.package p
join test.customer c on p.customeruuid = c.uuid
where c.reference < 90000) -- reserved for functional testing
loop
call createdomainTestData(pac.name, 2);

View File

@ -21,6 +21,8 @@ databaseChangeLog:
file: db/changelog/0-base/009-check-environment.sql
- include:
file: db/changelog/0-base/010-context.sql
- include:
file: db/changelog/0-base/011-table-schema-and-name.sql
- include:
file: db/changelog/0-base/020-audit-log.sql
- include:
@ -47,6 +49,8 @@ databaseChangeLog:
file: db/changelog/1-rbac/1059-rbac-statistics.sql
- include:
file: db/changelog/1-rbac/1080-rbac-global.sql
- include:
file: db/changelog/2-test/200-test-schema.sql
- include:
file: db/changelog/2-test/201-test-customer/2010-test-customer.sql
- include:

View File

@ -289,9 +289,9 @@ public class CsvDataImport extends ContextBasedTest {
protected void deleteFromTestTables() {
jpaAttempt.transacted(() -> {
context(rbacSuperuser);
em.createNativeQuery("delete from test_domain where true").executeUpdate();
em.createNativeQuery("delete from test_package where true").executeUpdate();
em.createNativeQuery("delete from test_customer where true").executeUpdate();
em.createNativeQuery("delete from test.domain where true").executeUpdate();
em.createNativeQuery("delete from test.package where true").executeUpdate();
em.createNativeQuery("delete from test.customer where true").executeUpdate();
}).assertSuccessful();
}

View File

@ -62,13 +62,13 @@ class ContextIntegrationTests {
void defineWithoutcurrentSubjectButWithAssumedRoles() {
// when
final var result = jpaAttempt.transacted(() ->
context.define(null, "test_package#yyy00:ADMIN")
context.define(null, "test.package#yyy00:ADMIN")
);
// then
result.assertExceptionWithRootCauseMessage(
jakarta.persistence.PersistenceException.class,
"ERROR: [403] undefined has no permission to assume role test_package#yyy00:ADMIN");
"ERROR: [403] undefined has no permission to assume role test.package#yyy00:ADMIN");
}
@Test
@ -88,7 +88,7 @@ class ContextIntegrationTests {
@Transactional
void defineWithcurrentSubjectAndAssumedRoles() {
// given
context.define("superuser-alex@hostsharing.net", "test_customer#xxx:OWNER;test_customer#yyy:OWNER");
context.define("superuser-alex@hostsharing.net", "test.customer#xxx:OWNER;test.customer#yyy:OWNER");
// when
final var currentSubject = context.fetchCurrentSubject();
@ -96,7 +96,7 @@ class ContextIntegrationTests {
// then
assertThat(context.fetchAssumedRoles())
.isEqualTo(Array.of("test_customer#xxx:OWNER", "test_customer#yyy:OWNER"));
.isEqualTo(Array.of("test.customer#xxx:OWNER", "test.customer#yyy:OWNER"));
assertThat(context.fetchCurrentSubjectOrAssumedRolesUuids()).hasSize(2);
}
@ -104,12 +104,12 @@ class ContextIntegrationTests {
public void defineContextWithcurrentSubjectAndAssumeInaccessibleRole() {
// when
final var result = jpaAttempt.transacted(() ->
context.define("customer-admin@xxx.example.com", "test_package#yyy00:ADMIN")
context.define("customer-admin@xxx.example.com", "test.package#yyy00:ADMIN")
);
// then
result.assertExceptionWithRootCauseMessage(
jakarta.persistence.PersistenceException.class,
"ERROR: [403] subject customer-admin@xxx.example.com has no permission to assume role test_package#yyy00:ADMIN");
"ERROR: [403] subject customer-admin@xxx.example.com has no permission to assume role test.package#yyy00:ADMIN");
}
}

View File

@ -71,16 +71,16 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
.body("", hasItem(
allOf(
// TODO: should there be a grantedByRole or just a grantedByTrigger?
hasEntry("grantedByRoleIdName", "test_customer#xxx:OWNER"),
hasEntry("grantedRoleIdName", "test_customer#xxx:ADMIN"),
hasEntry("grantedByRoleIdName", "test.customer#xxx:OWNER"),
hasEntry("grantedRoleIdName", "test.customer#xxx:ADMIN"),
hasEntry("granteeSubjectName", "customer-admin@xxx.example.com")
)
))
.body("", hasItem(
allOf(
// TODO: should there be a grantedByRole or just a grantedByTrigger?
hasEntry("grantedByRoleIdName", "test_customer#yyy:OWNER"),
hasEntry("grantedRoleIdName", "test_customer#yyy:ADMIN"),
hasEntry("grantedByRoleIdName", "test.customer#yyy:OWNER"),
hasEntry("grantedRoleIdName", "test.customer#yyy:ADMIN"),
hasEntry("granteeSubjectName", "customer-admin@yyy.example.com")
)
))
@ -93,15 +93,15 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
))
.body("", hasItem(
allOf(
hasEntry("grantedByRoleIdName", "test_customer#xxx:ADMIN"),
hasEntry("grantedRoleIdName", "test_package#xxx00:ADMIN"),
hasEntry("grantedByRoleIdName", "test.customer#xxx:ADMIN"),
hasEntry("grantedRoleIdName", "test.package#xxx00:ADMIN"),
hasEntry("granteeSubjectName", "pac-admin-xxx00@xxx.example.com")
)
))
.body("", hasItem(
allOf(
hasEntry("grantedByRoleIdName", "test_customer#zzz:ADMIN"),
hasEntry("grantedRoleIdName", "test_package#zzz02:ADMIN"),
hasEntry("grantedByRoleIdName", "test.customer#zzz:ADMIN"),
hasEntry("grantedRoleIdName", "test.package#zzz02:ADMIN"),
hasEntry("granteeSubjectName", "pac-admin-zzz02@zzz.example.com")
)
))
@ -114,7 +114,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
RestAssured // @formatter:off
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_package#yyy00:ADMIN")
.header("assumed-roles", "test.package#yyy00:ADMIN")
.port(port)
.when()
.get("http://localhost/api/rbac/grants")
@ -123,8 +123,8 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
.contentType("application/json")
.body("", hasItem(
allOf(
hasEntry("grantedByRoleIdName", "test_customer#yyy:ADMIN"),
hasEntry("grantedRoleIdName", "test_package#yyy00:ADMIN"),
hasEntry("grantedByRoleIdName", "test.customer#yyy:ADMIN"),
hasEntry("grantedRoleIdName", "test.package#yyy00:ADMIN"),
hasEntry("granteeSubjectName", "pac-admin-yyy00@yyy.example.com")
)
))
@ -145,13 +145,13 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
.contentType("application/json")
.body("", hasItem(
allOf(
hasEntry("grantedByRoleIdName", "test_customer#yyy:ADMIN"),
hasEntry("grantedRoleIdName", "test_package#yyy00:ADMIN"),
hasEntry("grantedByRoleIdName", "test.customer#yyy:ADMIN"),
hasEntry("grantedRoleIdName", "test.package#yyy00:ADMIN"),
hasEntry("granteeSubjectName", "pac-admin-yyy00@yyy.example.com")
)
))
.body("[0].grantedByRoleIdName", is("test_customer#yyy:ADMIN"))
.body("[0].grantedRoleIdName", is("test_package#yyy00:ADMIN"))
.body("[0].grantedByRoleIdName", is("test.customer#yyy:ADMIN"))
.body("[0].grantedRoleIdName", is("test.package#yyy00:ADMIN"))
.body("[0].granteeSubjectName", is("pac-admin-yyy00@yyy.example.com"));
// @formatter:on
}
@ -165,7 +165,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given
final var givencurrentSubjectAsPackageAdmin = new Subject("customer-admin@xxx.example.com");
final var givenGranteeUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com");
final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN");
final var givenGrantedRole = getRbacRoleByName("test.package#xxx00:ADMIN");
// when
final var grant = givencurrentSubjectAsPackageAdmin.getGrantById()
@ -174,8 +174,8 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// then
grant.assertThat()
.statusCode(200)
.body("grantedByRoleIdName", is("test_customer#xxx:ADMIN"))
.body("grantedRoleIdName", is("test_package#xxx00:ADMIN"))
.body("grantedByRoleIdName", is("test.customer#xxx:ADMIN"))
.body("grantedRoleIdName", is("test.package#xxx00:ADMIN"))
.body("granteeSubjectName", is("pac-admin-xxx00@xxx.example.com"));
}
@ -184,7 +184,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given
final var givencurrentSubjectAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com");
final var givenGranteeUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com");
final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN");
final var givenGrantedRole = getRbacRoleByName("test.package#xxx00:ADMIN");
// when
final var grant = givencurrentSubjectAsPackageAdmin.getGrantById()
@ -193,8 +193,8 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// then
grant.assertThat()
.statusCode(200)
.body("grantedByRoleIdName", is("test_customer#xxx:ADMIN"))
.body("grantedRoleIdName", is("test_package#xxx00:ADMIN"))
.body("grantedByRoleIdName", is("test.customer#xxx:ADMIN"))
.body("grantedRoleIdName", is("test.package#xxx00:ADMIN"))
.body("granteeSubjectName", is("pac-admin-xxx00@xxx.example.com"));
}
@ -203,9 +203,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given
final var givencurrentSubjectAsPackageAdmin = new Subject(
"pac-admin-xxx00@xxx.example.com",
"test_package#xxx00:ADMIN");
"test.package#xxx00:ADMIN");
final var givenGranteeUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com");
final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN");
final var givenGrantedRole = getRbacRoleByName("test.package#xxx00:ADMIN");
// when
final var grant = givencurrentSubjectAsPackageAdmin.getGrantById()
@ -214,8 +214,8 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// then
grant.assertThat()
.statusCode(200)
.body("grantedByRoleIdName", is("test_customer#xxx:ADMIN"))
.body("grantedRoleIdName", is("test_package#xxx00:ADMIN"))
.body("grantedByRoleIdName", is("test.customer#xxx:ADMIN"))
.body("grantedRoleIdName", is("test.package#xxx00:ADMIN"))
.body("granteeSubjectName", is("pac-admin-xxx00@xxx.example.com"));
}
@ -225,9 +225,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given
final var givencurrentSubjectAsPackageAdmin = new Subject(
"pac-admin-xxx00@xxx.example.com",
"test_package#xxx00:TENANT");
"test.package#xxx00:TENANT");
final var givenGranteeUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com");
final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN");
final var givenGrantedRole = getRbacRoleByName("test.package#xxx00:ADMIN");
final var grant = givencurrentSubjectAsPackageAdmin.getGrantById()
.forGrantedRole(givenGrantedRole).toGranteeUser(givenGranteeUser);
@ -245,7 +245,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given
final var givenNewUser = createRbacSubject();
final var givenRoleToGrant = "test_package#xxx00:ADMIN";
final var givenRoleToGrant = "test.package#xxx00:ADMIN";
final var givencurrentSubjectAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant);
final var givenOwnPackageAdminRole =
getRbacRoleByName(givencurrentSubjectAsPackageAdmin.assumedRole);
@ -258,9 +258,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// then
response.assertThat()
.statusCode(201)
.body("grantedByRoleIdName", is("test_package#xxx00:ADMIN"))
.body("grantedByRoleIdName", is("test.package#xxx00:ADMIN"))
.body("assumed", is(true))
.body("grantedRoleIdName", is("test_package#xxx00:ADMIN"))
.body("grantedRoleIdName", is("test.package#xxx00:ADMIN"))
.body("granteeSubjectName", is(givenNewUser.getName()));
assertThat(findAllGrantsOf(givencurrentSubjectAsPackageAdmin))
.extracting(RbacGrantEntity::toDisplay)
@ -274,9 +274,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given
final var givenNewUser = createRbacSubject();
final var givenRoleToGrant = "test_package#xxx00:ADMIN";
final var givenRoleToGrant = "test.package#xxx00:ADMIN";
final var givencurrentSubjectAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant);
final var givenAlienPackageAdminRole = getRbacRoleByName("test_package#yyy00:ADMIN");
final var givenAlienPackageAdminRole = getRbacRoleByName("test.package#yyy00:ADMIN");
// when
final var result = givencurrentSubjectAsPackageAdmin
@ -287,7 +287,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
result.assertThat()
.statusCode(403)
.body("message", containsString("Access to granted role"))
.body("message", containsString("forbidden for test_package#xxx00:ADMIN"));
.body("message", containsString("forbidden for test.package#xxx00:ADMIN"));
assertThat(findAllGrantsOf(givencurrentSubjectAsPackageAdmin))
.extracting(RbacGrantEntity::getGranteeSubjectName)
.doesNotContain(givenNewUser.getName());
@ -303,9 +303,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given
final var givenArbitraryUser = createRbacSubject();
final var givenRoleToGrant = "test_package#xxx00:ADMIN";
final var givenRoleToGrant = "test.package#xxx00:ADMIN";
final var givenCurrentSubjectAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant);
final var givenOwnPackageAdminRole = getRbacRoleByName("test_package#xxx00:ADMIN");
final var givenOwnPackageAdminRole = getRbacRoleByName("test.package#xxx00:ADMIN");
// and given an existing grant
assumeCreated(givenCurrentSubjectAsPackageAdmin

View File

@ -67,7 +67,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
// then
exactlyTheseRbacGrantsAreReturned(
result,
"{ grant role:test_package#xxx00:ADMIN to user:pac-admin-xxx00@xxx.example.com by role:test_customer#xxx:ADMIN and assume }");
"{ grant role:test.package#xxx00:ADMIN to user:pac-admin-xxx00@xxx.example.com by role:test.customer#xxx:ADMIN and assume }");
}
@Test
@ -81,16 +81,16 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
// then
exactlyTheseRbacGrantsAreReturned(
result,
"{ grant role:test_customer#xxx:ADMIN to user:customer-admin@xxx.example.com by role:test_customer#xxx:OWNER and assume }",
"{ grant role:test_package#xxx00:ADMIN to user:pac-admin-xxx00@xxx.example.com by role:test_customer#xxx:ADMIN and assume }",
"{ grant role:test_package#xxx01:ADMIN to user:pac-admin-xxx01@xxx.example.com by role:test_customer#xxx:ADMIN and assume }",
"{ grant role:test_package#xxx02:ADMIN to user:pac-admin-xxx02@xxx.example.com by role:test_customer#xxx:ADMIN and assume }");
"{ grant role:test.customer#xxx:ADMIN to user:customer-admin@xxx.example.com by role:test.customer#xxx:OWNER and assume }",
"{ grant role:test.package#xxx00:ADMIN to user:pac-admin-xxx00@xxx.example.com by role:test.customer#xxx:ADMIN and assume }",
"{ grant role:test.package#xxx01:ADMIN to user:pac-admin-xxx01@xxx.example.com by role:test.customer#xxx:ADMIN and assume }",
"{ grant role:test.package#xxx02:ADMIN to user:pac-admin-xxx02@xxx.example.com by role:test.customer#xxx:ADMIN and assume }");
}
@Test
public void customerAdmin_withAssumedRole_canOnlyViewRbacGrantsVisibleByAssumedRole() {
// given:
context("customer-admin@xxx.example.com", "test_package#xxx00:ADMIN");
context("customer-admin@xxx.example.com", "test.package#xxx00:ADMIN");
// when
final var result = rbacGrantRepository.findAll();
@ -98,7 +98,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
// then
exactlyTheseRbacGrantsAreReturned(
result,
"{ grant role:test_package#xxx00:ADMIN to user:pac-admin-xxx00@xxx.example.com by role:test_customer#xxx:ADMIN and assume }");
"{ grant role:test.package#xxx00:ADMIN to user:pac-admin-xxx00@xxx.example.com by role:test.customer#xxx:ADMIN and assume }");
}
}
@ -108,9 +108,9 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
@Test
public void customerAdmin_canGrantOwnPackageAdminRole_toArbitraryUser() {
// given
context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN");
context("customer-admin@xxx.example.com", "test.customer#xxx:ADMIN");
final var givenArbitrarySubjectUuid = rbacSubjectRepository.findByName("pac-admin-zzz00@zzz.example.com").getUuid();
final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName("test_package#xxx00:ADMIN").getUuid();
final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName("test.package#xxx00:ADMIN").getUuid();
// when
final var grant = RbacGrantEntity.builder()
@ -126,7 +126,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
assertThat(rbacGrantRepository.findAll())
.extracting(RbacGrantEntity::toDisplay)
.contains(
"{ grant role:test_package#xxx00:ADMIN to user:pac-admin-zzz00@zzz.example.com by role:test_customer#xxx:ADMIN and assume }");
"{ grant role:test.package#xxx00:ADMIN to user:pac-admin-zzz00@zzz.example.com by role:test.customer#xxx:ADMIN and assume }");
}
@Test
@ -139,14 +139,14 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
context("customer-admin@xxx.example.com", null);
return new Given(
createNewUser(),
rbacRoleRepository.findByRoleName("test_package#xxx00:OWNER").getUuid()
rbacRoleRepository.findByRoleName("test.package#xxx00:OWNER").getUuid()
);
}).assumeSuccessful().returnedValue();
// when
final var attempt = jpaAttempt.transacted(() -> {
// now we try to use these uuids as a less privileged user
context("pac-admin-xxx00@xxx.example.com", "test_package#xxx00:ADMIN");
context("pac-admin-xxx00@xxx.example.com", "test.package#xxx00:ADMIN");
final var grant = RbacGrantEntity.builder()
.granteeSubjectUuid(given.arbitraryUser.getUuid())
.grantedRoleUuid(given.packageOwnerRoleUuid)
@ -158,8 +158,8 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
// then
attempt.assertExceptionWithRootCauseMessage(
JpaSystemException.class,
"ERROR: [403] Access to granted role test_package#xxx00:OWNER",
"forbidden for test_package#xxx00:ADMIN");
"ERROR: [403] Access to granted role test.package#xxx00:OWNER",
"forbidden for test.package#xxx00:ADMIN");
jpaAttempt.transacted(() -> {
// finally, we use the new user to make sure, no roles were granted
context(given.arbitraryUser.getName(), null);
@ -176,16 +176,16 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
public void customerAdmin_canRevokeSelfGrantedPackageAdminRole() {
// given
final var grant = create(grant()
.byUser("customer-admin@xxx.example.com").withAssumedRole("test_customer#xxx:ADMIN")
.grantingRole("test_package#xxx00:ADMIN").toUser("pac-admin-zzz00@zzz.example.com"));
.byUser("customer-admin@xxx.example.com").withAssumedRole("test.customer#xxx:ADMIN")
.grantingRole("test.package#xxx00:ADMIN").toUser("pac-admin-zzz00@zzz.example.com"));
// when
context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN");
context("customer-admin@xxx.example.com", "test.customer#xxx:ADMIN");
final var revokeAttempt = attempt(em, () ->
rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId()));
// then
context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN");
context("customer-admin@xxx.example.com", "test.customer#xxx:ADMIN");
assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull();
assertThat(rbacGrantRepository.findAll())
.extracting(RbacGrantEntity::getGranteeSubjectName)
@ -197,17 +197,17 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
// given
final var newUser = createNewUserTransacted();
final var grant = create(grant()
.byUser("customer-admin@xxx.example.com").withAssumedRole("test_package#xxx00:ADMIN")
.grantingRole("test_package#xxx00:ADMIN").toUser(newUser.getName()));
.byUser("customer-admin@xxx.example.com").withAssumedRole("test.package#xxx00:ADMIN")
.grantingRole("test.package#xxx00:ADMIN").toUser(newUser.getName()));
// when
context("pac-admin-xxx00@xxx.example.com", "test_package#xxx00:ADMIN");
context("pac-admin-xxx00@xxx.example.com", "test.package#xxx00:ADMIN");
final var revokeAttempt = attempt(em, () ->
rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId()));
// then
assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull();
context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN");
context("customer-admin@xxx.example.com", "test.customer#xxx:ADMIN");
assertThat(rbacGrantRepository.findAll())
.extracting(RbacGrantEntity::getGranteeSubjectName)
.doesNotContain("pac-admin-zzz00@zzz.example.com");
@ -217,19 +217,19 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
public void packageAdmin_canNotRevokeOwnPackageAdminRoleGrantedByOwnerRoleOfThatPackage() {
// given
final var grant = create(grant()
.byUser("customer-admin@xxx.example.com").withAssumedRole("test_package#xxx00:OWNER")
.grantingRole("test_package#xxx00:ADMIN").toUser("pac-admin-zzz00@zzz.example.com"));
final var grantedByRole = rbacRoleRepository.findByRoleName("test_package#xxx00:OWNER");
.byUser("customer-admin@xxx.example.com").withAssumedRole("test.package#xxx00:OWNER")
.grantingRole("test.package#xxx00:ADMIN").toUser("pac-admin-zzz00@zzz.example.com"));
final var grantedByRole = rbacRoleRepository.findByRoleName("test.package#xxx00:OWNER");
// when
context("pac-admin-xxx00@xxx.example.com", "test_package#xxx00:ADMIN");
context("pac-admin-xxx00@xxx.example.com", "test.package#xxx00:ADMIN");
final var revokeAttempt = attempt(em, () ->
rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId()));
// then
revokeAttempt.assertExceptionWithRootCauseMessage(
JpaSystemException.class,
"ERROR: [403] Revoking role created by %s is forbidden for {test_package#xxx00:ADMIN}.".formatted(
"ERROR: [403] Revoking role created by %s is forbidden for {test.package#xxx00:ADMIN}.".formatted(
grantedByRole.getUuid()
));
}

View File

@ -54,36 +54,36 @@ class RbacGrantsDiagramServiceIntegrationTest extends ContextBasedTestWithCleanu
@Test
void allGrantsTocurrentSubject() {
context("superuser-alex@hostsharing.net", "test_domain#xxx00-aaaa:OWNER");
context("superuser-alex@hostsharing.net", "test.domain#xxx00-aaaa:OWNER");
final var graph = grantsMermaidService.allGrantsTocurrentSubject(EnumSet.of(Include.TEST_ENTITIES));
assertThat(graph).isEqualTo("""
flowchart TB
role:test_domain#xxx00-aaaa:ADMIN --> role:test_package#xxx00:TENANT
role:test_domain#xxx00-aaaa:OWNER --> role:test_domain#xxx00-aaaa:ADMIN
role:test_domain#xxx00-aaaa:OWNER --> role:test_package#xxx00:TENANT
role:test_package#xxx00:TENANT --> role:test_customer#xxx:TENANT
role:test.domain#xxx00-aaaa:ADMIN --> role:test.package#xxx00:TENANT
role:test.domain#xxx00-aaaa:OWNER --> role:test.domain#xxx00-aaaa:ADMIN
role:test.domain#xxx00-aaaa:OWNER --> role:test.package#xxx00:TENANT
role:test.package#xxx00:TENANT --> role:test.customer#xxx:TENANT
""".trim());
}
@Test
void allGrantsTocurrentSubjectIncludingPermissions() {
context("superuser-alex@hostsharing.net", "test_domain#xxx00-aaaa:OWNER");
context("superuser-alex@hostsharing.net", "test.domain#xxx00-aaaa:OWNER");
final var graph = grantsMermaidService.allGrantsTocurrentSubject(EnumSet.of(Include.TEST_ENTITIES, Include.PERMISSIONS));
assertThat(graph).isEqualTo("""
flowchart TB
role:test_customer#xxx:TENANT --> perm:test_customer#xxx:SELECT
role:test_domain#xxx00-aaaa:ADMIN --> perm:test_domain#xxx00-aaaa:SELECT
role:test_domain#xxx00-aaaa:ADMIN --> role:test_package#xxx00:TENANT
role:test_domain#xxx00-aaaa:OWNER --> perm:test_domain#xxx00-aaaa:DELETE
role:test_domain#xxx00-aaaa:OWNER --> perm:test_domain#xxx00-aaaa:UPDATE
role:test_domain#xxx00-aaaa:OWNER --> role:test_domain#xxx00-aaaa:ADMIN
role:test_domain#xxx00-aaaa:OWNER --> role:test_package#xxx00:TENANT
role:test_package#xxx00:TENANT --> perm:test_package#xxx00:SELECT
role:test_package#xxx00:TENANT --> role:test_customer#xxx:TENANT
role:test.customer#xxx:TENANT --> perm:test.customer#xxx:SELECT
role:test.domain#xxx00-aaaa:ADMIN --> perm:test.domain#xxx00-aaaa:SELECT
role:test.domain#xxx00-aaaa:ADMIN --> role:test.package#xxx00:TENANT
role:test.domain#xxx00-aaaa:OWNER --> perm:test.domain#xxx00-aaaa:DELETE
role:test.domain#xxx00-aaaa:OWNER --> perm:test.domain#xxx00-aaaa:UPDATE
role:test.domain#xxx00-aaaa:OWNER --> role:test.domain#xxx00-aaaa:ADMIN
role:test.domain#xxx00-aaaa:OWNER --> role:test.package#xxx00:TENANT
role:test.package#xxx00:TENANT --> perm:test.package#xxx00:SELECT
role:test.package#xxx00:TENANT --> role:test.customer#xxx:TENANT
""".trim());
}

View File

@ -42,14 +42,14 @@ class RbacRoleControllerAcceptanceTest {
.then().assertThat()
.statusCode(200)
.contentType("application/json")
.body("", hasItem(hasEntry("roleName", "test_customer#xxx:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_customer#xxx:OWNER")))
.body("", hasItem(hasEntry("roleName", "test_customer#xxx:TENANT")))
.body("", hasItem(hasEntry("roleName", "test.customer#xxx:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test.customer#xxx:OWNER")))
.body("", hasItem(hasEntry("roleName", "test.customer#xxx:TENANT")))
// ...
.body("", hasItem(hasEntry("roleName", "rbac.global#global:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_customer#yyy:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_package#yyy00:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER")))
.body("", hasItem(hasEntry("roleName", "test.customer#yyy:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test.package#yyy00:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test.domain#yyy00-aaaa:OWNER")))
.body( "size()", greaterThanOrEqualTo(73)); // increases with new test data
// @formatter:on
}
@ -61,7 +61,7 @@ class RbacRoleControllerAcceptanceTest {
RestAssured
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_package#yyy00:ADMIN")
.header("assumed-roles", "test.package#yyy00:ADMIN")
.port(port)
.when()
.get("http://localhost/api/rbac/roles")
@ -71,18 +71,18 @@ class RbacRoleControllerAcceptanceTest {
.statusCode(200)
.contentType("application/json")
.body("", hasItem(hasEntry("roleName", "test_customer#yyy:TENANT")))
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER")))
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaaa:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaab:OWNER")))
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaab:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_package#yyy00:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_package#yyy00:TENANT")))
.body("", hasItem(hasEntry("roleName", "test.customer#yyy:TENANT")))
.body("", hasItem(hasEntry("roleName", "test.domain#yyy00-aaaa:OWNER")))
.body("", hasItem(hasEntry("roleName", "test.domain#yyy00-aaaa:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test.domain#yyy00-aaab:OWNER")))
.body("", hasItem(hasEntry("roleName", "test.domain#yyy00-aaab:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test.package#yyy00:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test.package#yyy00:TENANT")))
.body("", not(hasItem(hasEntry("roleName", "test_customer#xxx:TENANT"))))
.body("", not(hasItem(hasEntry("roleName", "test_domain#xxx00-aaaa:ADMIN"))))
.body("", not(hasItem(hasEntry("roleName", "test_package#xxx00:ADMIN"))))
.body("", not(hasItem(hasEntry("roleName", "test_package#xxx00:TENANT"))))
.body("", not(hasItem(hasEntry("roleName", "test.customer#xxx:TENANT"))))
.body("", not(hasItem(hasEntry("roleName", "test.domain#xxx00-aaaa:ADMIN"))))
.body("", not(hasItem(hasEntry("roleName", "test.package#xxx00:ADMIN"))))
.body("", not(hasItem(hasEntry("roleName", "test.package#xxx00:TENANT"))))
;
// @formatter:on
}
@ -101,15 +101,15 @@ class RbacRoleControllerAcceptanceTest {
.statusCode(200)
.contentType("application/json")
.body("", hasItem(hasEntry("roleName", "test_customer#zzz:TENANT")))
.body("", hasItem(hasEntry("roleName", "test_domain#zzz00-aaaa:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_package#zzz00:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_package#zzz00:TENANT")))
.body("", hasItem(hasEntry("roleName", "test.customer#zzz:TENANT")))
.body("", hasItem(hasEntry("roleName", "test.domain#zzz00-aaaa:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test.package#zzz00:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test.package#zzz00:TENANT")))
.body("", not(hasItem(hasEntry("roleName", "test_customer#yyy:TENANT"))))
.body("", not(hasItem(hasEntry("roleName", "test_domain#yyy00-aaaa:ADMIN"))))
.body("", not(hasItem(hasEntry("roleName", "test_package#yyy00:ADMIN"))))
.body("", not(hasItem(hasEntry("roleName", "test_package#yyy00:TENANT"))));
.body("", not(hasItem(hasEntry("roleName", "test.customer#yyy:TENANT"))))
.body("", not(hasItem(hasEntry("roleName", "test.domain#yyy00-aaaa:ADMIN"))))
.body("", not(hasItem(hasEntry("roleName", "test.package#yyy00:ADMIN"))))
.body("", not(hasItem(hasEntry("roleName", "test.package#yyy00:TENANT"))));
// @formatter:on
}
}

View File

@ -74,11 +74,11 @@ class RbacRoleControllerRestTest {
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(3)))
.andExpect(jsonPath("$[0].roleName", is("rbac.global#global:ADMIN")))
.andExpect(jsonPath("$[1].roleName", is("test_customer#xxx:OWNER")))
.andExpect(jsonPath("$[2].roleName", is("test_customer#xxx:ADMIN")))
.andExpect(jsonPath("$[1].roleName", is("test.customer#xxx:OWNER")))
.andExpect(jsonPath("$[2].roleName", is("test.customer#xxx:ADMIN")))
.andExpect(jsonPath("$[2].uuid", is(customerXxxAdmin.getUuid().toString())))
.andExpect(jsonPath("$[2].objectUuid", is(customerXxxAdmin.getObjectUuid().toString())))
.andExpect(jsonPath("$[2].objectTable", is(customerXxxAdmin.getObjectTable().toString())))
.andExpect(jsonPath("$[2].objectIdName", is(customerXxxAdmin.getObjectIdName().toString())));
.andExpect(jsonPath("$[2].objectTable", is(customerXxxAdmin.getObjectTable())))
.andExpect(jsonPath("$[2].objectIdName", is(customerXxxAdmin.getObjectIdName())));
}
}

View File

@ -40,18 +40,18 @@ class RbacRoleRepositoryIntegrationTest {
private static final String[] ALL_TEST_DATA_ROLES = Array.of(
// @formatter:off
"rbac.global#global:ADMIN",
"test_customer#xxx:ADMIN", "test_customer#xxx:OWNER", "test_customer#xxx:TENANT",
"test_package#xxx00:ADMIN", "test_package#xxx00:OWNER", "test_package#xxx00:TENANT",
"test_package#xxx01:ADMIN", "test_package#xxx01:OWNER", "test_package#xxx01:TENANT",
"test_package#xxx02:ADMIN", "test_package#xxx02:OWNER", "test_package#xxx02:TENANT",
"test_customer#yyy:ADMIN", "test_customer#yyy:OWNER", "test_customer#yyy:TENANT",
"test_package#yyy00:ADMIN", "test_package#yyy00:OWNER", "test_package#yyy00:TENANT",
"test_package#yyy01:ADMIN", "test_package#yyy01:OWNER", "test_package#yyy01:TENANT",
"test_package#yyy02:ADMIN", "test_package#yyy02:OWNER", "test_package#yyy02:TENANT",
"test_customer#zzz:ADMIN", "test_customer#zzz:OWNER", "test_customer#zzz:TENANT",
"test_package#zzz00:ADMIN", "test_package#zzz00:OWNER", "test_package#zzz00:TENANT",
"test_package#zzz01:ADMIN", "test_package#zzz01:OWNER", "test_package#zzz01:TENANT",
"test_package#zzz02:ADMIN", "test_package#zzz02:OWNER", "test_package#zzz02:TENANT"
"test.customer#xxx:ADMIN", "test.customer#xxx:OWNER", "test.customer#xxx:TENANT",
"test.package#xxx00:ADMIN", "test.package#xxx00:OWNER", "test.package#xxx00:TENANT",
"test.package#xxx01:ADMIN", "test.package#xxx01:OWNER", "test.package#xxx01:TENANT",
"test.package#xxx02:ADMIN", "test.package#xxx02:OWNER", "test.package#xxx02:TENANT",
"test.customer#yyy:ADMIN", "test.customer#yyy:OWNER", "test.customer#yyy:TENANT",
"test.package#yyy00:ADMIN", "test.package#yyy00:OWNER", "test.package#yyy00:TENANT",
"test.package#yyy01:ADMIN", "test.package#yyy01:OWNER", "test.package#yyy01:TENANT",
"test.package#yyy02:ADMIN", "test.package#yyy02:OWNER", "test.package#yyy02:TENANT",
"test.customer#zzz:ADMIN", "test.customer#zzz:OWNER", "test.customer#zzz:TENANT",
"test.package#zzz00:ADMIN", "test.package#zzz00:OWNER", "test.package#zzz00:TENANT",
"test.package#zzz01:ADMIN", "test.package#zzz01:OWNER", "test.package#zzz01:TENANT",
"test.package#zzz02:ADMIN", "test.package#zzz02:OWNER", "test.package#zzz02:TENANT"
// @formatter:on
);
@ -91,49 +91,49 @@ class RbacRoleRepositoryIntegrationTest {
allTheseRbacRolesAreReturned(
result,
// @formatter:off
"test_customer#xxx:ADMIN",
"test_customer#xxx:TENANT",
"test_package#xxx00:ADMIN",
"test_package#xxx00:OWNER",
"test_package#xxx00:TENANT",
"test_package#xxx01:ADMIN",
"test_package#xxx01:OWNER",
"test_package#xxx01:TENANT",
"test.customer#xxx:ADMIN",
"test.customer#xxx:TENANT",
"test.package#xxx00:ADMIN",
"test.package#xxx00:OWNER",
"test.package#xxx00:TENANT",
"test.package#xxx01:ADMIN",
"test.package#xxx01:OWNER",
"test.package#xxx01:TENANT",
// ...
"test_domain#xxx00-aaaa:ADMIN",
"test_domain#xxx00-aaaa:OWNER",
"test.domain#xxx00-aaaa:ADMIN",
"test.domain#xxx00-aaaa:OWNER",
// ..
"test_domain#xxx01-aaab:ADMIN",
"test_domain#xxx01-aaab:OWNER"
"test.domain#xxx01-aaab:ADMIN",
"test.domain#xxx01-aaab:OWNER"
// @formatter:on
);
noneOfTheseRbacRolesIsReturned(
result,
// @formatter:off
"rbac.global#global:ADMIN",
"test_customer#xxx:OWNER",
"test_package#yyy00:ADMIN",
"test_package#yyy00:OWNER",
"test_package#yyy00:TENANT"
"test.customer#xxx:OWNER",
"test.package#yyy00:ADMIN",
"test.package#yyy00:OWNER",
"test.package#yyy00:TENANT"
// @formatter:on
);
}
@Test
public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnRbacRole() {
context.define("customer-admin@xxx.example.com", "test_package#xxx00:ADMIN");
context.define("customer-admin@xxx.example.com", "test.package#xxx00:ADMIN");
final var result = rbacRoleRepository.findAll();
exactlyTheseRbacRolesAreReturned(
result,
"test_customer#xxx:TENANT",
"test_package#xxx00:ADMIN",
"test_package#xxx00:TENANT",
"test_domain#xxx00-aaaa:ADMIN",
"test_domain#xxx00-aaaa:OWNER",
"test_domain#xxx00-aaab:ADMIN",
"test_domain#xxx00-aaab:OWNER");
"test.customer#xxx:TENANT",
"test.package#xxx00:ADMIN",
"test.package#xxx00:TENANT",
"test.domain#xxx00-aaaa:ADMIN",
"test.domain#xxx00-aaaa:OWNER",
"test.domain#xxx00-aaab:ADMIN",
"test.domain#xxx00-aaab:OWNER");
}
@Test
@ -157,10 +157,10 @@ class RbacRoleRepositoryIntegrationTest {
void customerAdmin_withoutAssumedRole_canFindItsOwnRolesByName() {
context.define("customer-admin@xxx.example.com");
final var result = rbacRoleRepository.findByRoleName("test_customer#xxx:ADMIN");
final var result = rbacRoleRepository.findByRoleName("test.customer#xxx:ADMIN");
assertThat(result).isNotNull();
assertThat(result.getObjectTable()).isEqualTo("test_customer");
assertThat(result.getObjectTable()).isEqualTo("test.customer");
assertThat(result.getObjectIdName()).isEqualTo("xxx");
assertThat(result.getRoleType()).isEqualTo(RbacRoleType.ADMIN);
}
@ -169,7 +169,7 @@ class RbacRoleRepositoryIntegrationTest {
void customerAdmin_withoutAssumedRole_canNotFindAlienRolesByName() {
context.define("customer-admin@xxx.example.com");
final var result = rbacRoleRepository.findByRoleName("test_customer#bbb:ADMIN");
final var result = rbacRoleRepository.findByRoleName("test.customer#bbb:ADMIN");
assertThat(result).isNull();
}

View File

@ -5,8 +5,8 @@ import static java.util.UUID.randomUUID;
public class TestRbacRole {
public static final RbacRoleEntity hostmasterRole = rbacRole("rbac.global", "global", RbacRoleType.ADMIN);
static final RbacRoleEntity customerXxxOwner = rbacRole("test_customer", "xxx", RbacRoleType.OWNER);
static final RbacRoleEntity customerXxxAdmin = rbacRole("test_customer", "xxx", RbacRoleType.ADMIN);
static final RbacRoleEntity customerXxxOwner = rbacRole("test.customer", "xxx", RbacRoleType.OWNER);
static final RbacRoleEntity customerXxxAdmin = rbacRole("test.customer", "xxx", RbacRoleType.ADMIN);
static public RbacRoleEntity rbacRole(final String objectTable, final String objectIdName, final RbacRoleType roleType) {
return new RbacRoleEntity(randomUUID(), randomUUID(), objectTable, objectIdName, roleType, objectTable+'#'+objectIdName+':'+roleType);

View File

@ -100,7 +100,7 @@ class RbacSubjectControllerAcceptanceTest {
RestAssured
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#yyy:ADMIN")
.header("assumed-roles", "test.customer#yyy:ADMIN")
.port(port)
.when()
.get("http://localhost/api/rbac/subjects/" + givenUser.getUuid())
@ -201,7 +201,7 @@ class RbacSubjectControllerAcceptanceTest {
RestAssured
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#yyy:ADMIN")
.header("assumed-roles", "test.customer#yyy:ADMIN")
.port(port)
.when()
.get("http://localhost/api/rbac/subjects")
@ -275,12 +275,12 @@ class RbacSubjectControllerAcceptanceTest {
.contentType("application/json")
.body("", hasItem(
allOf(
hasEntry("roleName", "test_customer#yyy:TENANT"),
hasEntry("roleName", "test.customer#yyy:TENANT"),
hasEntry("op", "SELECT"))
))
.body("", hasItem(
allOf(
hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER"),
hasEntry("roleName", "test.domain#yyy00-aaaa:OWNER"),
hasEntry("op", "DELETE"))
))
// actual content tested in integration test, so this is enough for here:
@ -296,7 +296,7 @@ class RbacSubjectControllerAcceptanceTest {
RestAssured
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#yyy:ADMIN")
.header("assumed-roles", "test.customer#yyy:ADMIN")
.port(port)
.when()
.get("http://localhost/api/rbac/subjects/" + givenUser.getUuid() + "/permissions")
@ -305,12 +305,12 @@ class RbacSubjectControllerAcceptanceTest {
.contentType("application/json")
.body("", hasItem(
allOf(
hasEntry("roleName", "test_customer#yyy:TENANT"),
hasEntry("roleName", "test.customer#yyy:TENANT"),
hasEntry("op", "SELECT"))
))
.body("", hasItem(
allOf(
hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER"),
hasEntry("roleName", "test.domain#yyy00-aaaa:OWNER"),
hasEntry("op", "DELETE"))
))
// actual content tested in integration test, so this is enough for here:
@ -334,12 +334,12 @@ class RbacSubjectControllerAcceptanceTest {
.contentType("application/json")
.body("", hasItem(
allOf(
hasEntry("roleName", "test_customer#yyy:TENANT"),
hasEntry("roleName", "test.customer#yyy:TENANT"),
hasEntry("op", "SELECT"))
))
.body("", hasItem(
allOf(
hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER"),
hasEntry("roleName", "test.domain#yyy00-aaaa:OWNER"),
hasEntry("op", "DELETE"))
))
// actual content tested in integration test, so this is enough for here:

View File

@ -128,7 +128,7 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest {
@Test
public void globalAdmin_withAssumedCustomerAdminRole_canViewOnlyUsersHavingRolesInThatCustomersRealm() {
given:
context("superuser-alex@hostsharing.net", "test_customer#xxx:ADMIN");
context("superuser-alex@hostsharing.net", "test.customer#xxx:ADMIN");
// when
final var result = rbacSubjectRepository.findByOptionalNameLike(null);
@ -159,7 +159,7 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest {
@Test
public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyUsersHavingRolesInThatPackage() {
context("customer-admin@xxx.example.com", "test_package#xxx00:ADMIN");
context("customer-admin@xxx.example.com", "test.package#xxx00:ADMIN");
final var result = rbacSubjectRepository.findByOptionalNameLike(null);
@ -182,47 +182,47 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest {
private static final String[] ALL_USER_PERMISSIONS = Array.of(
// @formatter:off
"test_customer#xxx:ADMIN -> test_customer#xxx: SELECT",
"test_customer#xxx:OWNER -> test_customer#xxx: DELETE",
"test_customer#xxx:TENANT -> test_customer#xxx: SELECT",
"test_customer#xxx:ADMIN -> test_customer#xxx: INSERT:test_package",
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
"test_package#xxx00:TENANT -> test_package#xxx00: SELECT",
"test_package#xxx01:ADMIN -> test_package#xxx01: INSERT:test_domain",
"test_package#xxx01:ADMIN -> test_package#xxx01: INSERT:test_domain",
"test_package#xxx01:TENANT -> test_package#xxx01: SELECT",
"test_package#xxx02:ADMIN -> test_package#xxx02: INSERT:test_domain",
"test_package#xxx02:ADMIN -> test_package#xxx02: INSERT:test_domain",
"test_package#xxx02:TENANT -> test_package#xxx02: SELECT",
"test.customer#xxx:ADMIN -> test.customer#xxx: SELECT",
"test.customer#xxx:OWNER -> test.customer#xxx: DELETE",
"test.customer#xxx:TENANT -> test.customer#xxx: SELECT",
"test.customer#xxx:ADMIN -> test.customer#xxx: INSERT:test.package",
"test.package#xxx00:ADMIN -> test.package#xxx00: INSERT:test.domain",
"test.package#xxx00:ADMIN -> test.package#xxx00: INSERT:test.domain",
"test.package#xxx00:TENANT -> test.package#xxx00: SELECT",
"test.package#xxx01:ADMIN -> test.package#xxx01: INSERT:test.domain",
"test.package#xxx01:ADMIN -> test.package#xxx01: INSERT:test.domain",
"test.package#xxx01:TENANT -> test.package#xxx01: SELECT",
"test.package#xxx02:ADMIN -> test.package#xxx02: INSERT:test.domain",
"test.package#xxx02:ADMIN -> test.package#xxx02: INSERT:test.domain",
"test.package#xxx02:TENANT -> test.package#xxx02: SELECT",
"test_customer#yyy:ADMIN -> test_customer#yyy: SELECT",
"test_customer#yyy:OWNER -> test_customer#yyy: DELETE",
"test_customer#yyy:TENANT -> test_customer#yyy: SELECT",
"test_customer#yyy:ADMIN -> test_customer#yyy: INSERT:test_package",
"test_package#yyy00:ADMIN -> test_package#yyy00: INSERT:test_domain",
"test_package#yyy00:ADMIN -> test_package#yyy00: INSERT:test_domain",
"test_package#yyy00:TENANT -> test_package#yyy00: SELECT",
"test_package#yyy01:ADMIN -> test_package#yyy01: INSERT:test_domain",
"test_package#yyy01:ADMIN -> test_package#yyy01: INSERT:test_domain",
"test_package#yyy01:TENANT -> test_package#yyy01: SELECT",
"test_package#yyy02:ADMIN -> test_package#yyy02: INSERT:test_domain",
"test_package#yyy02:ADMIN -> test_package#yyy02: INSERT:test_domain",
"test_package#yyy02:TENANT -> test_package#yyy02: SELECT",
"test.customer#yyy:ADMIN -> test.customer#yyy: SELECT",
"test.customer#yyy:OWNER -> test.customer#yyy: DELETE",
"test.customer#yyy:TENANT -> test.customer#yyy: SELECT",
"test.customer#yyy:ADMIN -> test.customer#yyy: INSERT:test.package",
"test.package#yyy00:ADMIN -> test.package#yyy00: INSERT:test.domain",
"test.package#yyy00:ADMIN -> test.package#yyy00: INSERT:test.domain",
"test.package#yyy00:TENANT -> test.package#yyy00: SELECT",
"test.package#yyy01:ADMIN -> test.package#yyy01: INSERT:test.domain",
"test.package#yyy01:ADMIN -> test.package#yyy01: INSERT:test.domain",
"test.package#yyy01:TENANT -> test.package#yyy01: SELECT",
"test.package#yyy02:ADMIN -> test.package#yyy02: INSERT:test.domain",
"test.package#yyy02:ADMIN -> test.package#yyy02: INSERT:test.domain",
"test.package#yyy02:TENANT -> test.package#yyy02: SELECT",
"test_customer#zzz:ADMIN -> test_customer#zzz: SELECT",
"test_customer#zzz:OWNER -> test_customer#zzz: DELETE",
"test_customer#zzz:TENANT -> test_customer#zzz: SELECT",
"test_customer#zzz:ADMIN -> test_customer#zzz: INSERT:test_package",
"test_package#zzz00:ADMIN -> test_package#zzz00: INSERT:test_domain",
"test_package#zzz00:ADMIN -> test_package#zzz00: INSERT:test_domain",
"test_package#zzz00:TENANT -> test_package#zzz00: SELECT",
"test_package#zzz01:ADMIN -> test_package#zzz01: INSERT:test_domain",
"test_package#zzz01:ADMIN -> test_package#zzz01: INSERT:test_domain",
"test_package#zzz01:TENANT -> test_package#zzz01: SELECT",
"test_package#zzz02:ADMIN -> test_package#zzz02: INSERT:test_domain",
"test_package#zzz02:ADMIN -> test_package#zzz02: INSERT:test_domain",
"test_package#zzz02:TENANT -> test_package#zzz02: SELECT"
"test.customer#zzz:ADMIN -> test.customer#zzz: SELECT",
"test.customer#zzz:OWNER -> test.customer#zzz: DELETE",
"test.customer#zzz:TENANT -> test.customer#zzz: SELECT",
"test.customer#zzz:ADMIN -> test.customer#zzz: INSERT:test.package",
"test.package#zzz00:ADMIN -> test.package#zzz00: INSERT:test.domain",
"test.package#zzz00:ADMIN -> test.package#zzz00: INSERT:test.domain",
"test.package#zzz00:TENANT -> test.package#zzz00: SELECT",
"test.package#zzz01:ADMIN -> test.package#zzz01: INSERT:test.domain",
"test.package#zzz01:ADMIN -> test.package#zzz01: INSERT:test.domain",
"test.package#zzz01:TENANT -> test.package#zzz01: SELECT",
"test.package#zzz02:ADMIN -> test.package#zzz02: INSERT:test.domain",
"test.package#zzz02:ADMIN -> test.package#zzz02: INSERT:test.domain",
"test.package#zzz02:TENANT -> test.package#zzz02: SELECT"
// @formatter:on
);
@ -252,32 +252,32 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest {
allTheseRbacPermissionsAreReturned(
result,
// @formatter:off
"test_customer#xxx:ADMIN -> test_customer#xxx: INSERT:test_package",
"test_customer#xxx:ADMIN -> test_customer#xxx: SELECT",
"test_customer#xxx:TENANT -> test_customer#xxx: SELECT",
"test.customer#xxx:ADMIN -> test.customer#xxx: INSERT:test.package",
"test.customer#xxx:ADMIN -> test.customer#xxx: SELECT",
"test.customer#xxx:TENANT -> test.customer#xxx: SELECT",
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
"test_package#xxx00:TENANT -> test_package#xxx00: SELECT",
"test_domain#xxx00-aaaa:OWNER -> test_domain#xxx00-aaaa: DELETE",
"test.package#xxx00:ADMIN -> test.package#xxx00: INSERT:test.domain",
"test.package#xxx00:ADMIN -> test.package#xxx00: INSERT:test.domain",
"test.package#xxx00:TENANT -> test.package#xxx00: SELECT",
"test.domain#xxx00-aaaa:OWNER -> test.domain#xxx00-aaaa: DELETE",
"test_package#xxx01:ADMIN -> test_package#xxx01: INSERT:test_domain",
"test_package#xxx01:ADMIN -> test_package#xxx01: INSERT:test_domain",
"test_package#xxx01:TENANT -> test_package#xxx01: SELECT",
"test_domain#xxx01-aaaa:OWNER -> test_domain#xxx01-aaaa: DELETE",
"test.package#xxx01:ADMIN -> test.package#xxx01: INSERT:test.domain",
"test.package#xxx01:ADMIN -> test.package#xxx01: INSERT:test.domain",
"test.package#xxx01:TENANT -> test.package#xxx01: SELECT",
"test.domain#xxx01-aaaa:OWNER -> test.domain#xxx01-aaaa: DELETE",
"test_package#xxx02:ADMIN -> test_package#xxx02: INSERT:test_domain",
"test_package#xxx02:ADMIN -> test_package#xxx02: INSERT:test_domain",
"test_package#xxx02:TENANT -> test_package#xxx02: SELECT",
"test_domain#xxx02-aaaa:OWNER -> test_domain#xxx02-aaaa: DELETE"
"test.package#xxx02:ADMIN -> test.package#xxx02: INSERT:test.domain",
"test.package#xxx02:ADMIN -> test.package#xxx02: INSERT:test.domain",
"test.package#xxx02:TENANT -> test.package#xxx02: SELECT",
"test.domain#xxx02-aaaa:OWNER -> test.domain#xxx02-aaaa: DELETE"
// @formatter:on
);
noneOfTheseRbacPermissionsAreReturned(
result,
// @formatter:off
"test_customer#yyy:ADMIN -> test_customer#yyy: INSERT:test_package",
"test_customer#yyy:ADMIN -> test_customer#yyy: SELECT",
"test_customer#yyy:TENANT -> test_customer#yyy: SELECT"
"test.customer#yyy:ADMIN -> test.customer#yyy: INSERT:test.package",
"test.customer#yyy:ADMIN -> test.customer#yyy: SELECT",
"test.customer#yyy:TENANT -> test.customer#yyy: SELECT"
// @formatter:on
);
}
@ -312,26 +312,26 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest {
allTheseRbacPermissionsAreReturned(
result,
// @formatter:off
"test_customer#xxx:TENANT -> test_customer#xxx: SELECT",
// "test_customer#xxx:ADMIN -> test_customer#xxx: view" - Not permissions through the customer admin!
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
"test_package#xxx00:TENANT -> test_package#xxx00: SELECT",
"test_domain#xxx00-aaaa:OWNER -> test_domain#xxx00-aaaa: DELETE",
"test_domain#xxx00-aaab:OWNER -> test_domain#xxx00-aaab: DELETE"
"test.customer#xxx:TENANT -> test.customer#xxx: SELECT",
// "test.customer#xxx:ADMIN -> test.customer#xxx: view" - Not permissions through the customer admin!
"test.package#xxx00:ADMIN -> test.package#xxx00: INSERT:test.domain",
"test.package#xxx00:ADMIN -> test.package#xxx00: INSERT:test.domain",
"test.package#xxx00:TENANT -> test.package#xxx00: SELECT",
"test.domain#xxx00-aaaa:OWNER -> test.domain#xxx00-aaaa: DELETE",
"test.domain#xxx00-aaab:OWNER -> test.domain#xxx00-aaab: DELETE"
// @formatter:on
);
noneOfTheseRbacPermissionsAreReturned(
result,
// @formatter:off
"test_customer#yyy:ADMIN -> test_customer#yyy: INSERT:test_package",
"test_customer#yyy:ADMIN -> test_customer#yyy: SELECT",
"test_customer#yyy:TENANT -> test_customer#yyy: SELECT",
"test_package#yyy00:ADMIN -> test_package#yyy00: INSERT:test_domain",
"test_package#yyy00:ADMIN -> test_package#yyy00: INSERT:test_domain",
"test_package#yyy00:TENANT -> test_package#yyy00: SELECT",
"test_domain#yyy00-aaaa:OWNER -> test_domain#yyy00-aaaa: DELETE",
"test_domain#yyy00-aaab:OWNER -> test_domain#yyy00-aaab: DELETE"
"test.customer#yyy:ADMIN -> test.customer#yyy: INSERT:test.package",
"test.customer#yyy:ADMIN -> test.customer#yyy: SELECT",
"test.customer#yyy:TENANT -> test.customer#yyy: SELECT",
"test.package#yyy00:ADMIN -> test.package#yyy00: INSERT:test.domain",
"test.package#yyy00:ADMIN -> test.package#yyy00: INSERT:test.domain",
"test.package#yyy00:TENANT -> test.package#yyy00: SELECT",
"test.domain#yyy00-aaaa:OWNER -> test.domain#yyy00-aaaa: DELETE",
"test.domain#yyy00-aaab:OWNER -> test.domain#yyy00-aaab: DELETE"
// @formatter:on
);
}
@ -360,26 +360,26 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest {
allTheseRbacPermissionsAreReturned(
result,
// @formatter:off
"test_customer#xxx:TENANT -> test_customer#xxx: SELECT",
// "test_customer#xxx:ADMIN -> test_customer#xxx: view" - Not permissions through the customer admin!
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
"test_package#xxx00:TENANT -> test_package#xxx00: SELECT"
"test.customer#xxx:TENANT -> test.customer#xxx: SELECT",
// "test.customer#xxx:ADMIN -> test.customer#xxx: view" - Not permissions through the customer admin!
"test.package#xxx00:ADMIN -> test.package#xxx00: INSERT:test.domain",
"test.package#xxx00:TENANT -> test.package#xxx00: SELECT"
// @formatter:on
);
noneOfTheseRbacPermissionsAreReturned(
result,
// @formatter:off
// no customer admin permissions
"test_customer#xxx:ADMIN -> test_customer#xxx: add-package",
"test.customer#xxx:ADMIN -> test.customer#xxx: add-package",
// no permissions on other customer's objects
"test_customer#yyy:ADMIN -> test_customer#yyy: add-package",
"test_customer#yyy:ADMIN -> test_customer#yyy: SELECT",
"test_customer#yyy:TENANT -> test_customer#yyy: SELECT",
"test_package#yyy00:ADMIN -> test_package#yyy00: INSERT:test_domain",
"test_package#yyy00:ADMIN -> test_package#yyy00: INSERT:test_domain",
"test_package#yyy00:TENANT -> test_package#yyy00: SELECT",
"test_domain#yyy00-aaaa:OWNER -> test_domain#yyy00-aaaa: DELETE",
"test_domain#yyy00-xxxb:OWNER -> test_domain#yyy00-xxxb: DELETE"
"test.customer#yyy:ADMIN -> test.customer#yyy: add-package",
"test.customer#yyy:ADMIN -> test.customer#yyy: SELECT",
"test.customer#yyy:TENANT -> test.customer#yyy: SELECT",
"test.package#yyy00:ADMIN -> test.package#yyy00: INSERT:test.domain",
"test.package#yyy00:ADMIN -> test.package#yyy00: INSERT:test.domain",
"test.package#yyy00:TENANT -> test.package#yyy00: SELECT",
"test.domain#yyy00-aaaa:OWNER -> test.domain#yyy00-aaaa: DELETE",
"test.domain#yyy00-xxxb:OWNER -> test.domain#yyy00-xxxb: DELETE"
// @formatter:on
);
}

View File

@ -89,7 +89,7 @@ class TestCustomerControllerAcceptanceTest {
RestAssured // @formatter:off
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#yyy:ADMIN")
.header("assumed-roles", "test.customer#yyy:ADMIN")
.port(port)
.when()
.get("http://localhost/api/test/customers")
@ -148,7 +148,7 @@ class TestCustomerControllerAcceptanceTest {
// finally, the new customer can be viewed by its own admin
final var newSubjectUuid = UUID.fromString(
location.substring(location.lastIndexOf('/') + 1));
context.define("superuser-fran@hostsharing.net", "test_customer#uuu:ADMIN");
context.define("superuser-fran@hostsharing.net", "test.customer#uuu:ADMIN");
assertThat(testCustomerRepository.findByUuid(newSubjectUuid))
.hasValueSatisfying(c -> assertThat(c.getPrefix()).isEqualTo("uuu"));
}
@ -159,7 +159,7 @@ class TestCustomerControllerAcceptanceTest {
RestAssured // @formatter:off
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#xxx:ADMIN")
.header("assumed-roles", "test.customer#xxx:ADMIN")
.contentType(ContentType.JSON)
.body("""
{
@ -175,8 +175,8 @@ class TestCustomerControllerAcceptanceTest {
.statusCode(403)
.contentType(ContentType.JSON)
.statusCode(403)
.body("message", containsString("ERROR: [403] insert into test_customer "))
.body("message", containsString(" not allowed for current subjects {test_customer#xxx:ADMIN}"));
.body("message", containsString("ERROR: [403] insert into test.customer "))
.body("message", containsString(" not allowed for current subjects {test.customer#xxx:ADMIN}"));
// @formatter:on
// finally, the new customer was not created
@ -205,7 +205,7 @@ class TestCustomerControllerAcceptanceTest {
.statusCode(403)
.contentType(ContentType.JSON)
.statusCode(403)
.body("message", containsString("ERROR: [403] insert into test_customer "))
.body("message", containsString("ERROR: [403] insert into test.customer "))
.body("message", containsString(" not allowed for current subjects"));
// @formatter:on

View File

@ -54,7 +54,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
@Test
public void globalAdmin_withAssumedCustomerRole_cannotCreateNewCustomer() {
// given
context("superuser-alex@hostsharing.net", "test_customer#xxx:ADMIN");
context("superuser-alex@hostsharing.net", "test.customer#xxx:ADMIN");
// when
final var result = attempt(em, () -> {
@ -66,8 +66,8 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
// then
result.assertExceptionWithRootCauseMessage(
PersistenceException.class,
"ERROR: [403] insert into test_customer ",
"not allowed for current subjects {test_customer#xxx:ADMIN}");
"ERROR: [403] insert into test.customer ",
"not allowed for current subjects {test.customer#xxx:ADMIN}");
}
@Test
@ -85,7 +85,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
// then
result.assertExceptionWithRootCauseMessage(
PersistenceException.class,
"ERROR: [403] insert into test_customer ",
"ERROR: [403] insert into test.customer ",
" not allowed for current subjects {customer-admin@xxx.example.com}");
}
@ -114,7 +114,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
@Test
public void globalAdmin_withAssumedCustomerOwnerRole_canViewExactlyThatCustomer() {
given:
context("superuser-alex@hostsharing.net", "test_customer#yyy:OWNER");
context("superuser-alex@hostsharing.net", "test.customer#yyy:OWNER");
// when
final var result = testCustomerRepository.findCustomerByOptionalPrefixLike(null);
@ -139,7 +139,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnCustomer() {
context("customer-admin@xxx.example.com");
context("customer-admin@xxx.example.com", "test_package#xxx00:ADMIN");
context("customer-admin@xxx.example.com", "test.package#xxx00:ADMIN");
final var result = testCustomerRepository.findCustomerByOptionalPrefixLike(null);

View File

@ -44,7 +44,7 @@ class TestPackageControllerAcceptanceTest {
RestAssured
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#xxx:ADMIN")
.header("assumed-roles", "test.customer#xxx:ADMIN")
.port(port)
.when()
.get("http://localhost/api/test/packages")
@ -66,7 +66,7 @@ class TestPackageControllerAcceptanceTest {
RestAssured
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#xxx:ADMIN")
.header("assumed-roles", "test.customer#xxx:ADMIN")
.port(port)
.when()
.get("http://localhost/api/test/packages?name=xxx01")
@ -95,7 +95,7 @@ class TestPackageControllerAcceptanceTest {
RestAssured
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#xxx:ADMIN")
.header("assumed-roles", "test.customer#xxx:ADMIN")
.contentType(ContentType.JSON)
.body(format("""
{
@ -126,7 +126,7 @@ class TestPackageControllerAcceptanceTest {
RestAssured
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#xxx:ADMIN")
.header("assumed-roles", "test.customer#xxx:ADMIN")
.contentType(ContentType.JSON)
.body("""
{
@ -156,7 +156,7 @@ class TestPackageControllerAcceptanceTest {
RestAssured
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#xxx:ADMIN")
.header("assumed-roles", "test.customer#xxx:ADMIN")
.contentType(ContentType.JSON)
.body("{}")
.port(port)
@ -176,7 +176,7 @@ class TestPackageControllerAcceptanceTest {
return UUID.fromString(RestAssured
.given()
.header("current-subject", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#xxx:ADMIN")
.header("assumed-roles", "test.customer#xxx:ADMIN")
.port(port)
.when()
.get("http://localhost/api/test/packages?name={packageName}", packageName)
@ -188,7 +188,7 @@ class TestPackageControllerAcceptanceTest {
}
String getDescriptionOfPackage(final String packageName) {
context.define("superuser-alex@hostsharing.net","test_customer#xxx:ADMIN");
context.define("superuser-alex@hostsharing.net","test.customer#xxx:ADMIN");
return testPackageRepository.findAllByOptionalNameLike(packageName).get(0).getDescription();
}
}

View File

@ -76,7 +76,7 @@ class TestPackageRepositoryIntegrationTest extends ContextBasedTest {
@Test
public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnPackages() {
context.define("customer-admin@xxx.example.com", "test_package#xxx00:ADMIN");
context.define("customer-admin@xxx.example.com", "test.package#xxx00:ADMIN");
final var result = testPackageRepository.findAllByOptionalNameLike(null);
@ -90,17 +90,17 @@ class TestPackageRepositoryIntegrationTest extends ContextBasedTest {
@Test
public void supportsOptimisticLocking() {
// given
globalAdminWithAssumedRole("test_package#xxx00:ADMIN");
globalAdminWithAssumedRole("test.package#xxx00:ADMIN");
final var pac = testPackageRepository.findAllByOptionalNameLike("%").get(0);
// when
final var result1 = jpaAttempt.transacted(() -> {
globalAdminWithAssumedRole("test_package#xxx00:OWNER");
globalAdminWithAssumedRole("test.package#xxx00:OWNER");
pac.setDescription("description set by thread 1");
testPackageRepository.save(pac);
});
final var result2 = jpaAttempt.transacted(() -> {
globalAdminWithAssumedRole("test_package#xxx00:OWNER");
globalAdminWithAssumedRole("test.package#xxx00:OWNER");
pac.setDescription("description set by thread 2");
testPackageRepository.save(pac);
sleep(1500);