Compare commits

..

2 Commits

Author SHA1 Message Date
Michael Hoennig
aaa3bf8935 use schema rbactest and amend generator code for schemas 2024-09-16 15:57:09 +02:00
Michael Hoennig
64163a4d4c introduce-separate-database-schemas-base-and-rbac 2024-09-16 10:57:07 +02:00
68 changed files with 988 additions and 823 deletions

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: # the following command should return a JSON array with just all packages visible for the admin of the customer yyy:
curl \ 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: rbactest.customer#yyy:ADMIN' \
http://localhost:8080/api/test/packages http://localhost:8080/api/test/packages
# add a new customer # add a new customer

View File

@ -38,7 +38,7 @@ In this solution, the database ignores row level visibility and returns all rows
Very flexible access, programmatic, rules could be implemented. Very flexible access, programmatic, rules could be implemented.
The role-hierarchy and permissions for current subjects (e.g. logged-in users) could be cached in the backend. The role-hierarchy and permissions for currently logged-in sujects could be cached in the backend.
The access logic can be tested in pure Java unit tests. The access logic can be tested in pure Java unit tests.

View File

@ -3,14 +3,14 @@
-- -------------------------------------------------------- -- --------------------------------------------------------
select rbac.isGranted(rbac.findRoleId('administrators'), rbac.findRoleId('test.package#aaa00:OWNER')); select rbac.isGranted(rbac.findRoleId('administrators'), rbac.findRoleId('rbactest.package#aaa00:OWNER'));
select rbac.isGranted(rbac.findRoleId('test.package#aaa00:OWNER'), rbac.findRoleId('administrators')); select rbac.isGranted(rbac.findRoleId('rbactest.package#aaa00:OWNER'), rbac.findRoleId('administrators'));
-- call rbac.grantRoleToRole(findRoleId('test.package#aaa00:OWNER'), findRoleId('administrators')); -- call rbac.grantRoleToRole(findRoleId('rbactest.package#aaa00:OWNER'), findRoleId('administrators'));
-- call rbac.grantRoleToRole(findRoleId('administrators'), findRoleId('test.package#aaa00:OWNER')); -- call rbac.grantRoleToRole(findRoleId('administrators'), findRoleId('rbactest.package#aaa00:OWNER'));
select count(*) select count(*)
FROM rbac.queryAllPermissionsOfSubjectIdForObjectUuids(rbac.findRbacSubject('superuser-fran@hostsharing.net'), FROM rbac.queryAllPermissionsOfSubjectIdForObjectUuids(rbac.findRbacSubject('superuser-fran@hostsharing.net'),
ARRAY(select uuid from test.customer where reference < 1100000)); ARRAY(select uuid from rbactest.customer where reference < 1100000));
select count(*) select count(*)
FROM rbac.queryAllPermissionsOfSubjectId(findRbacSubject('superuser-fran@hostsharing.net')); FROM rbac.queryAllPermissionsOfSubjectId(findRbacSubject('superuser-fran@hostsharing.net'));
select * select *

View File

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

View File

@ -100,7 +100,7 @@ public class InsertTriggerGenerator {
/** /**
Grants ${rawSubTable} INSERT permission to specified role of new ${rawSuperTable} rows. Grants ${rawSubTable} INSERT permission to specified role of new ${rawSuperTable} rows.
*/ */
create or replace function ${rawSuperTableSchemaName}new_${rawSubTableShortName}_grants_insert_to_${rawSuperTableShortName}_tf() create or replace function ${rawSubTableSchemaPrefix}new_${rawSubTableShortName}_grants_insert_to_${rawSuperTableShortName}_tf()
returns trigger returns trigger
language plpgsql language plpgsql
strict as $$ strict as $$
@ -114,10 +114,10 @@ public class InsertTriggerGenerator {
end; $$; end; $$;
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist -- 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} after insert on ${rawSuperTableWithSchema}
for each row for each row
execute procedure ${rawSuperTableSchemaName}new_${rawSubTableShortName}_grants_insert_to_${rawSuperTableShortName}_tf(); execute procedure ${rawSubTableSchemaPrefix}new_${rawSubTableShortName}_grants_insert_to_${rawSuperTableShortName}_tf();
""", """,
with("ifConditionThen", g.getSuperRoleDef().getEntityAlias().isCaseDependent() with("ifConditionThen", g.getSuperRoleDef().getEntityAlias().isCaseDependent()
// TODO.impl: .type needs to be dynamically generated // TODO.impl: .type needs to be dynamically generated
@ -130,8 +130,9 @@ public class InsertTriggerGenerator {
with("rawSuperTableWithSchema", g.getSuperRoleDef().getEntityAlias().getRawTableNameWithSchema()), with("rawSuperTableWithSchema", g.getSuperRoleDef().getEntityAlias().getRawTableNameWithSchema()),
with("rawSuperTableShortName", g.getSuperRoleDef().getEntityAlias().getRawTableShortName()), with("rawSuperTableShortName", g.getSuperRoleDef().getEntityAlias().getRawTableShortName()),
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()), with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
with("rawSuperTableSchemaName", g.getSuperRoleDef().getEntityAlias().getRawTableSchemaPrefix()),
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableNameWithSchema()), with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableNameWithSchema()),
with("rawSubTableSchemaPrefix", g.getPermDef().getEntityAlias().getRawTableSchemaPrefix()),
with("rawSubTableName", g.getPermDef().getEntityAlias().getRawTableName()),
with("rawSubTableShortName", g.getPermDef().getEntityAlias().getRawTableShortName())); with("rawSubTableShortName", g.getPermDef().getEntityAlias().getRawTableShortName()));
}); });
@ -154,15 +155,16 @@ public class InsertTriggerGenerator {
returns trigger returns trigger
language plpgsql as $$ language plpgsql as $$
begin 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; $$; end; $$;
create trigger ${rawSubTable}_insert_permission_check_tg create trigger ${rawSubTable}_insert_permission_check_tg
before insert on ${rawSubTable} before insert on ${rawSubTable}
for each row 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("--//"); plPgSql.writeLn("--//");
} }
@ -183,7 +185,7 @@ public class InsertTriggerGenerator {
private void generateInsertPermissionsCheckHeader(final StringWriter plPgSql) { private void generateInsertPermissionsCheckHeader(final StringWriter plPgSql) {
plPgSql.writeLn(""" plPgSql.writeLn("""
-- ============================================================================ -- ============================================================================
--changeset InsertTriggerGenerator:${rawSubTable}-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--// --changeset InsertTriggerGenerator:${liquibaseTagPrefix}-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/** /**
@ -196,6 +198,7 @@ public class InsertTriggerGenerator {
superObjectUuid uuid; superObjectUuid uuid;
begin begin
""", """,
with("liquibaseTagPrefix", liquibaseTagPrefix),
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema())); with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
plPgSql.chopEmptyLines(); plPgSql.chopEmptyLines();
} }
@ -258,17 +261,18 @@ public class InsertTriggerGenerator {
private void generateInsertPermissionsChecksFooter(final StringWriter plPgSql) { private void generateInsertPermissionsChecksFooter(final StringWriter plPgSql) {
plPgSql.writeLn(); plPgSql.writeLn();
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(); NEW, base.currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end; $$; end; $$;
create trigger ${rawSubTable}_insert_permission_check_tg create trigger ${rawSubTable}_insert_permission_check_tg
before insert on ${rawSubTable} before insert on ${rawSubTableWithSchema}
for each row 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) { private String toStringList(final Set<RbacView.CaseDef> cases) {

View File

@ -90,11 +90,11 @@ public class RbacView {
* @param <E> * @param <E>
* a JPA entity class extending RbacObject * 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); 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); rootEntityAlias = new EntityAlias(alias, entityClass);
entityAliases.put(alias, rootEntityAlias); entityAliases.put(alias, rootEntityAlias);
new RbacSubjectReference(CREATOR); new RbacSubjectReference(CREATOR);
@ -121,7 +121,7 @@ public class RbacView {
* <p>An identity view is a view which maps an objectUuid to an idName. * <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 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 '_'. * 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 rbactest.customer#abc:ADMIN - here 'abc' is the idName.
* The idName not necessarily unique in a table, but it should be avoided. * The idName not necessarily unique in a table, but it should be avoided.
* </p> * </p>
* *
@ -287,9 +287,9 @@ public class RbacView {
* @param <EC> * @param <EC>
* a JPA entity class extending RbacObject * a JPA entity class extending RbacObject
*/ */
public <EC extends BaseEntity> RbacView importRootEntityAliasProxy( public <EC extends BaseEntity<?>> RbacView importRootEntityAliasProxy(
final String aliasName, final String aliasName,
final Class<? extends BaseEntity> entityClass, final Class<? extends BaseEntity<?>> entityClass,
final ColumnValue forCase, final ColumnValue forCase,
final SQL fetchSql, final SQL fetchSql,
final Column dependsOnColum) { final Column dependsOnColum) {
@ -313,7 +313,7 @@ public class RbacView {
* a JPA entity class extending RbacObject * a JPA entity class extending RbacObject
*/ */
public RbacView importSubEntityAlias( 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) { final SQL fetchSql, final Column dependsOnColum) {
importEntityAliasImpl(aliasName, entityClass, usingDefaultCase(), fetchSql, dependsOnColum, true, NOT_NULL); importEntityAliasImpl(aliasName, entityClass, usingDefaultCase(), fetchSql, dependsOnColum, true, NOT_NULL);
return this; return this;
@ -350,14 +350,14 @@ public class RbacView {
* a JPA entity class extending RbacObject * a JPA entity class extending RbacObject
*/ */
public RbacView importEntityAlias( 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) { final Column dependsOnColum, final SQL fetchSql, final Nullable nullable) {
importEntityAliasImpl(aliasName, entityClass, usingCase, fetchSql, dependsOnColum, false, nullable); importEntityAliasImpl(aliasName, entityClass, usingCase, fetchSql, dependsOnColum, false, nullable);
return this; return this;
} }
private EntityAlias importEntityAliasImpl( 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 SQL fetchSql, final Column dependsOnColum, boolean asSubEntity, final Nullable nullable) {
final var entityAlias = ofNullable(entityAliases.get(aliasName)) final var entityAlias = ofNullable(entityAliases.get(aliasName))
@ -911,13 +911,13 @@ public class RbacView {
return distinctGrantDef; 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) { public EntityAlias(final String aliasName) {
this(aliasName, null, null, null, null, false, null); 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); this(aliasName, entityClass, null, null, null, false, null);
} }
@ -964,7 +964,7 @@ public class RbacView {
if ( aliasName.equals("rbac.global")) { if ( aliasName.equals("rbac.global")) {
return "rbac.global"; // TODO: maybe we should introduce a GlobalEntity class? return "rbac.global"; // TODO: maybe we should introduce a GlobalEntity class?
} }
return withoutRvSuffix(entityClass.getAnnotation(Table.class).name()); return qualifiedRealTableName(entityClass);
} }
String getRawTableSchemaPrefix() { String getRawTableSchemaPrefix() {
@ -1010,8 +1010,12 @@ public class RbacView {
} }
} }
public static String withoutRvSuffix(final String tableName) { public static String qualifiedRealTableName(final Class<? extends BaseEntity<?>> entityClass) {
return tableName.substring(0, tableName.length() - "_rv".length()); 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 { public enum Role {

View File

@ -17,7 +17,7 @@ public class RbacViewPostgresGenerator {
public RbacViewPostgresGenerator(final RbacView forRbacDef) { public RbacViewPostgresGenerator(final RbacView forRbacDef) {
rbacDef = forRbacDef; rbacDef = forRbacDef;
liqibaseTagPrefix = rbacDef.getRootEntityAlias().getRawTableNameWithSchema().replace("_", "-"); liqibaseTagPrefix = rbacDef.getRootEntityAlias().getRawTableNameWithSchema().replace("_", "-").replace(".", "-");
plPgSql.writeLn(""" plPgSql.writeLn("""
--liquibase formatted sql --liquibase formatted sql
-- This code generated was by ${generator}, do not amend manually. -- This code generated was by ${generator}, do not amend manually.

View File

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

View File

@ -79,10 +79,10 @@ public class RbacGrantsDiagramService {
return; return;
} }
if ( !g.getDescendantIdName().startsWith("role:rbac.global")) { if ( !g.getDescendantIdName().startsWith("role:rbac.global")) {
if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(":test_")) { if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(":rbactest.")) {
return; return;
} }
if (!includes.contains(NON_TEST_ENTITIES) && !g.getDescendantIdName().contains(":test_")) { if (!includes.contains(NON_TEST_ENTITIES) && !g.getDescendantIdName().contains(":rbactest.")) {
return; return;
} }
} }

View File

@ -20,7 +20,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor; import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity @Entity
@Table(name = "test_customer_rv") @Table(schema = "rbactest", name = "customer_rv")
@Getter @Getter
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@ -62,6 +62,6 @@ public class TestCustomerEntity implements BaseEntity<TestCustomerEntity> {
} }
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
rbac().generateWithBaseFileName("2-test/201-test-customer/2013-test-customer-rbac"); rbac().generateWithBaseFileName("2-rbactest/201-rbactest-customer/2013-rbactest-customer-rbac");
} }
} }

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; import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity @Entity
@Table(name = "test_domain_rv") @Table(schema = "rbactest", name = "domain_rv")
@Getter @Getter
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@ -68,6 +68,6 @@ public class TestDomainEntity implements BaseEntity<TestDomainEntity> {
} }
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
rbac().generateWithBaseFileName("2-test/203-test-domain/2033-test-domain-rbac"); rbac().generateWithBaseFileName("2-rbactest/203-rbactest-domain/2033-rbactest-domain-rbac");
} }
} }

View File

@ -22,7 +22,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor; import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity @Entity
@Table(name = "test_package_rv") @Table(schema = "rbactest", name = "package_rv")
@Getter @Getter
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@ -69,6 +69,6 @@ public class TestPackageEntity implements BaseEntity<TestPackageEntity> {
} }
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
rbac().generateWithBaseFileName("2-test/202-test-package/2023-test-package-rbac"); rbac().generateWithBaseFileName("2-rbactest/202-rbactest-package/2023-rbactest-package-rbac");
} }
} }

View File

@ -4,5 +4,16 @@
-- ============================================================================ -- ============================================================================
--changeset michael.hoennig:base-SCHEMA endDelimiter:--// --changeset michael.hoennig:base-SCHEMA endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
-- FIXME: remove this block
do $$
declare
changesetCount int;
begin
changesetCount := (select count(*) from databasechangelog);
assert changesetCount = 0, 'total changesets executed: ' || changesetCount;
end;
$$;
CREATE SCHEMA base; CREATE SCHEMA base;
--// --//

View File

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

View File

@ -127,6 +127,7 @@ begin
end; $$; end; $$;
--// --//
-- ============================================================================ -- ============================================================================
--changeset michael.hoennig:context-base.ASSUMED-ROLES endDelimiter:--// --changeset michael.hoennig:context-base.ASSUMED-ROLES endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------

View File

@ -0,0 +1,18 @@
--liquibase formatted sql
-- ============================================================================
--changeset michael.hoennig:base-COMBINE-TABLE-SCHEMA-AND-NAME 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 declare
curTask text; curTask text;
curTxId xid8; curTxId xid8;
tableSchemaAndName text;
begin begin
curTask := base.currentTask(); curTask := base.currentTask();
curTxId := pg_current_xact_id(); curTxId := pg_current_xact_id();
tableSchemaAndName := base.combine_table_schema_and_name(tg_table_schema, tg_table_name);
insert insert
into base.tx_context (txId, txTimestamp, currentSubject, assumedRoles, currentTask, currentRequest) into base.tx_context (txId, txTimestamp, currentSubject, assumedRoles, currentTask, currentRequest)
@ -90,20 +92,20 @@ begin
case tg_op case tg_op
when 'INSERT' then insert when 'INSERT' then insert
into base.tx_journal into base.tx_journal
values (curTxId, values (curTxId, tableSchemaAndName,
tg_table_name, new.uuid, tg_op::base.tx_operation, new.uuid, tg_op::base.tx_operation,
to_jsonb(new)); to_jsonb(new));
when 'UPDATE' then insert when 'UPDATE' then insert
into base.tx_journal into base.tx_journal
values (curTxId, values (curTxId, tableSchemaAndName,
tg_table_name, old.uuid, tg_op::base.tx_operation, old.uuid, tg_op::base.tx_operation,
base.jsonb_changes_delta(to_jsonb(old), to_jsonb(new))); base.jsonb_changes_delta(to_jsonb(old), to_jsonb(new)));
when 'DELETE' then insert when 'DELETE' then insert
into base.tx_journal into base.tx_journal
values (curTxId, values (curTxId,tableSchemaAndName,
tg_table_name, old.uuid, 'DELETE'::base.tx_operation, old.uuid, 'DELETE'::base.tx_operation,
null::jsonb); 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; end case;
return null; return null;
end; $$; end; $$;

View File

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

View File

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

View File

@ -20,7 +20,7 @@ begin
return currentSubjectOrAssumedRolesUuids[1]; return currentSubjectOrAssumedRolesUuids[1];
end; $$; end; $$;
create or replace procedure rbac.grantRoleToSubjectUnchecked(grantedByRoleUuid uuid, grantedRoleUuid uuid, subjectUuid uuid, doAssume boolean = true) create or replace procedure rbac.grantRoleToUserUnchecked(grantedByRoleUuid uuid, grantedRoleUuid uuid, subjectUuid uuid, doAssume boolean = true)
language plpgsql as $$ language plpgsql as $$
begin begin
perform rbac.assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'rbac.role'); perform rbac.assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'rbac.role');

View File

@ -57,7 +57,7 @@ begin
end if; end if;
foreach subjectUuid in array subjectUuids foreach subjectUuid in array subjectUuids
loop loop
call rbac.grantRoleToSubjectUnchecked(userGrantsByRoleUuid, roleUuid, subjectUuid); call rbac.grantRoleToUserUnchecked(userGrantsByRoleUuid, roleUuid, subjectUuid);
end loop; end loop;
end if; end if;

View File

@ -8,26 +8,40 @@
create or replace procedure rbac.generateRelatedRbacObject(targetTable varchar) create or replace procedure rbac.generateRelatedRbacObject(targetTable varchar)
language plpgsql as $$ language plpgsql as $$
declare declare
targetTableName text;
targetSchemaPrefix text;
createInsertTriggerSQL text; createInsertTriggerSQL text;
createDeleteTriggerSQL text; createDeleteTriggerSQL text;
begin 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$ createInsertTriggerSQL = format($sql$
create trigger createRbacObjectFor_%s_Trigger create trigger createRbacObjectFor_%s_insert_tg_1058_25
before insert on %s before insert on %s%s
for each row for each row
execute procedure rbac.insert_related_object(); execute procedure rbac.insert_related_object();
$sql$, targetTable, targetTable); $sql$, targetTableName, targetSchemaPrefix, targetTableName);
execute createInsertTriggerSQL; execute createInsertTriggerSQL;
createDeleteTriggerSQL = format($sql$ createDeleteTriggerSQL = format($sql$
create trigger delete_related_rbac_rules_for_%s_tg create trigger createRbacObjectFor_%s_delete_tg_1058_35
after delete after delete on %s%s
on %s
for each row for each row
execute procedure rbac.delete_related_rbac_rules_tf(); execute procedure rbac.delete_related_rbac_rules_tf();
$sql$, targetTable, targetTable); $sql$, targetTableName, targetSchemaPrefix, targetTableName);
execute createDeleteTriggerSQL; execute createDeleteTriggerSQL;
end; $$; end;
$$;
--// --//
@ -176,7 +190,7 @@ begin
*/ */
sql := format($sql$ sql := format($sql$
create or replace view %1$s_rv as create or replace view %1$s_rv as
with accessible_%1$s_uuids as ( with accessible_uuids as (
with recursive with recursive
recursive_grants as recursive_grants as
(select distinct rbac.grants.descendantuuid, (select distinct rbac.grants.descendantuuid,
@ -209,7 +223,7 @@ begin
) )
select target.* select target.*
from %1$s as 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; order by %2$s;
grant all privileges on %1$s_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}; grant all privileges on %1$s_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
@ -219,9 +233,9 @@ begin
/** /**
Instead of insert trigger function for the restricted view. Instead of insert trigger function for the restricted view.
*/ */
newColumns := 'new.' || replace(columnNames, ',', ', new.'); newColumns := 'new.' || replace(columnNames, ', ', ', new.');
sql := format($sql$ sql := format($sql$
create or replace function %1$sInsert() create function %1$s_instead_of_insert_tf()
returns trigger returns trigger
language plpgsql as $f$ language plpgsql as $f$
declare declare
@ -240,11 +254,11 @@ begin
Creates an instead of insert trigger for the restricted view. Creates an instead of insert trigger for the restricted view.
*/ */
sql := format($sql$ sql := format($sql$
create trigger %1$sInsert_tg create trigger instead_of_insert_tg
instead of insert instead of insert
on %1$s_rv on %1$s_rv
for each row for each row
execute function %1$sInsert(); execute function %1$s_instead_of_insert_tf();
$sql$, targetTable); $sql$, targetTable);
execute sql; execute sql;
@ -252,7 +266,7 @@ begin
Instead of delete trigger function for the restricted view. Instead of delete trigger function for the restricted view.
*/ */
sql := format($sql$ sql := format($sql$
create or replace function %1$sDelete() create function %1$s_instead_of_delete_tf()
returns trigger returns trigger
language plpgsql as $f$ language plpgsql as $f$
begin begin
@ -269,11 +283,11 @@ begin
Creates an instead of delete trigger for the restricted view. Creates an instead of delete trigger for the restricted view.
*/ */
sql := format($sql$ sql := format($sql$
create trigger %1$sDelete_tg create trigger instead_of_delete_tg
instead of delete instead of delete
on %1$s_rv on %1$s_rv
for each row for each row
execute function %1$sDelete(); execute function %1$s_instead_of_delete_tf();
$sql$, targetTable); $sql$, targetTable);
execute sql; execute sql;
@ -283,7 +297,7 @@ begin
*/ */
if columnUpdates is not null then if columnUpdates is not null then
sql := format($sql$ sql := format($sql$
create or replace function %1$sUpdate() create function %1$s_instead_of_update_tf()
returns trigger returns trigger
language plpgsql as $f$ language plpgsql as $f$
begin begin
@ -302,11 +316,11 @@ begin
Creates an instead of delete trigger for the restricted view. Creates an instead of delete trigger for the restricted view.
*/ */
sql = format($sql$ sql = format($sql$
create trigger %1$sUpdate_tg create trigger instead_of_update_tg
instead of update instead of update
on %1$s_rv on %1$s_rv
for each row for each row
execute function %1$sUpdate(); execute function %1$s_instead_of_update_tf();
$sql$, targetTable); $sql$, targetTable);
execute sql; execute sql;
end if; end if;

View File

@ -158,8 +158,8 @@ do language plpgsql $$
call base.defineContext('creating fake test-realm admin users', null, null, null); call base.defineContext('creating fake test-realm admin users', null, null, null);
admins = rbac.findRoleId(rbac.globalAdmin()); admins = rbac.findRoleId(rbac.globalAdmin());
call rbac.grantRoleToSubjectUnchecked(admins, admins, rbac.create_subject('superuser-alex@hostsharing.net')); call rbac.grantRoleToUserUnchecked(admins, admins, rbac.create_subject('superuser-alex@hostsharing.net'));
call rbac.grantRoleToSubjectUnchecked(admins, admins, rbac.create_subject('superuser-fran@hostsharing.net')); call rbac.grantRoleToUserUnchecked(admins, admins, rbac.create_subject('superuser-fran@hostsharing.net'));
perform rbac.create_subject('selfregistered-user-drew@hostsharing.org'); perform rbac.create_subject('selfregistered-user-drew@hostsharing.org');
perform rbac.create_subject('selfregistered-test-user@hostsharing.org'); perform rbac.create_subject('selfregistered-test-user@hostsharing.org');
end; end;

View File

@ -0,0 +1,8 @@
--liquibase formatted sql
-- ============================================================================
--changeset michael.hoennig:rbactest-SCHEMA endDelimiter:--//
-- ----------------------------------------------------------------------------
CREATE SCHEMA rbactest; -- just 'test' does not work, databasechangelog gets emptied or deleted
--//

View File

@ -1,10 +1,10 @@
--liquibase formatted sql --liquibase formatted sql
-- ============================================================================ -- ============================================================================
--changeset michael.hoennig:test-customer-MAIN-TABLE endDelimiter:--// --changeset michael.hoennig:rbactest-customer-MAIN-TABLE endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
create table if not exists test_customer create table if not exists rbactest.customer
( (
uuid uuid unique references rbac.object (uuid), uuid uuid unique references rbac.object (uuid),
version int not null default 0, version int not null default 0,

View File

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

View File

@ -2,7 +2,7 @@
-- ============================================================================ -- ============================================================================
--changeset michael.hoennig:test-customer-TEST-DATA-GENERATOR endDelimiter:--// --changeset michael.hoennig:rbactest-customer-TEST-DATA-GENERATOR endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
Generates a customer reference number for a given test data counter. Generates a customer reference number for a given test data counter.
@ -28,18 +28,18 @@ declare
custRowId uuid; custRowId uuid;
custAdminName varchar; custAdminName varchar;
custAdminUuid uuid; custAdminUuid uuid;
newCust test_customer; newCust rbactest.customer;
begin begin
custRowId = uuid_generate_v4(); custRowId = uuid_generate_v4();
custAdminName = 'customer-admin@' || custPrefix || '.example.com'; custAdminName = 'customer-admin@' || custPrefix || '.example.com';
custAdminUuid = rbac.create_subject(custAdminName); custAdminUuid = rbac.create_subject(custAdminName);
insert insert
into test_customer (reference, prefix, adminUserName) into rbactest.customer (reference, prefix, adminUserName)
values (custReference, custPrefix, custAdminName); values (custReference, custPrefix, custAdminName);
select * into newCust select * into newCust
from test_customer where reference=custReference; from rbactest.customer where reference=custReference;
call rbac.grantRoleToSubject( call rbac.grantRoleToSubject(
rbac.getRoleId(testCustomerOwner(newCust)), rbac.getRoleId(testCustomerOwner(newCust)),
rbac.getRoleId(testCustomerAdmin(newCust)), rbac.getRoleId(testCustomerAdmin(newCust)),
@ -67,7 +67,7 @@ end; $$;
-- ============================================================================ -- ============================================================================
--changeset michael.hoennig:test-customer-TEST-DATA-GENERATION context=dev,tc endDelimiter:--// --changeset michael.hoennig:rbactest-customer-TEST-DATA-GENERATION context=dev,tc endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
do language plpgsql $$ do language plpgsql $$

View File

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

View File

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

View File

@ -1,7 +1,7 @@
--liquibase formatted sql --liquibase formatted sql
-- ============================================================================ -- ============================================================================
--changeset michael.hoennig:test-package-TEST-DATA-GENERATOR endDelimiter:--// --changeset michael.hoennig:rbactest-package-TEST-DATA-GENERATOR endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
Creates the given number of test packages for the given customer. Creates the given number of test packages for the given customer.
@ -9,23 +9,23 @@
create or replace procedure createPackageTestData(customerPrefix varchar, pacCount int) create or replace procedure createPackageTestData(customerPrefix varchar, pacCount int)
language plpgsql as $$ language plpgsql as $$
declare declare
cust test_customer; cust rbactest.customer;
custAdminUser varchar; custAdminUser varchar;
custAdminRole varchar; custAdminRole varchar;
pacName varchar; pacName varchar;
pac test_package; pac rbactest.package;
begin begin
select * from test_customer where test_customer.prefix = customerPrefix into cust; select * from rbactest.customer where rbactest.customer.prefix = customerPrefix into cust;
for t in 0..(pacCount-1) for t in 0..(pacCount-1)
loop loop
pacName = cust.prefix || to_char(t, 'fm00'); pacName = cust.prefix || to_char(t, 'fm00');
custAdminUser = 'customer-admin@' || cust.prefix || '.example.com'; custAdminUser = 'customer-admin@' || cust.prefix || '.example.com';
custAdminRole = 'test_customer#' || cust.prefix || ':ADMIN'; custAdminRole = 'rbactest.customer#' || cust.prefix || ':ADMIN';
call base.defineContext('creating RBAC test package', null, 'superuser-fran@hostsharing.net', custAdminRole); call base.defineContext('creating RBAC test package', null, 'superuser-fran@hostsharing.net', custAdminRole);
insert insert
into test_package (customerUuid, name, description) into rbactest.package (customerUuid, name, description)
values (cust.uuid, pacName, 'Here you can add your own description of package ' || pacName || '.') values (cust.uuid, pacName, 'Here you can add your own description of package ' || pacName || '.')
returning * into pac; returning * into pac;
@ -44,9 +44,9 @@ end; $$;
create or replace procedure createPackageTestData() create or replace procedure createPackageTestData()
language plpgsql as $$ language plpgsql as $$
declare declare
cust test_customer; cust rbactest.customer;
begin begin
for cust in (select * from test_customer) for cust in (select * from rbactest.customer)
loop loop
continue when cust.reference >= 90000; -- reserved for functional testing continue when cust.reference >= 90000; -- reserved for functional testing
call createPackageTestData(cust.prefix, 3); call createPackageTestData(cust.prefix, 3);
@ -59,7 +59,7 @@ $$;
-- ============================================================================ -- ============================================================================
--changeset michael.hoennig:test-package-TEST-DATA-GENERATION context=dev,tc endDelimiter:--// --changeset michael.hoennig:rbactest-package-TEST-DATA-GENERATION context=dev,tc endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
do language plpgsql $$ do language plpgsql $$

View File

@ -1,13 +1,13 @@
--liquibase formatted sql --liquibase formatted sql
-- ============================================================================ -- ============================================================================
--changeset michael.hoennig:test-domain-MAIN-TABLE endDelimiter:--// --changeset michael.hoennig:rbactest-domain-MAIN-TABLE endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
create table if not exists test_domain create table if not exists rbactest.domain
( (
uuid uuid unique references rbac.object (uuid), uuid uuid unique references rbac.object (uuid),
packageUuid uuid references test_package (uuid), packageUuid uuid references rbactest.package (uuid),
name character varying(253), name character varying(253),
description character varying(96) description character varying(96)
); );

View File

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

View File

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

View File

@ -181,7 +181,7 @@ $$;
/** /**
Grants hs_office_partner INSERT permission to specified role of new global rows. Grants hs_office_partner INSERT permission to specified role of new global rows.
*/ */
create or replace function rbac.new_hsof_partner_grants_insert_to_global_tf() create or replace function new_hsof_partner_grants_insert_to_global_tf()
returns trigger returns trigger
language plpgsql language plpgsql
strict as $$ strict as $$
@ -198,11 +198,11 @@ end; $$;
create trigger z_new_hs_office_partner_grants_after_insert_tg create trigger z_new_hs_office_partner_grants_after_insert_tg
after insert on rbac.global after insert on rbac.global
for each row for each row
execute procedure rbac.new_hsof_partner_grants_insert_to_global_tf(); execute procedure new_hsof_partner_grants_insert_to_global_tf();
-- ============================================================================ -- ============================================================================
--changeset InsertTriggerGenerator:hs_office_partner-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--// --changeset InsertTriggerGenerator:hs-office-partner-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/** /**

View File

@ -85,7 +85,7 @@ $$;
/** /**
Grants hs_office_partner_details INSERT permission to specified role of new global rows. Grants hs_office_partner_details INSERT permission to specified role of new global rows.
*/ */
create or replace function rbac.new_hsof_partner_details_grants_insert_to_global_tf() create or replace function new_hsof_partner_details_grants_insert_to_global_tf()
returns trigger returns trigger
language plpgsql language plpgsql
strict as $$ strict as $$
@ -102,11 +102,11 @@ end; $$;
create trigger z_new_hs_office_partner_details_grants_after_insert_tg create trigger z_new_hs_office_partner_details_grants_after_insert_tg
after insert on rbac.global after insert on rbac.global
for each row for each row
execute procedure rbac.new_hsof_partner_details_grants_insert_to_global_tf(); execute procedure new_hsof_partner_details_grants_insert_to_global_tf();
-- ============================================================================ -- ============================================================================
--changeset InsertTriggerGenerator:hs_office_partner_details-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--// --changeset InsertTriggerGenerator:hs-office-partner-details-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/** /**

View File

@ -154,7 +154,7 @@ $$;
/** /**
Grants hs_office_debitor INSERT permission to specified role of new global rows. Grants hs_office_debitor INSERT permission to specified role of new global rows.
*/ */
create or replace function rbac.new_hsof_debitor_grants_insert_to_global_tf() create or replace function new_hsof_debitor_grants_insert_to_global_tf()
returns trigger returns trigger
language plpgsql language plpgsql
strict as $$ strict as $$
@ -171,11 +171,11 @@ end; $$;
create trigger z_new_hs_office_debitor_grants_after_insert_tg create trigger z_new_hs_office_debitor_grants_after_insert_tg
after insert on rbac.global after insert on rbac.global
for each row for each row
execute procedure rbac.new_hsof_debitor_grants_insert_to_global_tf(); execute procedure new_hsof_debitor_grants_insert_to_global_tf();
-- ============================================================================ -- ============================================================================
--changeset InsertTriggerGenerator:hs_office_debitor-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--// --changeset InsertTriggerGenerator:hs-office-debitor-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/** /**

View File

@ -150,7 +150,7 @@ execute procedure new_hsof_sepamandate_grants_insert_to_hsof_relation_tf();
-- ============================================================================ -- ============================================================================
--changeset InsertTriggerGenerator:hs_office_sepamandate-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--// --changeset InsertTriggerGenerator:hs-office-sepamandate-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/** /**

View File

@ -116,7 +116,7 @@ $$;
/** /**
Grants hs_office_membership INSERT permission to specified role of new global rows. Grants hs_office_membership INSERT permission to specified role of new global rows.
*/ */
create or replace function rbac.new_hsof_membership_grants_insert_to_global_tf() create or replace function new_hsof_membership_grants_insert_to_global_tf()
returns trigger returns trigger
language plpgsql language plpgsql
strict as $$ strict as $$
@ -133,11 +133,11 @@ end; $$;
create trigger z_new_hs_office_membership_grants_after_insert_tg create trigger z_new_hs_office_membership_grants_after_insert_tg
after insert on rbac.global after insert on rbac.global
for each row for each row
execute procedure rbac.new_hsof_membership_grants_insert_to_global_tf(); execute procedure new_hsof_membership_grants_insert_to_global_tf();
-- ============================================================================ -- ============================================================================
--changeset InsertTriggerGenerator:hs_office_membership-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--// --changeset InsertTriggerGenerator:hs-office-membership-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/** /**

View File

@ -113,7 +113,7 @@ execute procedure new_hsof_coopsharetx_grants_insert_to_hsof_membership_tf();
-- ============================================================================ -- ============================================================================
--changeset InsertTriggerGenerator:hs_office_coopsharestransaction-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--// --changeset InsertTriggerGenerator:hs-office-coopsharestransaction-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/** /**

View File

@ -113,7 +113,7 @@ execute procedure new_hsof_coopassettx_grants_insert_to_hsof_membership_tf();
-- ============================================================================ -- ============================================================================
--changeset InsertTriggerGenerator:hs_office_coopassetstransaction-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--// --changeset InsertTriggerGenerator:hs-office-coopassetstransaction-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/** /**

View File

@ -0,0 +1,63 @@
### rbac bookingItem
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
```mermaid
%%{init:{'flowchart':{'htmlLabels':false}}}%%
flowchart TB
subgraph bookingItem["`**bookingItem**`"]
direction TB
style bookingItem fill:#dd4901,stroke:#274d6e,stroke-width:8px
subgraph bookingItem:roles[ ]
style bookingItem:roles fill:#dd4901,stroke:white
role:bookingItem:OWNER[[bookingItem:OWNER]]
role:bookingItem:ADMIN[[bookingItem:ADMIN]]
role:bookingItem:AGENT[[bookingItem:AGENT]]
role:bookingItem:TENANT[[bookingItem:TENANT]]
end
subgraph bookingItem:permissions[ ]
style bookingItem:permissions fill:#dd4901,stroke:white
perm:bookingItem:INSERT{{bookingItem:INSERT}}
perm:bookingItem:DELETE{{bookingItem:DELETE}}
perm:bookingItem:UPDATE{{bookingItem:UPDATE}}
perm:bookingItem:SELECT{{bookingItem:SELECT}}
end
end
subgraph project["`**project**`"]
direction TB
style project fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph project:roles[ ]
style project:roles fill:#99bcdb,stroke:white
role:project:OWNER[[project:OWNER]]
role:project:ADMIN[[project:ADMIN]]
role:project:AGENT[[project:AGENT]]
role:project:TENANT[[project:TENANT]]
end
end
%% granting roles to roles
role:project:OWNER -.-> role:project:ADMIN
role:project:ADMIN -.-> role:project:AGENT
role:project:AGENT -.-> role:project:TENANT
role:project:AGENT ==> role:bookingItem:OWNER
role:bookingItem:OWNER ==> role:bookingItem:ADMIN
role:bookingItem:ADMIN ==> role:bookingItem:AGENT
role:bookingItem:AGENT ==> role:bookingItem:TENANT
role:bookingItem:TENANT ==> role:project:TENANT
%% granting permissions to roles
role:rbac.global:ADMIN ==> perm:bookingItem:INSERT
role:rbac.global:ADMIN ==> perm:bookingItem:DELETE
role:project:ADMIN ==> perm:bookingItem:INSERT
role:bookingItem:ADMIN ==> perm:bookingItem:UPDATE
role:bookingItem:TENANT ==> perm:bookingItem:SELECT
```

View File

@ -0,0 +1,277 @@
--liquibase formatted sql
-- This code generated was by RbacViewPostgresGenerator, do not amend manually.
-- ============================================================================
--changeset michael.hoennig:hs-booking-item-rbac-OBJECT endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRelatedRbacObject('hs_booking_item');
--//
-- ============================================================================
--changeset michael.hoennig:hs-booking-item-rbac-ROLE-DESCRIPTORS endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRbacRoleDescriptors('hsBookingItem', 'hs_booking_item');
--//
-- ============================================================================
--changeset michael.hoennig:hs-booking-item-rbac-insert-trigger endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
*/
create or replace procedure buildRbacSystemForHsBookingItem(
NEW hs_booking_item
)
language plpgsql as $$
declare
newProject hs_booking_project;
newParentItem hs_booking_item;
begin
call rbac.enterTriggerForObjectUuid(NEW.uuid);
SELECT * FROM hs_booking_project WHERE uuid = NEW.projectUuid INTO newProject;
SELECT * FROM hs_booking_item WHERE uuid = NEW.parentItemUuid INTO newParentItem;
perform rbac.defineRoleWithGrants(
hsBookingItemOWNER(NEW),
incomingSuperRoles => array[
hsBookingItemAGENT(newParentItem),
hsBookingProjectAGENT(newProject)]
);
perform rbac.defineRoleWithGrants(
hsBookingItemADMIN(NEW),
permissions => array['UPDATE'],
incomingSuperRoles => array[hsBookingItemOWNER(NEW)]
);
perform rbac.defineRoleWithGrants(
hsBookingItemAGENT(NEW),
incomingSuperRoles => array[hsBookingItemADMIN(NEW)]
);
perform rbac.defineRoleWithGrants(
hsBookingItemTENANT(NEW),
permissions => array['SELECT'],
incomingSuperRoles => array[hsBookingItemAGENT(NEW)],
outgoingSubRoles => array[
hsBookingItemTENANT(newParentItem),
hsBookingProjectTENANT(newProject)]
);
call rbac.grantPermissionToRole(rbac.createPermission(NEW.uuid, 'DELETE'), rbac.globalAdmin());
call rbac.leaveTriggerForObjectUuid(NEW.uuid);
end; $$;
/*
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_booking_item row.
*/
create or replace function insertTriggerForHsBookingItem_tf()
returns trigger
language plpgsql
strict as $$
begin
call buildRbacSystemForHsBookingItem(NEW);
return NEW;
end; $$;
create trigger insertTriggerForHsBookingItem_tg
after insert on hs_booking_item
for each row
execute procedure insertTriggerForHsBookingItem_tf();
--//
-- ============================================================================
--changeset michael.hoennig:hs-booking-item-rbac-GRANTING-INSERT-PERMISSION endDelimiter:--//
-- ----------------------------------------------------------------------------
-- granting INSERT permission to global ----------------------------
/*
Grants INSERT INTO hs_booking_item permissions to specified role of pre-existing global rows.
*/
do language plpgsql $$
declare
row rbac.global%ROWTYPE;
begin
call base.defineContext('create INSERT INTO hs_booking_item 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', 'hs_booking_item'),
rbac.globalAdmin());
END LOOP;
end;
$$;
/**
Grants hs_booking_item INSERT permission to specified role of new rbac.global rows.
*/
create or replace function new_hs_booking_item_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', 'hs_booking_item'),
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_hs_booking_item_grants_insert_to_global_tg
after insert on rbac.global
for each row
execute procedure new_hs_booking_item_grants_insert_to_global_tf();
-- granting INSERT permission to hs_booking_project ----------------------------
/*
Grants INSERT INTO hs_booking_item permissions to specified role of pre-existing hs_booking_project rows.
*/
do language plpgsql $$
declare
row hs_booking_project;
begin
call base.defineContext('create INSERT INTO hs_booking_item permissions for pre-exising hs_booking_project rows');
FOR row IN SELECT * FROM hs_booking_project
-- unconditional for all rows in that table
LOOP
call rbac.grantPermissionToRole(
rbac.createPermission(row.uuid, 'INSERT', 'hs_booking_item'),
hsBookingProjectADMIN(row));
END LOOP;
end;
$$;
/**
Grants hs_booking_item INSERT permission to specified role of new hs_booking_project rows.
*/
create or replace function new_hs_booking_item_grants_insert_to_hs_booking_project_tf()
returns trigger
language plpgsql
strict as $$
begin
-- unconditional for all rows in that table
call rbac.grantPermissionToRole(
rbac.createPermission(NEW.uuid, 'INSERT', 'hs_booking_item'),
hsBookingProjectADMIN(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_hs_booking_item_grants_insert_to_hs_booking_project_tg
after insert on hs_booking_project
for each row
execute procedure new_hs_booking_item_grants_insert_to_hs_booking_project_tf();
-- granting INSERT permission to hs_booking_item ----------------------------
-- Granting INSERT INTO hs_hosting_asset permissions to specified role of pre-existing hs_hosting_asset rows slipped,
-- because there cannot yet be any pre-existing rows in the same table yet.
/**
Grants hs_booking_item INSERT permission to specified role of new hs_booking_item rows.
*/
create or replace function new_hs_booking_item_grants_insert_to_hs_booking_item_tf()
returns trigger
language plpgsql
strict as $$
begin
-- unconditional for all rows in that table
call rbac.grantPermissionToRole(
rbac.createPermission(NEW.uuid, 'INSERT', 'hs_booking_item'),
hsBookingItemADMIN(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_hs_booking_item_grants_insert_to_hs_booking_item_tg
after insert on hs_booking_item
for each row
execute procedure new_hs_booking_item_grants_insert_to_hs_booking_item_tf();
-- ============================================================================
--changeset michael.hoennig:hs_booking_item-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
-- ----------------------------------------------------------------------------
/**
Checks if the user respectively the assumed roles are allowed to insert a row to hs_booking_item.
*/
create or replace function hs_booking_item_insert_permission_check_tf()
returns trigger
language plpgsql as $$
declare
superObjectUuid uuid;
begin
-- check INSERT INSERT if rbac.Global ADMIN
if rbac.isGlobalAdmin() then
return NEW;
end if;
-- check INSERT permission via direct foreign key: NEW.projectUuid
if rbac.hasInsertPermission(NEW.projectUuid, 'hs_booking_item') then
return NEW;
end if;
-- check INSERT permission via direct foreign key: NEW.parentItemUuid
if rbac.hasInsertPermission(NEW.parentItemUuid, 'hs_booking_item') then
return NEW;
end if;
raise exception '[403] insert into hs_booking_item values(%) not allowed for current subjects % (%)',
NEW, base.currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end; $$;
create trigger hs_booking_item_insert_permission_check_tg
before insert on hs_booking_item
for each row
execute procedure hs_booking_item_insert_permission_check_tf();
--//
-- ============================================================================
--changeset michael.hoennig:hs-booking-item-rbac-IDENTITY-VIEW endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRbacIdentityViewFromProjection('hs_booking_item',
$idName$
caption
$idName$);
--//
-- ============================================================================
--changeset michael.hoennig:hs-booking-item-rbac-RESTRICTED-VIEW endDelimiter:--//
-- ----------------------------------------------------------------------------
call rbac.generateRbacRestrictedView('hs_booking_item',
$orderBy$
validity
$orderBy$,
$updates$
version = new.version,
caption = new.caption,
validity = new.validity,
resources = new.resources
$updates$);
--//

View File

@ -1,96 +0,0 @@
--liquibase formatted sql
-- TODO: These changesets are just for the external remote views to simulate the legacy tables.
-- Once we don't need the external remote views anymore, create revert changesets.
-- ============================================================================
--changeset hs-hosting-asset-MIGRATION-mapping:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
CREATE TABLE hs_hosting_asset_legacy_id
(
uuid uuid NOT NULL REFERENCES hs_hosting_asset(uuid),
legacy_id integer NOT NULL
);
--//
-- ============================================================================
--changeset hs-hosting-asset-MIGRATION-sequence:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
CREATE SEQUENCE IF NOT EXISTS hs_hosting_asset_legacy_id_seq
AS integer
START 1000000000
OWNED BY hs_hosting_asset_legacy_id.legacy_id;
--//
-- ============================================================================
--changeset hs-hosting-asset-MIGRATION-default:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
ALTER TABLE hs_hosting_asset_legacy_id
ALTER COLUMN legacy_id
SET DEFAULT nextVal('hs_hosting_asset_legacy_id_seq');
--/
-- ============================================================================
--changeset hs-hosting-asset-MIGRATION-insert:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
CALL base.defineContext('schema-migration');
INSERT INTO hs_hosting_asset_legacy_id(uuid, legacy_id)
SELECT uuid, nextVal('hs_hosting_asset_legacy_id_seq') FROM hs_hosting_asset;
--/
-- ============================================================================
--changeset hs-hosting-asset-MIGRATION-insert-trigger:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
create or replace function insertassetLegacyIdMapping()
returns trigger
language plpgsql
strict as $$
begin
if TG_OP <> 'INSERT' then
raise exception 'invalid usage of trigger';
end if;
INSERT INTO hs_hosting_asset_legacy_id VALUES
(NEW.uuid, nextVal('hs_hosting_asset_legacy_id_seq'));
return NEW;
end; $$;
create trigger createassetLegacyIdMapping
after insert on hs_hosting_asset
for each row
execute procedure insertassetLegacyIdMapping();
--/
-- ============================================================================
--changeset hs-hosting-asset-MIGRATION-delete-trigger:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
create or replace function deleteassetLegacyIdMapping_tf()
returns trigger
language plpgsql
strict as $$
begin
if TG_OP <> 'DELETE' then
raise exception 'invalid usage of trigger';
end if;
DELETE FROM hs_hosting_asset_legacy_id
WHERE uuid = OLD.uuid;
return OLD;
end; $$;
create trigger deleteassetLegacyIdMapping_tg
before delete on hs_hosting_asset
for each row
execute procedure deleteassetLegacyIdMapping_tf();
--/

View File

@ -21,6 +21,8 @@ databaseChangeLog:
file: db/changelog/0-base/009-check-environment.sql file: db/changelog/0-base/009-check-environment.sql
- include: - include:
file: db/changelog/0-base/010-context.sql file: db/changelog/0-base/010-context.sql
- include:
file: db/changelog/0-base/011-table-schema-and-name.sql
- include: - include:
file: db/changelog/0-base/020-audit-log.sql file: db/changelog/0-base/020-audit-log.sql
- include: - include:
@ -48,23 +50,25 @@ databaseChangeLog:
- include: - include:
file: db/changelog/1-rbac/1080-rbac-global.sql file: db/changelog/1-rbac/1080-rbac-global.sql
- include: - include:
file: db/changelog/2-test/201-test-customer/2010-test-customer.sql file: db/changelog/2-rbactest/200-rbactest-schema.sql
- include: - include:
file: db/changelog/2-test/201-test-customer/2013-test-customer-rbac.sql file: db/changelog/2-rbactest/201-rbactest-customer/2010-rbactest-customer.sql
- include: - include:
file: db/changelog/2-test/201-test-customer/2018-test-customer-test-data.sql file: db/changelog/2-rbactest/201-rbactest-customer/2013-rbactest-customer-rbac.sql
- include: - include:
file: db/changelog/2-test/202-test-package/2020-test-package.sql file: db/changelog/2-rbactest/201-rbactest-customer/2018-rbactest-customer-test-data.sql
- include: - include:
file: db/changelog/2-test/202-test-package/2023-test-package-rbac.sql file: db/changelog/2-rbactest/202-rbactest-package/2020-rbactest-package.sql
- include: - include:
file: db/changelog/2-test/202-test-package/2028-test-package-test-data.sql file: db/changelog/2-rbactest/202-rbactest-package/2023-rbactest-package-rbac.sql
- include: - include:
file: db/changelog/2-test/203-test-domain/2030-test-domain.sql file: db/changelog/2-rbactest/202-rbactest-package/2028-rbactest-package-test-data.sql
- include: - include:
file: db/changelog/2-test/203-test-domain/2033-test-domain-rbac.sql file: db/changelog/2-rbactest/203-rbactest-domain/2030-rbactest-domain.sql
- include: - include:
file: db/changelog/2-test/203-test-domain/2038-test-domain-test-data.sql file: db/changelog/2-rbactest/203-rbactest-domain/2033-rbactest-domain-rbac.sql
- include:
file: db/changelog/2-rbactest/203-rbactest-domain/2038-rbactest-domain-test-data.sql
- include: - include:
file: db/changelog/5-hs-office/501-contact/5010-hs-office-contact.sql file: db/changelog/5-hs-office/501-contact/5010-hs-office-contact.sql
- include: - include:
@ -146,17 +150,15 @@ databaseChangeLog:
- include: - include:
file: db/changelog/6-hs-booking/620-booking-project/6208-hs-booking-project-test-data.sql file: db/changelog/6-hs-booking/620-booking-project/6208-hs-booking-project-test-data.sql
- include: - include:
file: db/changelog/6-hs-booking/630-booking-item/6300-hs-booking-item.sql file: db/changelog/6-hs-booking/630-booking-item/6200-hs-booking-item.sql
- include: - include:
file: db/changelog/6-hs-booking/630-booking-item/6303-hs-booking-item-rbac.sql file: db/changelog/6-hs-booking/630-booking-item/6203-hs-booking-item-rbac.sql
- include: - include:
file: db/changelog/6-hs-booking/630-booking-item/6308-hs-booking-item-test-data.sql file: db/changelog/6-hs-booking/630-booking-item/6208-hs-booking-item-test-data.sql
- include: - include:
file: db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql file: db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql
- include: - include:
file: db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.sql file: db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.sql
- include:
file: db/changelog/7-hs-hosting/701-hosting-asset/7016-hs-hosting-asset-migration.sql
- include: - include:
file: db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql file: db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql
- include: - include:

View File

@ -17,6 +17,7 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity; import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
@ -698,6 +699,24 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
assumeThat(partners.size()).isLessThanOrEqualTo(MAX_NUMBER_OF_TEST_DATA_PARTNERS); assumeThat(partners.size()).isLessThanOrEqualTo(MAX_NUMBER_OF_TEST_DATA_PARTNERS);
} }
private <E extends BaseEntity> void updateLegacyIds(
Map<Integer, E> entities,
final String legacyIdTable,
final String legacyIdColumn) {
em.flush();
entities.forEach((id, entity) -> em.createNativeQuery("""
UPDATE ${legacyIdTable}
SET ${legacyIdColumn} = :legacyId
WHERE uuid = :uuid
"""
.replace("${legacyIdTable}", legacyIdTable)
.replace("${legacyIdColumn}", legacyIdColumn))
.setParameter("legacyId", id)
.setParameter("uuid", entity.getUuid())
.executeUpdate()
);
}
@Test @Test
@Order(9999) @Order(9999)
@ContinueOnFailure @ContinueOnFailure

View File

@ -289,9 +289,9 @@ public class CsvDataImport extends ContextBasedTest {
protected void deleteFromTestTables() { protected void deleteFromTestTables() {
jpaAttempt.transacted(() -> { jpaAttempt.transacted(() -> {
context(rbacSuperuser); context(rbacSuperuser);
em.createNativeQuery("delete from test_domain where true").executeUpdate(); em.createNativeQuery("delete from rbactest.domain where true").executeUpdate();
em.createNativeQuery("delete from test_package where true").executeUpdate(); em.createNativeQuery("delete from rbactest.package where true").executeUpdate();
em.createNativeQuery("delete from test_customer where true").executeUpdate(); em.createNativeQuery("delete from rbactest.customer where true").executeUpdate();
}).assertSuccessful(); }).assertSuccessful();
} }
@ -334,24 +334,6 @@ public class CsvDataImport extends ContextBasedTest {
errors.clear(); errors.clear();
assertThat(errorsToLog).isEmpty(); assertThat(errorsToLog).isEmpty();
} }
protected <E extends BaseEntity> void updateLegacyIds(
Map<Integer, E> entities,
final String legacyIdTable,
final String legacyIdColumn) {
em.flush();
entities.forEach((id, entity) -> em.createNativeQuery("""
UPDATE ${legacyIdTable}
SET ${legacyIdColumn} = :legacyId
WHERE uuid = :uuid
"""
.replace("${legacyIdTable}", legacyIdTable)
.replace("${legacyIdColumn}", legacyIdColumn))
.setParameter("legacyId", id)
.setParameter("uuid", entity.getUuid())
.executeUpdate()
);
}
} }
class Columns { class Columns {

View File

@ -47,12 +47,12 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function; import java.util.function.Function;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static java.util.Arrays.stream; import static java.util.Arrays.stream;
import static java.util.Map.entry; import static java.util.Map.entry;
import static java.util.Map.ofEntries; import static java.util.Map.ofEntries;
import static java.util.Optional.ofNullable; import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toMap; import static java.util.stream.Collectors.toMap;
import static java.util.stream.Collectors.toSet; import static java.util.stream.Collectors.toSet;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
@ -938,132 +938,6 @@ public class ImportHostingAssets extends BaseOfficeDataImport {
@Test @Test
@Order(19930) @Order(19930)
void verifyCloudServerLegacyIds() {
assumeThatWeAreImportingControlledTestData();
assertThat(fetchHosingAssetLegacyIds(CLOUD_SERVER)).isEqualTo("""
23611
""".trim());
assertThat(missingHostingAsstLegacyIds(CLOUD_SERVER)).isEmpty();
}
@Test
@Order(19931)
void verifyManagedServerLegacyIds() {
assumeThatWeAreImportingControlledTestData();
assertThat(fetchHosingAssetLegacyIds(MANAGED_SERVER)).isEqualTo("""
10968
10978
11061
11447
""".trim());
assertThat(missingHostingAsstLegacyIds(MANAGED_SERVER)).isEmpty();
}
@Test
@Order(19932)
void verifyManagedWebspaceLegacyIds() {
assumeThatWeAreImportingControlledTestData();
assertThat(fetchHosingAssetLegacyIds(MANAGED_WEBSPACE)).isEqualTo("""
10630
11094
11111
11112
19959
""".trim());
assertThat(missingHostingAsstLegacyIds(MANAGED_WEBSPACE)).isEmpty();
}
@Test
@Order(19933)
void verifyUnixUserLegacyIds() {
assumeThatWeAreImportingControlledTestData();
assertThat(fetchHosingAssetLegacyIds(UNIX_USER)).isEqualTo("""
5803
5805
5809
5811
5813
5835
5961
5964
5966
5990
6705
6824
7846
9546
9596
""".trim());
assertThat(missingHostingAsstLegacyIds(UNIX_USER)).isEmpty();
}
@Test
@Order(19934)
void verifyPgSqlDbLegacyIds() {
assumeThatWeAreImportingControlledTestData();
assertThat(fetchHosingAssetLegacyIds(PGSQL_DATABASE)).isEqualTo("""
1077
1858
1860
4931
4932
7522
7523
7605
""".trim());
assertThat(missingHostingAsstLegacyIds(PGSQL_DATABASE)).isEmpty();
}
@Test
@Order(19934)
void verifyPgSqlUserLegacyIds() {
assumeThatWeAreImportingControlledTestData();
assertThat(fetchHosingAssetLegacyIds(PGSQL_USER)).isEqualTo("""
1857
1859
1860
1861
4931
7522
7605
""".trim());
assertThat(missingHostingAsstLegacyIds(PGSQL_USER)).isEmpty();
}
@Test
@Order(19935)
void verifyMariaDbLegacyIds() {
assumeThatWeAreImportingControlledTestData();
assertThat(fetchHosingAssetLegacyIds(MARIADB_DATABASE)).isEqualTo("""
1786
1805
4908
4941
4942
7520
7521
7604
""".trim());
assertThat(missingHostingAsstLegacyIds(MARIADB_DATABASE)).isEmpty();
}
@Test
@Order(19936)
void verifyMariaDbUserLegacyIds() {
assumeThatWeAreImportingControlledTestData();
assertThat(fetchHosingAssetLegacyIds(MARIADB_USER)).isEqualTo("""
1858
4908
4909
4932
7520
7604
""".trim());
assertThat(missingHostingAsstLegacyIds(MARIADB_USER)).isEmpty();
}
@Test
@Order(19940)
void verifyProjectAgentsCanViewEmailAddresses() { void verifyProjectAgentsCanViewEmailAddresses() {
assumeThatWeAreImportingControlledTestData(); assumeThatWeAreImportingControlledTestData();
@ -1075,7 +949,6 @@ public class ImportHostingAssets extends BaseOfficeDataImport {
assertThat(haCount).isEqualTo(68); assertThat(haCount).isEqualTo(68);
} }
// ============================================================================================ // ============================================================================================
@Test @Test
@ -1133,11 +1006,6 @@ public class ImportHostingAssets extends BaseOfficeDataImport {
} }
).assertSuccessful() ).assertSuccessful()
); );
jpaAttempt.transacted(() -> {
context(rbacSuperuser);
updateLegacyIds(assets, "hs_hosting_asset_legacy_id", "legacy_id");
}).assertSuccessful();
} }
private void verifyActuallyPersistedHostingAssetCount( private void verifyActuallyPersistedHostingAssetCount(
@ -1742,7 +1610,7 @@ public class ImportHostingAssets extends BaseOfficeDataImport {
//noinspection unchecked //noinspection unchecked
zoneData.put("user-RR", ((ArrayList<ArrayList<Object>>) zoneData.get("user-RR")).stream() zoneData.put("user-RR", ((ArrayList<ArrayList<Object>>) zoneData.get("user-RR")).stream()
.map(userRR -> userRR.stream().map(Object::toString).collect(joining(" "))) .map(userRR -> userRR.stream().map(Object::toString).collect(Collectors.joining(" ")))
.toArray(String[]::new) .toArray(String[]::new)
); );
domainDnsSetupAsset.getConfig().putAll(zoneData); domainDnsSetupAsset.getConfig().putAll(zoneData);
@ -1890,35 +1758,4 @@ public class ImportHostingAssets extends BaseOfficeDataImport {
protected static void assumeThatWeAreImportingControlledTestData() { protected static void assumeThatWeAreImportingControlledTestData() {
assumeThat(isImportingControlledTestData()).isTrue(); assumeThat(isImportingControlledTestData()).isTrue();
} }
private String fetchHosingAssetLegacyIds(final HsHostingAssetType type) {
//noinspection unchecked
return ((List<List<?>>) em.createNativeQuery(
"""
SELECT li.* FROM hs_hosting_asset_legacy_id li
JOIN hs_hosting_asset ha ON ha.uuid=li.uuid
WHERE CAST(ha.type AS text)=:type
ORDER BY legacy_id
""",
List.class)
.setParameter("type", type.name())
.getResultList()
).stream().map(row -> row.get(1).toString()).collect(joining("\n"));
}
private String missingHostingAsstLegacyIds(final HsHostingAssetType type) {
//noinspection unchecked
return ((List<List<?>>) em.createNativeQuery(
"""
SELECT ha.uuid, ha.type, ha.identifier FROM hs_hosting_asset ha
JOIN hs_hosting_asset_legacy_id li ON li.uuid=ha.uuid
WHERE li.legacy_id is null AND CAST(ha.type AS text)=:type
ORDER BY li.legacy_id
""",
List.class)
.setParameter("type", type.name())
.getResultList()).stream()
.map(row -> row.stream().map(Object::toString).collect(joining(", ")))
.collect(joining("\n"));
}
} }

View File

@ -62,13 +62,13 @@ class ContextIntegrationTests {
void defineWithoutcurrentSubjectButWithAssumedRoles() { void defineWithoutcurrentSubjectButWithAssumedRoles() {
// when // when
final var result = jpaAttempt.transacted(() -> final var result = jpaAttempt.transacted(() ->
context.define(null, "test_package#yyy00:ADMIN") context.define(null, "rbactest.package#yyy00:ADMIN")
); );
// then // then
result.assertExceptionWithRootCauseMessage( result.assertExceptionWithRootCauseMessage(
jakarta.persistence.PersistenceException.class, 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 rbactest.package#yyy00:ADMIN");
} }
@Test @Test
@ -88,7 +88,7 @@ class ContextIntegrationTests {
@Transactional @Transactional
void defineWithcurrentSubjectAndAssumedRoles() { void defineWithcurrentSubjectAndAssumedRoles() {
// given // given
context.define("superuser-alex@hostsharing.net", "test_customer#xxx:OWNER;test_customer#yyy:OWNER"); context.define("superuser-alex@hostsharing.net", "rbactest.customer#xxx:OWNER;rbactest.customer#yyy:OWNER");
// when // when
final var currentSubject = context.fetchCurrentSubject(); final var currentSubject = context.fetchCurrentSubject();
@ -96,7 +96,7 @@ class ContextIntegrationTests {
// then // then
assertThat(context.fetchAssumedRoles()) assertThat(context.fetchAssumedRoles())
.isEqualTo(Array.of("test_customer#xxx:OWNER", "test_customer#yyy:OWNER")); .isEqualTo(Array.of("rbactest.customer#xxx:OWNER", "rbactest.customer#yyy:OWNER"));
assertThat(context.fetchCurrentSubjectOrAssumedRolesUuids()).hasSize(2); assertThat(context.fetchCurrentSubjectOrAssumedRolesUuids()).hasSize(2);
} }
@ -104,12 +104,12 @@ class ContextIntegrationTests {
public void defineContextWithcurrentSubjectAndAssumeInaccessibleRole() { public void defineContextWithcurrentSubjectAndAssumeInaccessibleRole() {
// when // when
final var result = jpaAttempt.transacted(() -> final var result = jpaAttempt.transacted(() ->
context.define("customer-admin@xxx.example.com", "test_package#yyy00:ADMIN") context.define("customer-admin@xxx.example.com", "rbactest.package#yyy00:ADMIN")
); );
// then // then
result.assertExceptionWithRootCauseMessage( result.assertExceptionWithRootCauseMessage(
jakarta.persistence.PersistenceException.class, 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 rbactest.package#yyy00:ADMIN");
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,6 +5,7 @@ spring:
datasource: datasource:
url-tc: jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers url-tc: jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers
url-tcx: jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers?TC_REUSABLE=true&TC_DAEMON=true
url-local: jdbc:postgresql://localhost:5432/postgres url-local: jdbc:postgresql://localhost:5432/postgres
url: ${spring.datasource.url-tc} url: ${spring.datasource.url-tc}
username: postgres username: postgres