Compare commits
2 Commits
aaa3bf8935
...
1eed0e9b21
Author | SHA1 | Date | |
---|---|---|---|
1eed0e9b21 | |||
80d79de5f4 |
@ -82,7 +82,7 @@ If you have at least Docker and the Java JDK installed in appropriate versions a
|
||||
|
||||
# the following command should return a JSON array with just all packages visible for the admin of the customer yyy:
|
||||
curl \
|
||||
-H 'current-subject: superuser-alex@hostsharing.net' -H 'assumed-roles: rbactest.customer#yyy:ADMIN' \
|
||||
-H 'current-subject: superuser-alex@hostsharing.net' -H 'assumed-roles: test_customer#yyy:ADMIN' \
|
||||
http://localhost:8080/api/test/packages
|
||||
|
||||
# add a new customer
|
||||
|
@ -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.
|
||||
|
||||
The role-hierarchy and permissions for currently logged-in sujects could be cached in the backend.
|
||||
The role-hierarchy and permissions for current subjects (e.g. logged-in users) could be cached in the backend.
|
||||
|
||||
The access logic can be tested in pure Java unit tests.
|
||||
|
||||
|
@ -3,14 +3,14 @@
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
||||
select rbac.isGranted(rbac.findRoleId('administrators'), rbac.findRoleId('rbactest.package#aaa00:OWNER'));
|
||||
select rbac.isGranted(rbac.findRoleId('rbactest.package#aaa00:OWNER'), rbac.findRoleId('administrators'));
|
||||
-- call rbac.grantRoleToRole(findRoleId('rbactest.package#aaa00:OWNER'), findRoleId('administrators'));
|
||||
-- call rbac.grantRoleToRole(findRoleId('administrators'), findRoleId('rbactest.package#aaa00:OWNER'));
|
||||
select rbac.isGranted(rbac.findRoleId('administrators'), rbac.findRoleId('test.package#aaa00:OWNER'));
|
||||
select rbac.isGranted(rbac.findRoleId('test.package#aaa00:OWNER'), rbac.findRoleId('administrators'));
|
||||
-- call rbac.grantRoleToRole(findRoleId('test.package#aaa00:OWNER'), findRoleId('administrators'));
|
||||
-- call rbac.grantRoleToRole(findRoleId('administrators'), findRoleId('test.package#aaa00:OWNER'));
|
||||
|
||||
select count(*)
|
||||
FROM rbac.queryAllPermissionsOfSubjectIdForObjectUuids(rbac.findRbacSubject('superuser-fran@hostsharing.net'),
|
||||
ARRAY(select uuid from rbactest.customer where reference < 1100000));
|
||||
ARRAY(select uuid from test.customer where reference < 1100000));
|
||||
select count(*)
|
||||
FROM rbac.queryAllPermissionsOfSubjectId(findRbacSubject('superuser-fran@hostsharing.net'));
|
||||
select *
|
||||
|
@ -20,7 +20,7 @@ CREATE POLICY customer_policy ON customer
|
||||
TO restricted
|
||||
USING (
|
||||
-- id=1000
|
||||
rbac.isPermissionGrantedToSubject(rbac.findEffectivePermissionId('rbactest.customer', id, 'SELECT'), rbac.currentSubjectUuid())
|
||||
rbac.isPermissionGrantedToSubject(rbac.findEffectivePermissionId('test.customer', id, 'SELECT'), rbac.currentSubjectUuid())
|
||||
);
|
||||
|
||||
SET SESSION AUTHORIZATION restricted;
|
||||
@ -31,28 +31,28 @@ SELECT * from customer;
|
||||
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||
DROP VIEW cust_view;
|
||||
CREATE VIEW cust_view AS
|
||||
SELECT * FROM rbactest.customer;
|
||||
SELECT * FROM test.customer;
|
||||
CREATE OR REPLACE RULE "_RETURN" AS
|
||||
ON SELECT TO cust_view
|
||||
DO INSTEAD
|
||||
SELECT * FROM rbactest.customer WHERE rbac.isPermissionGrantedToSubject(rbac.findEffectivePermissionId('rbactest.customer', id, 'SELECT'), rbac.currentSubjectUuid());
|
||||
SELECT * FROM test.customer WHERE rbac.isPermissionGrantedToSubject(rbac.findEffectivePermissionId('test.customer', id, 'SELECT'), rbac.currentSubjectUuid());
|
||||
SELECT * from cust_view LIMIT 10;
|
||||
|
||||
select rbac.queryAllPermissionsOfSubjectId(findRbacSubject('superuser-alex@hostsharing.net'));
|
||||
|
||||
-- access control via view-rule with join to recursive permissions - really fast (38ms for 1 million rows)
|
||||
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||
ALTER TABLE rbactest.customer ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE test.customer ENABLE ROW LEVEL SECURITY;
|
||||
DROP VIEW IF EXISTS cust_view;
|
||||
CREATE OR REPLACE VIEW cust_view AS
|
||||
SELECT *
|
||||
FROM rbactest.customer;
|
||||
FROM test.customer;
|
||||
CREATE OR REPLACE RULE "_RETURN" AS
|
||||
ON SELECT TO cust_view
|
||||
DO INSTEAD
|
||||
SELECT c.uuid, c.reference, c.prefix FROM rbactest.customer AS c
|
||||
SELECT c.uuid, c.reference, c.prefix FROM test.customer AS c
|
||||
JOIN rbac.queryAllPermissionsOfSubjectId(rbac.currentSubjectUuid()) AS p
|
||||
ON p.objectTable='rbactest.customer' AND p.objectUuid=c.uuid;
|
||||
ON p.objectTable='test.customer' AND p.objectUuid=c.uuid;
|
||||
GRANT ALL PRIVILEGES ON cust_view TO 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
|
||||
where g.descendantUuid in (
|
||||
select uuid from rbac.queryAllPermissionsOfSubjectId(findRbacSubject('alex@example.com'))
|
||||
where objectTable='rbactest.customer');
|
||||
where objectTable='test.customer');
|
||||
|
||||
call rbac.grantRoleToUser(rbac.findRoleId('rbactest.customer#aaa:ADMIN'), rbac.findRbacSubject('aaaaouq@example.com'));
|
||||
call rbac.grantRoleToUser(rbac.findRoleId('test.customer#aaa:ADMIN'), rbac.findRbacSubject('aaaaouq@example.com'));
|
||||
|
||||
select rbac.queryAllPermissionsOfSubjectId(findRbacSubject('aaaaouq@example.com'));
|
||||
|
||||
|
@ -100,7 +100,7 @@ public class InsertTriggerGenerator {
|
||||
/**
|
||||
Grants ${rawSubTable} INSERT permission to specified role of new ${rawSuperTable} rows.
|
||||
*/
|
||||
create or replace function ${rawSubTableSchemaPrefix}new_${rawSubTableShortName}_grants_insert_to_${rawSuperTableShortName}_tf()
|
||||
create or replace function ${rawSuperTableSchemaName}new_${rawSubTableShortName}_grants_insert_to_${rawSuperTableShortName}_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
@ -114,10 +114,10 @@ public class InsertTriggerGenerator {
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_new_${rawSubTableName}_grants_after_insert_tg
|
||||
create trigger z_new_${rawSubTable}_grants_after_insert_tg
|
||||
after insert on ${rawSuperTableWithSchema}
|
||||
for each row
|
||||
execute procedure ${rawSubTableSchemaPrefix}new_${rawSubTableShortName}_grants_insert_to_${rawSuperTableShortName}_tf();
|
||||
execute procedure ${rawSuperTableSchemaName}new_${rawSubTableShortName}_grants_insert_to_${rawSuperTableShortName}_tf();
|
||||
""",
|
||||
with("ifConditionThen", g.getSuperRoleDef().getEntityAlias().isCaseDependent()
|
||||
// TODO.impl: .type needs to be dynamically generated
|
||||
@ -130,9 +130,8 @@ public class InsertTriggerGenerator {
|
||||
with("rawSuperTableWithSchema", g.getSuperRoleDef().getEntityAlias().getRawTableNameWithSchema()),
|
||||
with("rawSuperTableShortName", g.getSuperRoleDef().getEntityAlias().getRawTableShortName()),
|
||||
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
|
||||
with("rawSuperTableSchemaName", g.getSuperRoleDef().getEntityAlias().getRawTableSchemaPrefix()),
|
||||
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableNameWithSchema()),
|
||||
with("rawSubTableSchemaPrefix", g.getPermDef().getEntityAlias().getRawTableSchemaPrefix()),
|
||||
with("rawSubTableName", g.getPermDef().getEntityAlias().getRawTableName()),
|
||||
with("rawSubTableShortName", g.getPermDef().getEntityAlias().getRawTableShortName()));
|
||||
|
||||
});
|
||||
@ -155,16 +154,15 @@ public class InsertTriggerGenerator {
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into ${rawSubTableWithSchema} values(%) not allowed regardless of current subject, no insert permissions granted at all', NEW;
|
||||
raise exception '[403] insert into ${rawSubTable} values(%) not allowed regardless of current subject, no insert permissions granted at all', NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger ${rawSubTable}_insert_permission_check_tg
|
||||
before insert on ${rawSubTable}
|
||||
for each row
|
||||
execute procedure ${rawSubTableWithSchema}_insert_permission_missing_tf();
|
||||
execute procedure ${rawSubTable}_insert_permission_missing_tf();
|
||||
""",
|
||||
with("rawSubTableWithSchema", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()),
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
|
||||
|
||||
plPgSql.writeLn("--//");
|
||||
}
|
||||
@ -185,7 +183,7 @@ public class InsertTriggerGenerator {
|
||||
private void generateInsertPermissionsCheckHeader(final StringWriter plPgSql) {
|
||||
plPgSql.writeLn("""
|
||||
-- ============================================================================
|
||||
--changeset InsertTriggerGenerator:${liquibaseTagPrefix}-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
|
||||
--changeset InsertTriggerGenerator:${rawSubTable}-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@ -198,7 +196,6 @@ public class InsertTriggerGenerator {
|
||||
superObjectUuid uuid;
|
||||
begin
|
||||
""",
|
||||
with("liquibaseTagPrefix", liquibaseTagPrefix),
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
|
||||
plPgSql.chopEmptyLines();
|
||||
}
|
||||
@ -261,18 +258,17 @@ public class InsertTriggerGenerator {
|
||||
private void generateInsertPermissionsChecksFooter(final StringWriter plPgSql) {
|
||||
plPgSql.writeLn();
|
||||
plPgSql.writeLn("""
|
||||
raise exception '[403] insert into ${rawSubTableWithSchema} values(%) not allowed for current subjects % (%)',
|
||||
raise exception '[403] insert into ${rawSubTable} values(%) not allowed for current subjects % (%)',
|
||||
NEW, base.currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger ${rawSubTable}_insert_permission_check_tg
|
||||
before insert on ${rawSubTableWithSchema}
|
||||
before insert on ${rawSubTable}
|
||||
for each row
|
||||
execute procedure ${rawSubTableWithSchema}_insert_permission_check_tf();
|
||||
execute procedure ${rawSubTable}_insert_permission_check_tf();
|
||||
--//
|
||||
""",
|
||||
with("rawSubTableWithSchema", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()),
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
|
||||
}
|
||||
|
||||
private String toStringList(final Set<RbacView.CaseDef> cases) {
|
||||
|
@ -90,11 +90,11 @@ public class RbacView {
|
||||
* @param <E>
|
||||
* a JPA entity class extending RbacObject
|
||||
*/
|
||||
public static <E extends BaseEntity<?>> RbacView rbacViewFor(final String alias, final Class<E> entityClass) {
|
||||
public static <E extends BaseEntity> RbacView rbacViewFor(final String alias, final Class<E> entityClass) {
|
||||
return new RbacView(alias, entityClass);
|
||||
}
|
||||
|
||||
RbacView(final String alias, final Class<? extends BaseEntity<?>> entityClass) {
|
||||
RbacView(final String alias, final Class<? extends BaseEntity> entityClass) {
|
||||
rootEntityAlias = new EntityAlias(alias, entityClass);
|
||||
entityAliases.put(alias, rootEntityAlias);
|
||||
new RbacSubjectReference(CREATOR);
|
||||
@ -121,7 +121,7 @@ public class RbacView {
|
||||
* <p>An identity view is a view which maps an objectUuid to an idName.
|
||||
* The idName should be a human-readable representation of the row, but as short as possible.
|
||||
* The idName must only consist of letters (A-Z, a-z), digits (0-9), dash (-), dot (.) and unserscore '_'.
|
||||
* It's used to create the object-specific-role-names like rbactest.customer#abc:ADMIN - here 'abc' is the idName.
|
||||
* It's used to create the object-specific-role-names like test_customer#abc:ADMIN - here 'abc' is the idName.
|
||||
* The idName not necessarily unique in a table, but it should be avoided.
|
||||
* </p>
|
||||
*
|
||||
@ -287,9 +287,9 @@ public class RbacView {
|
||||
* @param <EC>
|
||||
* a JPA entity class extending RbacObject
|
||||
*/
|
||||
public <EC extends BaseEntity<?>> RbacView importRootEntityAliasProxy(
|
||||
public <EC extends BaseEntity> RbacView importRootEntityAliasProxy(
|
||||
final String aliasName,
|
||||
final Class<? extends BaseEntity<?>> entityClass,
|
||||
final Class<? extends BaseEntity> entityClass,
|
||||
final ColumnValue forCase,
|
||||
final SQL fetchSql,
|
||||
final Column dependsOnColum) {
|
||||
@ -313,7 +313,7 @@ public class RbacView {
|
||||
* a JPA entity class extending RbacObject
|
||||
*/
|
||||
public RbacView importSubEntityAlias(
|
||||
final String aliasName, final Class<? extends BaseEntity<?>> entityClass,
|
||||
final String aliasName, final Class<? extends BaseEntity> entityClass,
|
||||
final SQL fetchSql, final Column dependsOnColum) {
|
||||
importEntityAliasImpl(aliasName, entityClass, usingDefaultCase(), fetchSql, dependsOnColum, true, NOT_NULL);
|
||||
return this;
|
||||
@ -350,14 +350,14 @@ public class RbacView {
|
||||
* a JPA entity class extending RbacObject
|
||||
*/
|
||||
public RbacView importEntityAlias(
|
||||
final String aliasName, final Class<? extends BaseEntity<?>> entityClass, final ColumnValue usingCase,
|
||||
final String aliasName, final Class<? extends BaseEntity> entityClass, final ColumnValue usingCase,
|
||||
final Column dependsOnColum, final SQL fetchSql, final Nullable nullable) {
|
||||
importEntityAliasImpl(aliasName, entityClass, usingCase, fetchSql, dependsOnColum, false, nullable);
|
||||
return this;
|
||||
}
|
||||
|
||||
private EntityAlias importEntityAliasImpl(
|
||||
final String aliasName, final Class<? extends BaseEntity<?>> entityClass, final ColumnValue usingCase,
|
||||
final String aliasName, final Class<? extends BaseEntity> entityClass, final ColumnValue usingCase,
|
||||
final SQL fetchSql, final Column dependsOnColum, boolean asSubEntity, final Nullable nullable) {
|
||||
|
||||
final var entityAlias = ofNullable(entityAliases.get(aliasName))
|
||||
@ -911,13 +911,13 @@ public class RbacView {
|
||||
return distinctGrantDef;
|
||||
}
|
||||
|
||||
record EntityAlias(String aliasName, Class<? extends BaseEntity<?>> entityClass, ColumnValue usingCase, SQL fetchSql, Column dependsOnColum, boolean isSubEntity, Nullable nullable) {
|
||||
record EntityAlias(String aliasName, Class<? extends BaseEntity> entityClass, ColumnValue usingCase, SQL fetchSql, Column dependsOnColum, boolean isSubEntity, Nullable nullable) {
|
||||
|
||||
public EntityAlias(final String aliasName) {
|
||||
this(aliasName, null, null, null, null, false, null);
|
||||
}
|
||||
|
||||
public EntityAlias(final String aliasName, final Class<? extends BaseEntity<?>> entityClass) {
|
||||
public EntityAlias(final String aliasName, final Class<? extends BaseEntity> entityClass) {
|
||||
this(aliasName, entityClass, null, null, null, false, null);
|
||||
}
|
||||
|
||||
@ -964,7 +964,7 @@ public class RbacView {
|
||||
if ( aliasName.equals("rbac.global")) {
|
||||
return "rbac.global"; // TODO: maybe we should introduce a GlobalEntity class?
|
||||
}
|
||||
return qualifiedRealTableName(entityClass);
|
||||
return withoutRvSuffix(entityClass.getAnnotation(Table.class).name());
|
||||
}
|
||||
|
||||
String getRawTableSchemaPrefix() {
|
||||
@ -1010,12 +1010,8 @@ public class RbacView {
|
||||
}
|
||||
}
|
||||
|
||||
public static String qualifiedRealTableName(final Class<? extends BaseEntity<?>> entityClass) {
|
||||
final var tableAnnotation = entityClass.getAnnotation(Table.class);
|
||||
final var schema = tableAnnotation.schema();
|
||||
final var tableName = tableAnnotation.name();
|
||||
final var realTableName = tableName.substring(0, tableName.length() - "_rv".length());
|
||||
return (schema.isEmpty() ? "" : (schema + ".")) + realTableName;
|
||||
public static String withoutRvSuffix(final String tableName) {
|
||||
return tableName.substring(0, tableName.length() - "_rv".length());
|
||||
}
|
||||
|
||||
public enum Role {
|
||||
|
@ -17,7 +17,7 @@ public class RbacViewPostgresGenerator {
|
||||
|
||||
public RbacViewPostgresGenerator(final RbacView forRbacDef) {
|
||||
rbacDef = forRbacDef;
|
||||
liqibaseTagPrefix = rbacDef.getRootEntityAlias().getRawTableNameWithSchema().replace("_", "-").replace(".", "-");
|
||||
liqibaseTagPrefix = rbacDef.getRootEntityAlias().getRawTableNameWithSchema().replace("_", "-");
|
||||
plPgSql.writeLn("""
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by ${generator}, do not amend manually.
|
||||
|
@ -19,11 +19,9 @@ public class StringWriter {
|
||||
writeLn();
|
||||
}
|
||||
|
||||
String writeLn(final String text, final VarDef... varDefs) {
|
||||
final var insertText = indented(new VarReplacer(varDefs).apply(text));
|
||||
string.append(insertText);
|
||||
void writeLn(final String text, final VarDef... varDefs) {
|
||||
string.append( indented( new VarReplacer(varDefs).apply(text) ));
|
||||
writeLn();
|
||||
return insertText;
|
||||
}
|
||||
|
||||
void writeLn() {
|
||||
|
@ -79,10 +79,10 @@ public class RbacGrantsDiagramService {
|
||||
return;
|
||||
}
|
||||
if ( !g.getDescendantIdName().startsWith("role:rbac.global")) {
|
||||
if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(":rbactest.")) {
|
||||
if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(":test_")) {
|
||||
return;
|
||||
}
|
||||
if (!includes.contains(NON_TEST_ENTITIES) && !g.getDescendantIdName().contains(":rbactest.")) {
|
||||
if (!includes.contains(NON_TEST_ENTITIES) && !g.getDescendantIdName().contains(":test_")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(schema = "rbactest", name = "customer_rv")
|
||||
@Table(name = "test_customer_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@ -62,6 +62,6 @@ public class TestCustomerEntity implements BaseEntity<TestCustomerEntity> {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
rbac().generateWithBaseFileName("2-rbactest/201-rbactest-customer/2013-rbactest-customer-rbac");
|
||||
rbac().generateWithBaseFileName("2-test/201-test-customer/2013-test-customer-rbac");
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetc
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(schema = "rbactest", name = "domain_rv")
|
||||
@Table(name = "test_domain_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@ -68,6 +68,6 @@ public class TestDomainEntity implements BaseEntity<TestDomainEntity> {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
rbac().generateWithBaseFileName("2-rbactest/203-rbactest-domain/2033-rbactest-domain-rbac");
|
||||
rbac().generateWithBaseFileName("2-test/203-test-domain/2033-test-domain-rbac");
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(schema = "rbactest", name = "package_rv")
|
||||
@Table(name = "test_package_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@ -69,6 +69,6 @@ public class TestPackageEntity implements BaseEntity<TestPackageEntity> {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
rbac().generateWithBaseFileName("2-rbactest/202-rbactest-package/2023-rbactest-package-rbac");
|
||||
rbac().generateWithBaseFileName("2-test/202-test-package/2023-test-package-rbac");
|
||||
}
|
||||
}
|
||||
|
@ -4,16 +4,5 @@
|
||||
-- ============================================================================
|
||||
--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;
|
||||
--//
|
||||
|
@ -6,31 +6,15 @@
|
||||
--changeset michael.hoennig:table-columns-function endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create or replace function base.tableColumnNames( ofTableName text )
|
||||
create or replace function base.tableColumnNames( tableName text )
|
||||
returns text
|
||||
stable
|
||||
language 'plpgsql' as $$
|
||||
declare
|
||||
tableName text;
|
||||
tableSchema text;
|
||||
columns text[];
|
||||
declare columns text[];
|
||||
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
|
||||
from information_schema.columns
|
||||
where table_name = tableName
|
||||
and table_schema = tableSchema));
|
||||
assert cardinality(columns) > 0, 'cannot determine columns of table ' || ofTableName ||
|
||||
'("' || tableSchema || '"."' || tableName || '")';
|
||||
from information_schema.columns
|
||||
where table_name = tableName));
|
||||
return array_to_string(columns, ', ');
|
||||
end; $$
|
||||
--//
|
||||
|
@ -127,7 +127,6 @@ begin
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:context-base.ASSUMED-ROLES endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
@ -1,18 +0,0 @@
|
||||
--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; $$;
|
||||
--//
|
@ -77,11 +77,9 @@ create or replace function base.tx_journal_trigger()
|
||||
declare
|
||||
curTask text;
|
||||
curTxId xid8;
|
||||
tableSchemaAndName text;
|
||||
begin
|
||||
curTask := base.currentTask();
|
||||
curTxId := pg_current_xact_id();
|
||||
tableSchemaAndName := base.combine_table_schema_and_name(tg_table_schema, tg_table_name);
|
||||
|
||||
insert
|
||||
into base.tx_context (txId, txTimestamp, currentSubject, assumedRoles, currentTask, currentRequest)
|
||||
@ -92,20 +90,20 @@ begin
|
||||
case tg_op
|
||||
when 'INSERT' then insert
|
||||
into base.tx_journal
|
||||
values (curTxId, tableSchemaAndName,
|
||||
new.uuid, tg_op::base.tx_operation,
|
||||
values (curTxId,
|
||||
tg_table_name, new.uuid, tg_op::base.tx_operation,
|
||||
to_jsonb(new));
|
||||
when 'UPDATE' then insert
|
||||
into base.tx_journal
|
||||
values (curTxId, tableSchemaAndName,
|
||||
old.uuid, tg_op::base.tx_operation,
|
||||
values (curTxId,
|
||||
tg_table_name, old.uuid, tg_op::base.tx_operation,
|
||||
base.jsonb_changes_delta(to_jsonb(old), to_jsonb(new)));
|
||||
when 'DELETE' then insert
|
||||
into base.tx_journal
|
||||
values (curTxId,tableSchemaAndName,
|
||||
old.uuid, 'DELETE'::base.tx_operation,
|
||||
values (curTxId,
|
||||
tg_table_name, old.uuid, 'DELETE'::base.tx_operation,
|
||||
null::jsonb);
|
||||
else raise exception 'Trigger op % not supported for %.', tg_op, tableSchemaAndName;
|
||||
else raise exception 'Trigger op % not supported for %.', tg_op, tg_table_name;
|
||||
end case;
|
||||
return null;
|
||||
end; $$;
|
||||
|
@ -81,8 +81,8 @@ begin
|
||||
"alive" := false;
|
||||
end if;
|
||||
|
||||
sql := format('INSERT INTO %3$I_ex VALUES (DEFAULT, pg_current_xact_id(), %1$L, %2$L, $1.*)',
|
||||
TG_OP, alive, base.combine_table_schema_and_name(tg_table_schema, tg_table_name)::name);
|
||||
sql := format('INSERT INTO %3$I_ex VALUES (DEFAULT, pg_current_xact_id(), %1$L, %2$L, $1.*)', TG_OP, alive, TG_TABLE_NAME);
|
||||
raise notice 'sql: %', sql;
|
||||
execute sql using "row";
|
||||
|
||||
return "row";
|
||||
|
@ -3,7 +3,9 @@
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:rbac-base-REFERENCE endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
|
||||
*/
|
||||
create type rbac.ReferenceType as enum ('rbac.subject', 'rbac.role', 'rbac.permission');
|
||||
|
||||
create table rbac.reference
|
||||
@ -118,20 +120,18 @@ create or replace function rbac.insert_related_object()
|
||||
strict as $$
|
||||
declare
|
||||
objectUuid uuid;
|
||||
tableSchemaAndName text;
|
||||
begin
|
||||
tableSchemaAndName := base.combine_table_schema_and_name(TG_TABLE_SCHEMA, TG_TABLE_NAME);
|
||||
if TG_OP = 'INSERT' then
|
||||
if NEW.uuid is null then
|
||||
insert
|
||||
into rbac.object (objectTable)
|
||||
values (tableSchemaAndName)
|
||||
values (TG_TABLE_NAME)
|
||||
returning uuid into objectUuid;
|
||||
NEW.uuid = objectUuid;
|
||||
else
|
||||
insert
|
||||
into rbac.object (uuid, objectTable)
|
||||
values (NEW.uuid, tableSchemaAndName)
|
||||
values (NEW.uuid, TG_TABLE_NAME)
|
||||
returning uuid into objectUuid;
|
||||
end if;
|
||||
return NEW;
|
||||
|
@ -20,7 +20,7 @@ begin
|
||||
return currentSubjectOrAssumedRolesUuids[1];
|
||||
end; $$;
|
||||
|
||||
create or replace procedure rbac.grantRoleToUserUnchecked(grantedByRoleUuid uuid, grantedRoleUuid uuid, subjectUuid uuid, doAssume boolean = true)
|
||||
create or replace procedure rbac.grantRoleToSubjectUnchecked(grantedByRoleUuid uuid, grantedRoleUuid uuid, subjectUuid uuid, doAssume boolean = true)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
perform rbac.assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'rbac.role');
|
||||
|
@ -57,7 +57,7 @@ begin
|
||||
end if;
|
||||
foreach subjectUuid in array subjectUuids
|
||||
loop
|
||||
call rbac.grantRoleToUserUnchecked(userGrantsByRoleUuid, roleUuid, subjectUuid);
|
||||
call rbac.grantRoleToSubjectUnchecked(userGrantsByRoleUuid, roleUuid, subjectUuid);
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
|
@ -8,40 +8,26 @@
|
||||
create or replace procedure rbac.generateRelatedRbacObject(targetTable varchar)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
targetTableName text;
|
||||
targetSchemaPrefix text;
|
||||
createInsertTriggerSQL text;
|
||||
createDeleteTriggerSQL text;
|
||||
begin
|
||||
if POSITION('.' IN targetTable) > 0 then
|
||||
targetSchemaPrefix := SPLIT_PART(targetTable, '.', 1) || '.';
|
||||
targetTableName := SPLIT_PART(targetTable, '.', 2);
|
||||
else
|
||||
targetSchemaPrefix := '';
|
||||
targetTableName := targetTable;
|
||||
end if;
|
||||
|
||||
if targetSchemaPrefix = '' and targetTableName = 'customer' then
|
||||
raise exception 'missing targetShemaPrefix: %', targetTable;
|
||||
end if;
|
||||
|
||||
createInsertTriggerSQL = format($sql$
|
||||
create trigger createRbacObjectFor_%s_insert_tg_1058_25
|
||||
before insert on %s%s
|
||||
create trigger createRbacObjectFor_%s_Trigger
|
||||
before insert on %s
|
||||
for each row
|
||||
execute procedure rbac.insert_related_object();
|
||||
$sql$, targetTableName, targetSchemaPrefix, targetTableName);
|
||||
$sql$, targetTable, targetTable);
|
||||
execute createInsertTriggerSQL;
|
||||
|
||||
createDeleteTriggerSQL = format($sql$
|
||||
create trigger createRbacObjectFor_%s_delete_tg_1058_35
|
||||
after delete on %s%s
|
||||
create trigger delete_related_rbac_rules_for_%s_tg
|
||||
after delete
|
||||
on %s
|
||||
for each row
|
||||
execute procedure rbac.delete_related_rbac_rules_tf();
|
||||
$sql$, targetTableName, targetSchemaPrefix, targetTableName);
|
||||
$sql$, targetTable, targetTable);
|
||||
execute createDeleteTriggerSQL;
|
||||
end;
|
||||
$$;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
@ -190,7 +176,7 @@ begin
|
||||
*/
|
||||
sql := format($sql$
|
||||
create or replace view %1$s_rv as
|
||||
with accessible_uuids as (
|
||||
with accessible_%1$s_uuids as (
|
||||
with recursive
|
||||
recursive_grants as
|
||||
(select distinct rbac.grants.descendantuuid,
|
||||
@ -223,7 +209,7 @@ begin
|
||||
)
|
||||
select target.*
|
||||
from %1$s as target
|
||||
where target.uuid in (select * from accessible_uuids)
|
||||
where target.uuid in (select * from accessible_%1$s_uuids)
|
||||
order by %2$s;
|
||||
|
||||
grant all privileges on %1$s_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||
@ -233,9 +219,9 @@ begin
|
||||
/**
|
||||
Instead of insert trigger function for the restricted view.
|
||||
*/
|
||||
newColumns := 'new.' || replace(columnNames, ', ', ', new.');
|
||||
newColumns := 'new.' || replace(columnNames, ',', ', new.');
|
||||
sql := format($sql$
|
||||
create function %1$s_instead_of_insert_tf()
|
||||
create or replace function %1$sInsert()
|
||||
returns trigger
|
||||
language plpgsql as $f$
|
||||
declare
|
||||
@ -254,11 +240,11 @@ begin
|
||||
Creates an instead of insert trigger for the restricted view.
|
||||
*/
|
||||
sql := format($sql$
|
||||
create trigger instead_of_insert_tg
|
||||
create trigger %1$sInsert_tg
|
||||
instead of insert
|
||||
on %1$s_rv
|
||||
for each row
|
||||
execute function %1$s_instead_of_insert_tf();
|
||||
execute function %1$sInsert();
|
||||
$sql$, targetTable);
|
||||
execute sql;
|
||||
|
||||
@ -266,7 +252,7 @@ begin
|
||||
Instead of delete trigger function for the restricted view.
|
||||
*/
|
||||
sql := format($sql$
|
||||
create function %1$s_instead_of_delete_tf()
|
||||
create or replace function %1$sDelete()
|
||||
returns trigger
|
||||
language plpgsql as $f$
|
||||
begin
|
||||
@ -283,11 +269,11 @@ begin
|
||||
Creates an instead of delete trigger for the restricted view.
|
||||
*/
|
||||
sql := format($sql$
|
||||
create trigger instead_of_delete_tg
|
||||
create trigger %1$sDelete_tg
|
||||
instead of delete
|
||||
on %1$s_rv
|
||||
for each row
|
||||
execute function %1$s_instead_of_delete_tf();
|
||||
execute function %1$sDelete();
|
||||
$sql$, targetTable);
|
||||
execute sql;
|
||||
|
||||
@ -297,7 +283,7 @@ begin
|
||||
*/
|
||||
if columnUpdates is not null then
|
||||
sql := format($sql$
|
||||
create function %1$s_instead_of_update_tf()
|
||||
create or replace function %1$sUpdate()
|
||||
returns trigger
|
||||
language plpgsql as $f$
|
||||
begin
|
||||
@ -316,11 +302,11 @@ begin
|
||||
Creates an instead of delete trigger for the restricted view.
|
||||
*/
|
||||
sql = format($sql$
|
||||
create trigger instead_of_update_tg
|
||||
create trigger %1$sUpdate_tg
|
||||
instead of update
|
||||
on %1$s_rv
|
||||
for each row
|
||||
execute function %1$s_instead_of_update_tf();
|
||||
execute function %1$sUpdate();
|
||||
$sql$, targetTable);
|
||||
execute sql;
|
||||
end if;
|
||||
|
@ -158,8 +158,8 @@ do language plpgsql $$
|
||||
call base.defineContext('creating fake test-realm admin users', null, null, null);
|
||||
|
||||
admins = rbac.findRoleId(rbac.globalAdmin());
|
||||
call rbac.grantRoleToUserUnchecked(admins, admins, rbac.create_subject('superuser-alex@hostsharing.net'));
|
||||
call rbac.grantRoleToUserUnchecked(admins, admins, rbac.create_subject('superuser-fran@hostsharing.net'));
|
||||
call rbac.grantRoleToSubjectUnchecked(admins, admins, rbac.create_subject('superuser-alex@hostsharing.net'));
|
||||
call rbac.grantRoleToSubjectUnchecked(admins, admins, rbac.create_subject('superuser-fran@hostsharing.net'));
|
||||
perform rbac.create_subject('selfregistered-user-drew@hostsharing.org');
|
||||
perform rbac.create_subject('selfregistered-test-user@hostsharing.org');
|
||||
end;
|
||||
|
@ -1,8 +0,0 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:rbactest-SCHEMA endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
CREATE SCHEMA rbactest; -- just 'test' does not work, databasechangelog gets emptied or deleted
|
||||
--//
|
@ -1,13 +1,13 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:rbactest-customer-MAIN-TABLE endDelimiter:--//
|
||||
--changeset michael.hoennig:test-customer-MAIN-TABLE endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create table if not exists rbactest.customer
|
||||
create table if not exists test_customer
|
||||
(
|
||||
uuid uuid unique references rbac.object (uuid),
|
||||
version int not null default 0,
|
||||
version int not null default 0,
|
||||
reference int not null unique check (reference between 10000 and 99999),
|
||||
prefix character(3) unique,
|
||||
adminUserName varchar(63)
|
@ -3,21 +3,21 @@
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RbacObjectGenerator:rbactest-customer-rbac-OBJECT endDelimiter:--//
|
||||
--changeset RbacObjectGenerator:test-customer-rbac-OBJECT endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call rbac.generateRelatedRbacObject('rbactest.customer');
|
||||
call rbac.generateRelatedRbacObject('test_customer');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RbacRoleDescriptorsGenerator:rbactest-customer-rbac-ROLE-DESCRIPTORS endDelimiter:--//
|
||||
--changeset RbacRoleDescriptorsGenerator:test-customer-rbac-ROLE-DESCRIPTORS endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call rbac.generateRbacRoleDescriptors('testCustomer', 'rbactest.customer');
|
||||
call rbac.generateRbacRoleDescriptors('testCustomer', 'test_customer');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RolesGrantsAndPermissionsGenerator:rbactest-customer-rbac-insert-trigger endDelimiter:--//
|
||||
--changeset RolesGrantsAndPermissionsGenerator:test-customer-rbac-insert-trigger endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
@ -25,7 +25,7 @@ call rbac.generateRbacRoleDescriptors('testCustomer', 'rbactest.customer');
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForTestCustomer(
|
||||
NEW rbactest.customer
|
||||
NEW test_customer
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
@ -57,7 +57,7 @@ begin
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new rbactest.customer row.
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new test_customer row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForTestCustomer_tf()
|
||||
@ -70,68 +70,68 @@ begin
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForTestCustomer_tg
|
||||
after insert on rbactest.customer
|
||||
after insert on test_customer
|
||||
for each row
|
||||
execute procedure insertTriggerForTestCustomer_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset InsertTriggerGenerator:rbactest-customer-rbac-GRANTING-INSERT-PERMISSION endDelimiter:--//
|
||||
--changeset InsertTriggerGenerator:test-customer-rbac-GRANTING-INSERT-PERMISSION endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
-- granting INSERT permission to rbac.global ----------------------------
|
||||
|
||||
/*
|
||||
Grants INSERT INTO rbactest.customer permissions to specified role of pre-existing rbac.global rows.
|
||||
Grants INSERT INTO test_customer permissions to specified role of pre-existing rbac.global rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row rbac.global;
|
||||
begin
|
||||
call base.defineContext('create INSERT INTO rbactest.customer permissions for pre-exising rbac.global rows');
|
||||
call base.defineContext('create INSERT INTO test_customer permissions for pre-exising rbac.global rows');
|
||||
|
||||
FOR row IN SELECT * FROM rbac.global
|
||||
-- unconditional for all rows in that table
|
||||
LOOP
|
||||
call rbac.grantPermissionToRole(
|
||||
rbac.createPermission(row.uuid, 'INSERT', 'rbactest.customer'),
|
||||
rbac.createPermission(row.uuid, 'INSERT', 'test_customer'),
|
||||
rbac.globalADMIN());
|
||||
END LOOP;
|
||||
end;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Grants rbactest.customer INSERT permission to specified role of new global rows.
|
||||
Grants test_customer INSERT permission to specified role of new global rows.
|
||||
*/
|
||||
create or replace function rbactest.new_customer_grants_insert_to_global_tf()
|
||||
create or replace function rbac.new_test_customer_grants_insert_to_global_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
-- unconditional for all rows in that table
|
||||
call rbac.grantPermissionToRole(
|
||||
rbac.createPermission(NEW.uuid, 'INSERT', 'rbactest.customer'),
|
||||
rbac.createPermission(NEW.uuid, 'INSERT', 'test_customer'),
|
||||
rbac.globalADMIN());
|
||||
-- end.
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_new_customer_grants_after_insert_tg
|
||||
create trigger z_new_test_customer_grants_after_insert_tg
|
||||
after insert on rbac.global
|
||||
for each row
|
||||
execute procedure rbactest.new_customer_grants_insert_to_global_tf();
|
||||
execute procedure rbac.new_test_customer_grants_insert_to_global_tf();
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset InsertTriggerGenerator:rbactest-customer-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
|
||||
--changeset InsertTriggerGenerator:test_customer-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Checks if the user respectively the assumed roles are allowed to insert a row to rbactest.customer.
|
||||
Checks if the user respectively the assumed roles are allowed to insert a row to test_customer.
|
||||
*/
|
||||
create or replace function rbactest.customer_insert_permission_check_tf()
|
||||
create or replace function test_customer_insert_permission_check_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
declare
|
||||
@ -142,22 +142,22 @@ begin
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
raise exception '[403] insert into rbactest.customer values(%) not allowed for current subjects % (%)',
|
||||
raise exception '[403] insert into test_customer values(%) not allowed for current subjects % (%)',
|
||||
NEW, base.currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger customer_insert_permission_check_tg
|
||||
before insert on rbactest.customer
|
||||
create trigger test_customer_insert_permission_check_tg
|
||||
before insert on test_customer
|
||||
for each row
|
||||
execute procedure rbactest.customer_insert_permission_check_tf();
|
||||
execute procedure test_customer_insert_permission_check_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RbacIdentityViewGenerator:rbactest-customer-rbac-IDENTITY-VIEW endDelimiter:--//
|
||||
--changeset RbacIdentityViewGenerator:test-customer-rbac-IDENTITY-VIEW endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call rbac.generateRbacIdentityViewFromProjection('rbactest.customer',
|
||||
call rbac.generateRbacIdentityViewFromProjection('test_customer',
|
||||
$idName$
|
||||
prefix
|
||||
$idName$);
|
||||
@ -165,9 +165,9 @@ call rbac.generateRbacIdentityViewFromProjection('rbactest.customer',
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:rbactest-customer-rbac-RESTRICTED-VIEW endDelimiter:--//
|
||||
--changeset RbacRestrictedViewGenerator:test-customer-rbac-RESTRICTED-VIEW endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call rbac.generateRbacRestrictedView('rbactest.customer',
|
||||
call rbac.generateRbacRestrictedView('test_customer',
|
||||
$orderBy$
|
||||
reference
|
||||
$orderBy$,
|
@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:rbactest-customer-TEST-DATA-GENERATOR endDelimiter:--//
|
||||
--changeset michael.hoennig:test-customer-TEST-DATA-GENERATOR endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Generates a customer reference number for a given test data counter.
|
||||
@ -28,18 +28,18 @@ declare
|
||||
custRowId uuid;
|
||||
custAdminName varchar;
|
||||
custAdminUuid uuid;
|
||||
newCust rbactest.customer;
|
||||
newCust test_customer;
|
||||
begin
|
||||
custRowId = uuid_generate_v4();
|
||||
custAdminName = 'customer-admin@' || custPrefix || '.example.com';
|
||||
custAdminUuid = rbac.create_subject(custAdminName);
|
||||
|
||||
insert
|
||||
into rbactest.customer (reference, prefix, adminUserName)
|
||||
into test_customer (reference, prefix, adminUserName)
|
||||
values (custReference, custPrefix, custAdminName);
|
||||
|
||||
select * into newCust
|
||||
from rbactest.customer where reference=custReference;
|
||||
from test_customer where reference=custReference;
|
||||
call rbac.grantRoleToSubject(
|
||||
rbac.getRoleId(testCustomerOwner(newCust)),
|
||||
rbac.getRoleId(testCustomerAdmin(newCust)),
|
||||
@ -67,7 +67,7 @@ end; $$;
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:rbactest-customer-TEST-DATA-GENERATION –context=dev,tc endDelimiter:--//
|
||||
--changeset michael.hoennig:test-customer-TEST-DATA-GENERATION –context=dev,tc endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
do language plpgsql $$
|
@ -1,14 +1,14 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:rbactest-package-MAIN-TABLE endDelimiter:--//
|
||||
--changeset michael.hoennig:test-package-MAIN-TABLE endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create table if not exists rbactest.package
|
||||
create table if not exists test_package
|
||||
(
|
||||
uuid uuid unique references rbac.object (uuid),
|
||||
version int not null default 0,
|
||||
customerUuid uuid references rbactest.customer (uuid),
|
||||
customerUuid uuid references test_customer (uuid),
|
||||
name varchar(5),
|
||||
description varchar(96)
|
||||
);
|
@ -3,21 +3,21 @@
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RbacObjectGenerator:rbactest-package-rbac-OBJECT endDelimiter:--//
|
||||
--changeset RbacObjectGenerator:test-package-rbac-OBJECT endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call rbac.generateRelatedRbacObject('rbactest.package');
|
||||
call rbac.generateRelatedRbacObject('test_package');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RbacRoleDescriptorsGenerator:rbactest-package-rbac-ROLE-DESCRIPTORS endDelimiter:--//
|
||||
--changeset RbacRoleDescriptorsGenerator:test-package-rbac-ROLE-DESCRIPTORS endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call rbac.generateRbacRoleDescriptors('testPackage', 'rbactest.package');
|
||||
call rbac.generateRbacRoleDescriptors('testPackage', 'test_package');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RolesGrantsAndPermissionsGenerator:rbactest-package-rbac-insert-trigger endDelimiter:--//
|
||||
--changeset RolesGrantsAndPermissionsGenerator:test-package-rbac-insert-trigger endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
@ -25,17 +25,17 @@ call rbac.generateRbacRoleDescriptors('testPackage', 'rbactest.package');
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForTestPackage(
|
||||
NEW rbactest.package
|
||||
NEW test_package
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
newCustomer rbactest.customer;
|
||||
newCustomer test_customer;
|
||||
|
||||
begin
|
||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM rbactest.customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
||||
SELECT * FROM test_customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
||||
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s', NEW.customerUuid);
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@ begin
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new rbactest.package row.
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new test_package row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForTestPackage_tf()
|
||||
@ -74,14 +74,14 @@ begin
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForTestPackage_tg
|
||||
after insert on rbactest.package
|
||||
after insert on test_package
|
||||
for each row
|
||||
execute procedure insertTriggerForTestPackage_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RolesGrantsAndPermissionsGenerator:rbactest-package-rbac-update-trigger endDelimiter:--//
|
||||
--changeset RolesGrantsAndPermissionsGenerator:test-package-rbac-update-trigger endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
@ -89,22 +89,22 @@ execute procedure insertTriggerForTestPackage_tf();
|
||||
*/
|
||||
|
||||
create or replace procedure updateRbacRulesForTestPackage(
|
||||
OLD rbactest.package,
|
||||
NEW rbactest.package
|
||||
OLD test_package,
|
||||
NEW test_package
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
oldCustomer rbactest.customer;
|
||||
newCustomer rbactest.customer;
|
||||
oldCustomer test_customer;
|
||||
newCustomer test_customer;
|
||||
|
||||
begin
|
||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM rbactest.customer WHERE uuid = OLD.customerUuid INTO oldCustomer;
|
||||
SELECT * FROM test_customer WHERE uuid = OLD.customerUuid INTO oldCustomer;
|
||||
assert oldCustomer.uuid is not null, format('oldCustomer must not be null for OLD.customerUuid = %s', OLD.customerUuid);
|
||||
|
||||
SELECT * FROM rbactest.customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
||||
SELECT * FROM test_customer WHERE uuid = NEW.customerUuid INTO newCustomer;
|
||||
assert newCustomer.uuid is not null, format('newCustomer must not be null for NEW.customerUuid = %s', NEW.customerUuid);
|
||||
|
||||
|
||||
@ -122,7 +122,7 @@ begin
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to re-wire the grant structure for a new rbactest.package row.
|
||||
AFTER INSERT TRIGGER to re-wire the grant structure for a new test_package row.
|
||||
*/
|
||||
|
||||
create or replace function updateTriggerForTestPackage_tf()
|
||||
@ -135,94 +135,94 @@ begin
|
||||
end; $$;
|
||||
|
||||
create trigger updateTriggerForTestPackage_tg
|
||||
after update on rbactest.package
|
||||
after update on test_package
|
||||
for each row
|
||||
execute procedure updateTriggerForTestPackage_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset InsertTriggerGenerator:rbactest-package-rbac-GRANTING-INSERT-PERMISSION endDelimiter:--//
|
||||
--changeset InsertTriggerGenerator:test-package-rbac-GRANTING-INSERT-PERMISSION endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
-- granting INSERT permission to rbactest.customer ----------------------------
|
||||
-- granting INSERT permission to test_customer ----------------------------
|
||||
|
||||
/*
|
||||
Grants INSERT INTO rbactest.package permissions to specified role of pre-existing rbactest.customer rows.
|
||||
Grants INSERT INTO test_package permissions to specified role of pre-existing test_customer rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row rbactest.customer;
|
||||
row test_customer;
|
||||
begin
|
||||
call base.defineContext('create INSERT INTO rbactest.package permissions for pre-exising rbactest.customer rows');
|
||||
call base.defineContext('create INSERT INTO test_package permissions for pre-exising test_customer rows');
|
||||
|
||||
FOR row IN SELECT * FROM rbactest.customer
|
||||
FOR row IN SELECT * FROM test_customer
|
||||
-- unconditional for all rows in that table
|
||||
LOOP
|
||||
call rbac.grantPermissionToRole(
|
||||
rbac.createPermission(row.uuid, 'INSERT', 'rbactest.package'),
|
||||
rbac.createPermission(row.uuid, 'INSERT', 'test_package'),
|
||||
testCustomerADMIN(row));
|
||||
END LOOP;
|
||||
end;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Grants rbactest.package INSERT permission to specified role of new customer rows.
|
||||
Grants test_package INSERT permission to specified role of new test_customer rows.
|
||||
*/
|
||||
create or replace function rbactest.new_package_grants_insert_to_customer_tf()
|
||||
create or replace function new_test_package_grants_insert_to_test_customer_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
-- unconditional for all rows in that table
|
||||
call rbac.grantPermissionToRole(
|
||||
rbac.createPermission(NEW.uuid, 'INSERT', 'rbactest.package'),
|
||||
rbac.createPermission(NEW.uuid, 'INSERT', 'test_package'),
|
||||
testCustomerADMIN(NEW));
|
||||
-- end.
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_new_package_grants_after_insert_tg
|
||||
after insert on rbactest.customer
|
||||
create trigger z_new_test_package_grants_after_insert_tg
|
||||
after insert on test_customer
|
||||
for each row
|
||||
execute procedure rbactest.new_package_grants_insert_to_customer_tf();
|
||||
execute procedure new_test_package_grants_insert_to_test_customer_tf();
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset InsertTriggerGenerator:rbactest-package-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
|
||||
--changeset InsertTriggerGenerator:test_package-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Checks if the user respectively the assumed roles are allowed to insert a row to rbactest.package.
|
||||
Checks if the user respectively the assumed roles are allowed to insert a row to test_package.
|
||||
*/
|
||||
create or replace function rbactest.package_insert_permission_check_tf()
|
||||
create or replace function test_package_insert_permission_check_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
declare
|
||||
superObjectUuid uuid;
|
||||
begin
|
||||
-- check INSERT permission via direct foreign key: NEW.customerUuid
|
||||
if rbac.hasInsertPermission(NEW.customerUuid, 'rbactest.package') then
|
||||
if rbac.hasInsertPermission(NEW.customerUuid, 'test_package') then
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
raise exception '[403] insert into rbactest.package values(%) not allowed for current subjects % (%)',
|
||||
raise exception '[403] insert into test_package values(%) not allowed for current subjects % (%)',
|
||||
NEW, base.currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger package_insert_permission_check_tg
|
||||
before insert on rbactest.package
|
||||
create trigger test_package_insert_permission_check_tg
|
||||
before insert on test_package
|
||||
for each row
|
||||
execute procedure rbactest.package_insert_permission_check_tf();
|
||||
execute procedure test_package_insert_permission_check_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RbacIdentityViewGenerator:rbactest-package-rbac-IDENTITY-VIEW endDelimiter:--//
|
||||
--changeset RbacIdentityViewGenerator:test-package-rbac-IDENTITY-VIEW endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call rbac.generateRbacIdentityViewFromProjection('rbactest.package',
|
||||
call rbac.generateRbacIdentityViewFromProjection('test_package',
|
||||
$idName$
|
||||
name
|
||||
$idName$);
|
||||
@ -230,9 +230,9 @@ call rbac.generateRbacIdentityViewFromProjection('rbactest.package',
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:rbactest-package-rbac-RESTRICTED-VIEW endDelimiter:--//
|
||||
--changeset RbacRestrictedViewGenerator:test-package-rbac-RESTRICTED-VIEW endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call rbac.generateRbacRestrictedView('rbactest.package',
|
||||
call rbac.generateRbacRestrictedView('test_package',
|
||||
$orderBy$
|
||||
name
|
||||
$orderBy$,
|
@ -1,7 +1,7 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:rbactest-package-TEST-DATA-GENERATOR endDelimiter:--//
|
||||
--changeset michael.hoennig:test-package-TEST-DATA-GENERATOR endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Creates the given number of test packages for the given customer.
|
||||
@ -9,23 +9,23 @@
|
||||
create or replace procedure createPackageTestData(customerPrefix varchar, pacCount int)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
cust rbactest.customer;
|
||||
cust test_customer;
|
||||
custAdminUser varchar;
|
||||
custAdminRole varchar;
|
||||
pacName varchar;
|
||||
pac rbactest.package;
|
||||
pac test_package;
|
||||
begin
|
||||
select * from rbactest.customer where rbactest.customer.prefix = customerPrefix into cust;
|
||||
select * from test_customer where test_customer.prefix = customerPrefix into cust;
|
||||
|
||||
for t in 0..(pacCount-1)
|
||||
loop
|
||||
pacName = cust.prefix || to_char(t, 'fm00');
|
||||
custAdminUser = 'customer-admin@' || cust.prefix || '.example.com';
|
||||
custAdminRole = 'rbactest.customer#' || cust.prefix || ':ADMIN';
|
||||
custAdminRole = 'test_customer#' || cust.prefix || ':ADMIN';
|
||||
call base.defineContext('creating RBAC test package', null, 'superuser-fran@hostsharing.net', custAdminRole);
|
||||
|
||||
insert
|
||||
into rbactest.package (customerUuid, name, description)
|
||||
into test_package (customerUuid, name, description)
|
||||
values (cust.uuid, pacName, 'Here you can add your own description of package ' || pacName || '.')
|
||||
returning * into pac;
|
||||
|
||||
@ -44,9 +44,9 @@ end; $$;
|
||||
create or replace procedure createPackageTestData()
|
||||
language plpgsql as $$
|
||||
declare
|
||||
cust rbactest.customer;
|
||||
cust test_customer;
|
||||
begin
|
||||
for cust in (select * from rbactest.customer)
|
||||
for cust in (select * from test_customer)
|
||||
loop
|
||||
continue when cust.reference >= 90000; -- reserved for functional testing
|
||||
call createPackageTestData(cust.prefix, 3);
|
||||
@ -59,7 +59,7 @@ $$;
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:rbactest-package-TEST-DATA-GENERATION –context=dev,tc endDelimiter:--//
|
||||
--changeset michael.hoennig:test-package-TEST-DATA-GENERATION –context=dev,tc endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
do language plpgsql $$
|
@ -1,13 +1,13 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:rbactest-domain-MAIN-TABLE endDelimiter:--//
|
||||
--changeset michael.hoennig:test-domain-MAIN-TABLE endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create table if not exists rbactest.domain
|
||||
create table if not exists test_domain
|
||||
(
|
||||
uuid uuid unique references rbac.object (uuid),
|
||||
packageUuid uuid references rbactest.package (uuid),
|
||||
packageUuid uuid references test_package (uuid),
|
||||
name character varying(253),
|
||||
description character varying(96)
|
||||
);
|
@ -3,21 +3,21 @@
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RbacObjectGenerator:rbactest-domain-rbac-OBJECT endDelimiter:--//
|
||||
--changeset RbacObjectGenerator:test-domain-rbac-OBJECT endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call rbac.generateRelatedRbacObject('rbactest.domain');
|
||||
call rbac.generateRelatedRbacObject('test_domain');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RbacRoleDescriptorsGenerator:rbactest-domain-rbac-ROLE-DESCRIPTORS endDelimiter:--//
|
||||
--changeset RbacRoleDescriptorsGenerator:test-domain-rbac-ROLE-DESCRIPTORS endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call rbac.generateRbacRoleDescriptors('testDomain', 'rbactest.domain');
|
||||
call rbac.generateRbacRoleDescriptors('testDomain', 'test_domain');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RolesGrantsAndPermissionsGenerator:rbactest-domain-rbac-insert-trigger endDelimiter:--//
|
||||
--changeset RolesGrantsAndPermissionsGenerator:test-domain-rbac-insert-trigger endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
@ -25,17 +25,17 @@ call rbac.generateRbacRoleDescriptors('testDomain', 'rbactest.domain');
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForTestDomain(
|
||||
NEW rbactest.domain
|
||||
NEW test_domain
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
newPackage rbactest.package;
|
||||
newPackage test_package;
|
||||
|
||||
begin
|
||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM rbactest.package WHERE uuid = NEW.packageUuid INTO newPackage;
|
||||
SELECT * FROM test_package WHERE uuid = NEW.packageUuid INTO newPackage;
|
||||
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s', NEW.packageUuid);
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@ begin
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new rbactest.domain row.
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new test_domain row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForTestDomain_tf()
|
||||
@ -70,14 +70,14 @@ begin
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForTestDomain_tg
|
||||
after insert on rbactest.domain
|
||||
after insert on test_domain
|
||||
for each row
|
||||
execute procedure insertTriggerForTestDomain_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RolesGrantsAndPermissionsGenerator:rbactest-domain-rbac-update-trigger endDelimiter:--//
|
||||
--changeset RolesGrantsAndPermissionsGenerator:test-domain-rbac-update-trigger endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
@ -85,22 +85,22 @@ execute procedure insertTriggerForTestDomain_tf();
|
||||
*/
|
||||
|
||||
create or replace procedure updateRbacRulesForTestDomain(
|
||||
OLD rbactest.domain,
|
||||
NEW rbactest.domain
|
||||
OLD test_domain,
|
||||
NEW test_domain
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
oldPackage rbactest.package;
|
||||
newPackage rbactest.package;
|
||||
oldPackage test_package;
|
||||
newPackage test_package;
|
||||
|
||||
begin
|
||||
call rbac.enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM rbactest.package WHERE uuid = OLD.packageUuid INTO oldPackage;
|
||||
SELECT * FROM test_package WHERE uuid = OLD.packageUuid INTO oldPackage;
|
||||
assert oldPackage.uuid is not null, format('oldPackage must not be null for OLD.packageUuid = %s', OLD.packageUuid);
|
||||
|
||||
SELECT * FROM rbactest.package WHERE uuid = NEW.packageUuid INTO newPackage;
|
||||
SELECT * FROM test_package WHERE uuid = NEW.packageUuid INTO newPackage;
|
||||
assert newPackage.uuid is not null, format('newPackage must not be null for NEW.packageUuid = %s', NEW.packageUuid);
|
||||
|
||||
|
||||
@ -121,7 +121,7 @@ begin
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to re-wire the grant structure for a new rbactest.domain row.
|
||||
AFTER INSERT TRIGGER to re-wire the grant structure for a new test_domain row.
|
||||
*/
|
||||
|
||||
create or replace function updateTriggerForTestDomain_tf()
|
||||
@ -134,94 +134,94 @@ begin
|
||||
end; $$;
|
||||
|
||||
create trigger updateTriggerForTestDomain_tg
|
||||
after update on rbactest.domain
|
||||
after update on test_domain
|
||||
for each row
|
||||
execute procedure updateTriggerForTestDomain_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset InsertTriggerGenerator:rbactest-domain-rbac-GRANTING-INSERT-PERMISSION endDelimiter:--//
|
||||
--changeset InsertTriggerGenerator:test-domain-rbac-GRANTING-INSERT-PERMISSION endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
-- granting INSERT permission to rbactest.package ----------------------------
|
||||
-- granting INSERT permission to test_package ----------------------------
|
||||
|
||||
/*
|
||||
Grants INSERT INTO rbactest.domain permissions to specified role of pre-existing rbactest.package rows.
|
||||
Grants INSERT INTO test_domain permissions to specified role of pre-existing test_package rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row rbactest.package;
|
||||
row test_package;
|
||||
begin
|
||||
call base.defineContext('create INSERT INTO rbactest.domain permissions for pre-exising rbactest.package rows');
|
||||
call base.defineContext('create INSERT INTO test_domain permissions for pre-exising test_package rows');
|
||||
|
||||
FOR row IN SELECT * FROM rbactest.package
|
||||
FOR row IN SELECT * FROM test_package
|
||||
-- unconditional for all rows in that table
|
||||
LOOP
|
||||
call rbac.grantPermissionToRole(
|
||||
rbac.createPermission(row.uuid, 'INSERT', 'rbactest.domain'),
|
||||
rbac.createPermission(row.uuid, 'INSERT', 'test_domain'),
|
||||
testPackageADMIN(row));
|
||||
END LOOP;
|
||||
end;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Grants rbactest.domain INSERT permission to specified role of new package rows.
|
||||
Grants test_domain INSERT permission to specified role of new test_package rows.
|
||||
*/
|
||||
create or replace function rbactest.new_domain_grants_insert_to_package_tf()
|
||||
create or replace function new_test_domain_grants_insert_to_test_package_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
-- unconditional for all rows in that table
|
||||
call rbac.grantPermissionToRole(
|
||||
rbac.createPermission(NEW.uuid, 'INSERT', 'rbactest.domain'),
|
||||
rbac.createPermission(NEW.uuid, 'INSERT', 'test_domain'),
|
||||
testPackageADMIN(NEW));
|
||||
-- end.
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_new_domain_grants_after_insert_tg
|
||||
after insert on rbactest.package
|
||||
create trigger z_new_test_domain_grants_after_insert_tg
|
||||
after insert on test_package
|
||||
for each row
|
||||
execute procedure rbactest.new_domain_grants_insert_to_package_tf();
|
||||
execute procedure new_test_domain_grants_insert_to_test_package_tf();
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset InsertTriggerGenerator:rbactest-domain-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
|
||||
--changeset InsertTriggerGenerator:test_domain-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Checks if the user respectively the assumed roles are allowed to insert a row to rbactest.domain.
|
||||
Checks if the user respectively the assumed roles are allowed to insert a row to test_domain.
|
||||
*/
|
||||
create or replace function rbactest.domain_insert_permission_check_tf()
|
||||
create or replace function test_domain_insert_permission_check_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
declare
|
||||
superObjectUuid uuid;
|
||||
begin
|
||||
-- check INSERT permission via direct foreign key: NEW.packageUuid
|
||||
if rbac.hasInsertPermission(NEW.packageUuid, 'rbactest.domain') then
|
||||
if rbac.hasInsertPermission(NEW.packageUuid, 'test_domain') then
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
raise exception '[403] insert into rbactest.domain values(%) not allowed for current subjects % (%)',
|
||||
raise exception '[403] insert into test_domain values(%) not allowed for current subjects % (%)',
|
||||
NEW, base.currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger domain_insert_permission_check_tg
|
||||
before insert on rbactest.domain
|
||||
create trigger test_domain_insert_permission_check_tg
|
||||
before insert on test_domain
|
||||
for each row
|
||||
execute procedure rbactest.domain_insert_permission_check_tf();
|
||||
execute procedure test_domain_insert_permission_check_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RbacIdentityViewGenerator:rbactest-domain-rbac-IDENTITY-VIEW endDelimiter:--//
|
||||
--changeset RbacIdentityViewGenerator:test-domain-rbac-IDENTITY-VIEW endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call rbac.generateRbacIdentityViewFromProjection('rbactest.domain',
|
||||
call rbac.generateRbacIdentityViewFromProjection('test_domain',
|
||||
$idName$
|
||||
name
|
||||
$idName$);
|
||||
@ -229,9 +229,9 @@ call rbac.generateRbacIdentityViewFromProjection('rbactest.domain',
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:rbactest-domain-rbac-RESTRICTED-VIEW endDelimiter:--//
|
||||
--changeset RbacRestrictedViewGenerator:test-domain-rbac-RESTRICTED-VIEW endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call rbac.generateRbacRestrictedView('rbactest.domain',
|
||||
call rbac.generateRbacRestrictedView('test_domain',
|
||||
$orderBy$
|
||||
name
|
||||
$orderBy$,
|
@ -13,8 +13,8 @@ declare
|
||||
pacAdmin varchar;
|
||||
begin
|
||||
select p.uuid, p.name, c.prefix as custPrefix
|
||||
from rbactest.package p
|
||||
join rbactest.customer c on p.customeruuid = c.uuid
|
||||
from test_package p
|
||||
join test_customer c on p.customeruuid = c.uuid
|
||||
where p.name = packageName
|
||||
into pac;
|
||||
|
||||
@ -24,7 +24,7 @@ begin
|
||||
call base.defineContext('creating RBAC test domain', null, pacAdmin, null);
|
||||
|
||||
insert
|
||||
into rbactest.domain (name, packageUuid)
|
||||
into test_domain (name, packageUuid)
|
||||
values (pac.name || '-' || base.intToVarChar(t, 4), pac.uuid);
|
||||
end loop;
|
||||
end; $$;
|
||||
@ -41,8 +41,8 @@ declare
|
||||
begin
|
||||
for pac in
|
||||
(select p.uuid, p.name
|
||||
from rbactest.package p
|
||||
join rbactest.customer c on p.customeruuid = c.uuid
|
||||
from test_package p
|
||||
join test_customer c on p.customeruuid = c.uuid
|
||||
where c.reference < 90000) -- reserved for functional testing
|
||||
loop
|
||||
call createdomainTestData(pac.name, 2);
|
@ -181,7 +181,7 @@ $$;
|
||||
/**
|
||||
Grants hs_office_partner INSERT permission to specified role of new global rows.
|
||||
*/
|
||||
create or replace function new_hsof_partner_grants_insert_to_global_tf()
|
||||
create or replace function rbac.new_hsof_partner_grants_insert_to_global_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
@ -198,11 +198,11 @@ end; $$;
|
||||
create trigger z_new_hs_office_partner_grants_after_insert_tg
|
||||
after insert on rbac.global
|
||||
for each row
|
||||
execute procedure new_hsof_partner_grants_insert_to_global_tf();
|
||||
execute procedure rbac.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:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
@ -85,7 +85,7 @@ $$;
|
||||
/**
|
||||
Grants hs_office_partner_details INSERT permission to specified role of new global rows.
|
||||
*/
|
||||
create or replace function new_hsof_partner_details_grants_insert_to_global_tf()
|
||||
create or replace function rbac.new_hsof_partner_details_grants_insert_to_global_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
@ -102,11 +102,11 @@ end; $$;
|
||||
create trigger z_new_hs_office_partner_details_grants_after_insert_tg
|
||||
after insert on rbac.global
|
||||
for each row
|
||||
execute procedure new_hsof_partner_details_grants_insert_to_global_tf();
|
||||
execute procedure rbac.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:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
@ -154,7 +154,7 @@ $$;
|
||||
/**
|
||||
Grants hs_office_debitor INSERT permission to specified role of new global rows.
|
||||
*/
|
||||
create or replace function new_hsof_debitor_grants_insert_to_global_tf()
|
||||
create or replace function rbac.new_hsof_debitor_grants_insert_to_global_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
@ -171,11 +171,11 @@ end; $$;
|
||||
create trigger z_new_hs_office_debitor_grants_after_insert_tg
|
||||
after insert on rbac.global
|
||||
for each row
|
||||
execute procedure new_hsof_debitor_grants_insert_to_global_tf();
|
||||
execute procedure rbac.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:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
@ -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:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
@ -116,7 +116,7 @@ $$;
|
||||
/**
|
||||
Grants hs_office_membership INSERT permission to specified role of new global rows.
|
||||
*/
|
||||
create or replace function new_hsof_membership_grants_insert_to_global_tf()
|
||||
create or replace function rbac.new_hsof_membership_grants_insert_to_global_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
@ -133,11 +133,11 @@ end; $$;
|
||||
create trigger z_new_hs_office_membership_grants_after_insert_tg
|
||||
after insert on rbac.global
|
||||
for each row
|
||||
execute procedure new_hsof_membership_grants_insert_to_global_tf();
|
||||
execute procedure rbac.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:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
@ -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:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
@ -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:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
@ -1,63 +0,0 @@
|
||||
### 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
|
||||
|
||||
```
|
@ -1,277 +0,0 @@
|
||||
--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$);
|
||||
--//
|
||||
|
@ -0,0 +1,96 @@
|
||||
--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();
|
||||
--/
|
@ -21,8 +21,6 @@ databaseChangeLog:
|
||||
file: db/changelog/0-base/009-check-environment.sql
|
||||
- include:
|
||||
file: db/changelog/0-base/010-context.sql
|
||||
- include:
|
||||
file: db/changelog/0-base/011-table-schema-and-name.sql
|
||||
- include:
|
||||
file: db/changelog/0-base/020-audit-log.sql
|
||||
- include:
|
||||
@ -50,25 +48,23 @@ databaseChangeLog:
|
||||
- include:
|
||||
file: db/changelog/1-rbac/1080-rbac-global.sql
|
||||
- include:
|
||||
file: db/changelog/2-rbactest/200-rbactest-schema.sql
|
||||
file: db/changelog/2-test/201-test-customer/2010-test-customer.sql
|
||||
- include:
|
||||
file: db/changelog/2-rbactest/201-rbactest-customer/2010-rbactest-customer.sql
|
||||
file: db/changelog/2-test/201-test-customer/2013-test-customer-rbac.sql
|
||||
- include:
|
||||
file: db/changelog/2-rbactest/201-rbactest-customer/2013-rbactest-customer-rbac.sql
|
||||
file: db/changelog/2-test/201-test-customer/2018-test-customer-test-data.sql
|
||||
- include:
|
||||
file: db/changelog/2-rbactest/201-rbactest-customer/2018-rbactest-customer-test-data.sql
|
||||
file: db/changelog/2-test/202-test-package/2020-test-package.sql
|
||||
- include:
|
||||
file: db/changelog/2-rbactest/202-rbactest-package/2020-rbactest-package.sql
|
||||
file: db/changelog/2-test/202-test-package/2023-test-package-rbac.sql
|
||||
- include:
|
||||
file: db/changelog/2-rbactest/202-rbactest-package/2023-rbactest-package-rbac.sql
|
||||
file: db/changelog/2-test/202-test-package/2028-test-package-test-data.sql
|
||||
- include:
|
||||
file: db/changelog/2-rbactest/202-rbactest-package/2028-rbactest-package-test-data.sql
|
||||
file: db/changelog/2-test/203-test-domain/2030-test-domain.sql
|
||||
- include:
|
||||
file: db/changelog/2-rbactest/203-rbactest-domain/2030-rbactest-domain.sql
|
||||
file: db/changelog/2-test/203-test-domain/2033-test-domain-rbac.sql
|
||||
- include:
|
||||
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
|
||||
file: db/changelog/2-test/203-test-domain/2038-test-domain-test-data.sql
|
||||
- include:
|
||||
file: db/changelog/5-hs-office/501-contact/5010-hs-office-contact.sql
|
||||
- include:
|
||||
@ -150,15 +146,17 @@ databaseChangeLog:
|
||||
- include:
|
||||
file: db/changelog/6-hs-booking/620-booking-project/6208-hs-booking-project-test-data.sql
|
||||
- include:
|
||||
file: db/changelog/6-hs-booking/630-booking-item/6200-hs-booking-item.sql
|
||||
file: db/changelog/6-hs-booking/630-booking-item/6300-hs-booking-item.sql
|
||||
- include:
|
||||
file: db/changelog/6-hs-booking/630-booking-item/6203-hs-booking-item-rbac.sql
|
||||
file: db/changelog/6-hs-booking/630-booking-item/6303-hs-booking-item-rbac.sql
|
||||
- include:
|
||||
file: db/changelog/6-hs-booking/630-booking-item/6208-hs-booking-item-test-data.sql
|
||||
file: db/changelog/6-hs-booking/630-booking-item/6308-hs-booking-item-test-data.sql
|
||||
- include:
|
||||
file: db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql
|
||||
- include:
|
||||
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:
|
||||
file: db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql
|
||||
- include:
|
||||
|
@ -17,7 +17,6 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||
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.StringUtils;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
@ -615,7 +614,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
contacts.forEach(this::persist);
|
||||
updateLegacyIds(contacts, "hs_office_contact_legacy_id", "contact_id");
|
||||
updateLegacyIds(contacts, "hs_office_contact_legacy_id", "contact_id");
|
||||
}).assertSuccessful();
|
||||
|
||||
jpaAttempt.transacted(() -> {
|
||||
@ -699,24 +698,6 @@ public abstract class BaseOfficeDataImport extends CsvDataImport {
|
||||
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
|
||||
@Order(9999)
|
||||
@ContinueOnFailure
|
||||
|
@ -289,9 +289,9 @@ public class CsvDataImport extends ContextBasedTest {
|
||||
protected void deleteFromTestTables() {
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
em.createNativeQuery("delete from rbactest.domain where true").executeUpdate();
|
||||
em.createNativeQuery("delete from rbactest.package where true").executeUpdate();
|
||||
em.createNativeQuery("delete from rbactest.customer where true").executeUpdate();
|
||||
em.createNativeQuery("delete from test_domain where true").executeUpdate();
|
||||
em.createNativeQuery("delete from test_package where true").executeUpdate();
|
||||
em.createNativeQuery("delete from test_customer where true").executeUpdate();
|
||||
}).assertSuccessful();
|
||||
}
|
||||
|
||||
@ -334,6 +334,24 @@ public class CsvDataImport extends ContextBasedTest {
|
||||
errors.clear();
|
||||
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 {
|
||||
|
@ -47,12 +47,12 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.Map.entry;
|
||||
import static java.util.Map.ofEntries;
|
||||
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.toSet;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
||||
@ -938,6 +938,132 @@ public class ImportHostingAssets extends BaseOfficeDataImport {
|
||||
|
||||
@Test
|
||||
@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() {
|
||||
assumeThatWeAreImportingControlledTestData();
|
||||
|
||||
@ -949,6 +1075,7 @@ public class ImportHostingAssets extends BaseOfficeDataImport {
|
||||
assertThat(haCount).isEqualTo(68);
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================================
|
||||
|
||||
@Test
|
||||
@ -1006,6 +1133,11 @@ public class ImportHostingAssets extends BaseOfficeDataImport {
|
||||
}
|
||||
).assertSuccessful()
|
||||
);
|
||||
|
||||
jpaAttempt.transacted(() -> {
|
||||
context(rbacSuperuser);
|
||||
updateLegacyIds(assets, "hs_hosting_asset_legacy_id", "legacy_id");
|
||||
}).assertSuccessful();
|
||||
}
|
||||
|
||||
private void verifyActuallyPersistedHostingAssetCount(
|
||||
@ -1610,7 +1742,7 @@ public class ImportHostingAssets extends BaseOfficeDataImport {
|
||||
|
||||
//noinspection unchecked
|
||||
zoneData.put("user-RR", ((ArrayList<ArrayList<Object>>) zoneData.get("user-RR")).stream()
|
||||
.map(userRR -> userRR.stream().map(Object::toString).collect(Collectors.joining(" ")))
|
||||
.map(userRR -> userRR.stream().map(Object::toString).collect(joining(" ")))
|
||||
.toArray(String[]::new)
|
||||
);
|
||||
domainDnsSetupAsset.getConfig().putAll(zoneData);
|
||||
@ -1758,4 +1890,35 @@ public class ImportHostingAssets extends BaseOfficeDataImport {
|
||||
protected static void assumeThatWeAreImportingControlledTestData() {
|
||||
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"));
|
||||
}
|
||||
}
|
||||
|
@ -62,13 +62,13 @@ class ContextIntegrationTests {
|
||||
void defineWithoutcurrentSubjectButWithAssumedRoles() {
|
||||
// when
|
||||
final var result = jpaAttempt.transacted(() ->
|
||||
context.define(null, "rbactest.package#yyy00:ADMIN")
|
||||
context.define(null, "test_package#yyy00:ADMIN")
|
||||
);
|
||||
|
||||
// then
|
||||
result.assertExceptionWithRootCauseMessage(
|
||||
jakarta.persistence.PersistenceException.class,
|
||||
"ERROR: [403] undefined has no permission to assume role rbactest.package#yyy00:ADMIN");
|
||||
"ERROR: [403] undefined has no permission to assume role test_package#yyy00:ADMIN");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -88,7 +88,7 @@ class ContextIntegrationTests {
|
||||
@Transactional
|
||||
void defineWithcurrentSubjectAndAssumedRoles() {
|
||||
// given
|
||||
context.define("superuser-alex@hostsharing.net", "rbactest.customer#xxx:OWNER;rbactest.customer#yyy:OWNER");
|
||||
context.define("superuser-alex@hostsharing.net", "test_customer#xxx:OWNER;test_customer#yyy:OWNER");
|
||||
|
||||
// when
|
||||
final var currentSubject = context.fetchCurrentSubject();
|
||||
@ -96,7 +96,7 @@ class ContextIntegrationTests {
|
||||
|
||||
// then
|
||||
assertThat(context.fetchAssumedRoles())
|
||||
.isEqualTo(Array.of("rbactest.customer#xxx:OWNER", "rbactest.customer#yyy:OWNER"));
|
||||
.isEqualTo(Array.of("test_customer#xxx:OWNER", "test_customer#yyy:OWNER"));
|
||||
assertThat(context.fetchCurrentSubjectOrAssumedRolesUuids()).hasSize(2);
|
||||
}
|
||||
|
||||
@ -104,12 +104,12 @@ class ContextIntegrationTests {
|
||||
public void defineContextWithcurrentSubjectAndAssumeInaccessibleRole() {
|
||||
// when
|
||||
final var result = jpaAttempt.transacted(() ->
|
||||
context.define("customer-admin@xxx.example.com", "rbactest.package#yyy00:ADMIN")
|
||||
context.define("customer-admin@xxx.example.com", "test_package#yyy00:ADMIN")
|
||||
);
|
||||
|
||||
// then
|
||||
result.assertExceptionWithRootCauseMessage(
|
||||
jakarta.persistence.PersistenceException.class,
|
||||
"ERROR: [403] subject customer-admin@xxx.example.com has no permission to assume role rbactest.package#yyy00:ADMIN");
|
||||
"ERROR: [403] subject customer-admin@xxx.example.com has no permission to assume role test_package#yyy00:ADMIN");
|
||||
}
|
||||
}
|
||||
|
@ -71,16 +71,16 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
.body("", hasItem(
|
||||
allOf(
|
||||
// TODO: should there be a grantedByRole or just a grantedByTrigger?
|
||||
hasEntry("grantedByRoleIdName", "rbactest.customer#xxx:OWNER"),
|
||||
hasEntry("grantedRoleIdName", "rbactest.customer#xxx:ADMIN"),
|
||||
hasEntry("grantedByRoleIdName", "test_customer#xxx:OWNER"),
|
||||
hasEntry("grantedRoleIdName", "test_customer#xxx:ADMIN"),
|
||||
hasEntry("granteeSubjectName", "customer-admin@xxx.example.com")
|
||||
)
|
||||
))
|
||||
.body("", hasItem(
|
||||
allOf(
|
||||
// TODO: should there be a grantedByRole or just a grantedByTrigger?
|
||||
hasEntry("grantedByRoleIdName", "rbactest.customer#yyy:OWNER"),
|
||||
hasEntry("grantedRoleIdName", "rbactest.customer#yyy:ADMIN"),
|
||||
hasEntry("grantedByRoleIdName", "test_customer#yyy:OWNER"),
|
||||
hasEntry("grantedRoleIdName", "test_customer#yyy:ADMIN"),
|
||||
hasEntry("granteeSubjectName", "customer-admin@yyy.example.com")
|
||||
)
|
||||
))
|
||||
@ -93,15 +93,15 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
))
|
||||
.body("", hasItem(
|
||||
allOf(
|
||||
hasEntry("grantedByRoleIdName", "rbactest.customer#xxx:ADMIN"),
|
||||
hasEntry("grantedRoleIdName", "rbactest.package#xxx00:ADMIN"),
|
||||
hasEntry("grantedByRoleIdName", "test_customer#xxx:ADMIN"),
|
||||
hasEntry("grantedRoleIdName", "test_package#xxx00:ADMIN"),
|
||||
hasEntry("granteeSubjectName", "pac-admin-xxx00@xxx.example.com")
|
||||
)
|
||||
))
|
||||
.body("", hasItem(
|
||||
allOf(
|
||||
hasEntry("grantedByRoleIdName", "rbactest.customer#zzz:ADMIN"),
|
||||
hasEntry("grantedRoleIdName", "rbactest.package#zzz02:ADMIN"),
|
||||
hasEntry("grantedByRoleIdName", "test_customer#zzz:ADMIN"),
|
||||
hasEntry("grantedRoleIdName", "test_package#zzz02:ADMIN"),
|
||||
hasEntry("granteeSubjectName", "pac-admin-zzz02@zzz.example.com")
|
||||
)
|
||||
))
|
||||
@ -114,7 +114,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "rbactest.package#yyy00:ADMIN")
|
||||
.header("assumed-roles", "test_package#yyy00:ADMIN")
|
||||
.port(port)
|
||||
.when()
|
||||
.get("http://localhost/api/rbac/grants")
|
||||
@ -123,8 +123,8 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
.contentType("application/json")
|
||||
.body("", hasItem(
|
||||
allOf(
|
||||
hasEntry("grantedByRoleIdName", "rbactest.customer#yyy:ADMIN"),
|
||||
hasEntry("grantedRoleIdName", "rbactest.package#yyy00:ADMIN"),
|
||||
hasEntry("grantedByRoleIdName", "test_customer#yyy:ADMIN"),
|
||||
hasEntry("grantedRoleIdName", "test_package#yyy00:ADMIN"),
|
||||
hasEntry("granteeSubjectName", "pac-admin-yyy00@yyy.example.com")
|
||||
)
|
||||
))
|
||||
@ -145,13 +145,13 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
.contentType("application/json")
|
||||
.body("", hasItem(
|
||||
allOf(
|
||||
hasEntry("grantedByRoleIdName", "rbactest.customer#yyy:ADMIN"),
|
||||
hasEntry("grantedRoleIdName", "rbactest.package#yyy00:ADMIN"),
|
||||
hasEntry("grantedByRoleIdName", "test_customer#yyy:ADMIN"),
|
||||
hasEntry("grantedRoleIdName", "test_package#yyy00:ADMIN"),
|
||||
hasEntry("granteeSubjectName", "pac-admin-yyy00@yyy.example.com")
|
||||
)
|
||||
))
|
||||
.body("[0].grantedByRoleIdName", is("rbactest.customer#yyy:ADMIN"))
|
||||
.body("[0].grantedRoleIdName", is("rbactest.package#yyy00:ADMIN"))
|
||||
.body("[0].grantedByRoleIdName", is("test_customer#yyy:ADMIN"))
|
||||
.body("[0].grantedRoleIdName", is("test_package#yyy00:ADMIN"))
|
||||
.body("[0].granteeSubjectName", is("pac-admin-yyy00@yyy.example.com"));
|
||||
// @formatter:on
|
||||
}
|
||||
@ -165,7 +165,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
// given
|
||||
final var givencurrentSubjectAsPackageAdmin = new Subject("customer-admin@xxx.example.com");
|
||||
final var givenGranteeUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com");
|
||||
final var givenGrantedRole = getRbacRoleByName("rbactest.package#xxx00:ADMIN");
|
||||
final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN");
|
||||
|
||||
// when
|
||||
final var grant = givencurrentSubjectAsPackageAdmin.getGrantById()
|
||||
@ -174,8 +174,8 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
// then
|
||||
grant.assertThat()
|
||||
.statusCode(200)
|
||||
.body("grantedByRoleIdName", is("rbactest.customer#xxx:ADMIN"))
|
||||
.body("grantedRoleIdName", is("rbactest.package#xxx00:ADMIN"))
|
||||
.body("grantedByRoleIdName", is("test_customer#xxx:ADMIN"))
|
||||
.body("grantedRoleIdName", is("test_package#xxx00:ADMIN"))
|
||||
.body("granteeSubjectName", is("pac-admin-xxx00@xxx.example.com"));
|
||||
}
|
||||
|
||||
@ -184,7 +184,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
// given
|
||||
final var givencurrentSubjectAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com");
|
||||
final var givenGranteeUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com");
|
||||
final var givenGrantedRole = getRbacRoleByName("rbactest.package#xxx00:ADMIN");
|
||||
final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN");
|
||||
|
||||
// when
|
||||
final var grant = givencurrentSubjectAsPackageAdmin.getGrantById()
|
||||
@ -193,8 +193,8 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
// then
|
||||
grant.assertThat()
|
||||
.statusCode(200)
|
||||
.body("grantedByRoleIdName", is("rbactest.customer#xxx:ADMIN"))
|
||||
.body("grantedRoleIdName", is("rbactest.package#xxx00:ADMIN"))
|
||||
.body("grantedByRoleIdName", is("test_customer#xxx:ADMIN"))
|
||||
.body("grantedRoleIdName", is("test_package#xxx00:ADMIN"))
|
||||
.body("granteeSubjectName", is("pac-admin-xxx00@xxx.example.com"));
|
||||
}
|
||||
|
||||
@ -203,9 +203,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
// given
|
||||
final var givencurrentSubjectAsPackageAdmin = new Subject(
|
||||
"pac-admin-xxx00@xxx.example.com",
|
||||
"rbactest.package#xxx00:ADMIN");
|
||||
"test_package#xxx00:ADMIN");
|
||||
final var givenGranteeUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com");
|
||||
final var givenGrantedRole = getRbacRoleByName("rbactest.package#xxx00:ADMIN");
|
||||
final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN");
|
||||
|
||||
// when
|
||||
final var grant = givencurrentSubjectAsPackageAdmin.getGrantById()
|
||||
@ -214,8 +214,8 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
// then
|
||||
grant.assertThat()
|
||||
.statusCode(200)
|
||||
.body("grantedByRoleIdName", is("rbactest.customer#xxx:ADMIN"))
|
||||
.body("grantedRoleIdName", is("rbactest.package#xxx00:ADMIN"))
|
||||
.body("grantedByRoleIdName", is("test_customer#xxx:ADMIN"))
|
||||
.body("grantedRoleIdName", is("test_package#xxx00:ADMIN"))
|
||||
.body("granteeSubjectName", is("pac-admin-xxx00@xxx.example.com"));
|
||||
}
|
||||
|
||||
@ -225,9 +225,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
// given
|
||||
final var givencurrentSubjectAsPackageAdmin = new Subject(
|
||||
"pac-admin-xxx00@xxx.example.com",
|
||||
"rbactest.package#xxx00:TENANT");
|
||||
"test_package#xxx00:TENANT");
|
||||
final var givenGranteeUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com");
|
||||
final var givenGrantedRole = getRbacRoleByName("rbactest.package#xxx00:ADMIN");
|
||||
final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN");
|
||||
final var grant = givencurrentSubjectAsPackageAdmin.getGrantById()
|
||||
.forGrantedRole(givenGrantedRole).toGranteeUser(givenGranteeUser);
|
||||
|
||||
@ -245,7 +245,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
|
||||
// given
|
||||
final var givenNewUser = createRbacSubject();
|
||||
final var givenRoleToGrant = "rbactest.package#xxx00:ADMIN";
|
||||
final var givenRoleToGrant = "test_package#xxx00:ADMIN";
|
||||
final var givencurrentSubjectAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant);
|
||||
final var givenOwnPackageAdminRole =
|
||||
getRbacRoleByName(givencurrentSubjectAsPackageAdmin.assumedRole);
|
||||
@ -258,9 +258,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
// then
|
||||
response.assertThat()
|
||||
.statusCode(201)
|
||||
.body("grantedByRoleIdName", is("rbactest.package#xxx00:ADMIN"))
|
||||
.body("grantedByRoleIdName", is("test_package#xxx00:ADMIN"))
|
||||
.body("assumed", is(true))
|
||||
.body("grantedRoleIdName", is("rbactest.package#xxx00:ADMIN"))
|
||||
.body("grantedRoleIdName", is("test_package#xxx00:ADMIN"))
|
||||
.body("granteeSubjectName", is(givenNewUser.getName()));
|
||||
assertThat(findAllGrantsOf(givencurrentSubjectAsPackageAdmin))
|
||||
.extracting(RbacGrantEntity::toDisplay)
|
||||
@ -274,9 +274,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
|
||||
// given
|
||||
final var givenNewUser = createRbacSubject();
|
||||
final var givenRoleToGrant = "rbactest.package#xxx00:ADMIN";
|
||||
final var givenRoleToGrant = "test_package#xxx00:ADMIN";
|
||||
final var givencurrentSubjectAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant);
|
||||
final var givenAlienPackageAdminRole = getRbacRoleByName("rbactest.package#yyy00:ADMIN");
|
||||
final var givenAlienPackageAdminRole = getRbacRoleByName("test_package#yyy00:ADMIN");
|
||||
|
||||
// when
|
||||
final var result = givencurrentSubjectAsPackageAdmin
|
||||
@ -287,7 +287,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
result.assertThat()
|
||||
.statusCode(403)
|
||||
.body("message", containsString("Access to granted role"))
|
||||
.body("message", containsString("forbidden for rbactest.package#xxx00:ADMIN"));
|
||||
.body("message", containsString("forbidden for test_package#xxx00:ADMIN"));
|
||||
assertThat(findAllGrantsOf(givencurrentSubjectAsPackageAdmin))
|
||||
.extracting(RbacGrantEntity::getGranteeSubjectName)
|
||||
.doesNotContain(givenNewUser.getName());
|
||||
@ -303,9 +303,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
|
||||
// given
|
||||
final var givenArbitraryUser = createRbacSubject();
|
||||
final var givenRoleToGrant = "rbactest.package#xxx00:ADMIN";
|
||||
final var givenRoleToGrant = "test_package#xxx00:ADMIN";
|
||||
final var givenCurrentSubjectAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant);
|
||||
final var givenOwnPackageAdminRole = getRbacRoleByName("rbactest.package#xxx00:ADMIN");
|
||||
final var givenOwnPackageAdminRole = getRbacRoleByName("test_package#xxx00:ADMIN");
|
||||
|
||||
// and given an existing grant
|
||||
assumeCreated(givenCurrentSubjectAsPackageAdmin
|
||||
|
@ -67,7 +67,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
// then
|
||||
exactlyTheseRbacGrantsAreReturned(
|
||||
result,
|
||||
"{ 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#xxx00:ADMIN to user:pac-admin-xxx00@xxx.example.com by role:test_customer#xxx:ADMIN and assume }");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -81,16 +81,16 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
// then
|
||||
exactlyTheseRbacGrantsAreReturned(
|
||||
result,
|
||||
"{ grant role:rbactest.customer#xxx:ADMIN to user:customer-admin@xxx.example.com by role:rbactest.customer#xxx:OWNER 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:rbactest.package#xxx01:ADMIN to user:pac-admin-xxx01@xxx.example.com by role:rbactest.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 }");
|
||||
"{ grant role:test_customer#xxx:ADMIN to user:customer-admin@xxx.example.com by role:test_customer#xxx:OWNER and assume }",
|
||||
"{ grant role:test_package#xxx00:ADMIN to user:pac-admin-xxx00@xxx.example.com by role:test_customer#xxx:ADMIN and assume }",
|
||||
"{ grant role:test_package#xxx01:ADMIN to user:pac-admin-xxx01@xxx.example.com by role:test_customer#xxx:ADMIN and assume }",
|
||||
"{ grant role:test_package#xxx02:ADMIN to user:pac-admin-xxx02@xxx.example.com by role:test_customer#xxx:ADMIN and assume }");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customerAdmin_withAssumedRole_canOnlyViewRbacGrantsVisibleByAssumedRole() {
|
||||
// given:
|
||||
context("customer-admin@xxx.example.com", "rbactest.package#xxx00:ADMIN");
|
||||
context("customer-admin@xxx.example.com", "test_package#xxx00:ADMIN");
|
||||
|
||||
// when
|
||||
final var result = rbacGrantRepository.findAll();
|
||||
@ -98,7 +98,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
// then
|
||||
exactlyTheseRbacGrantsAreReturned(
|
||||
result,
|
||||
"{ grant role:rbactest.package#xxx00:ADMIN to user:pac-admin-xxx00@xxx.example.com by role:rbactest.customer#xxx:ADMIN and assume }");
|
||||
"{ grant role:test_package#xxx00:ADMIN to user:pac-admin-xxx00@xxx.example.com by role:test_customer#xxx:ADMIN and assume }");
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,9 +108,9 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
@Test
|
||||
public void customerAdmin_canGrantOwnPackageAdminRole_toArbitraryUser() {
|
||||
// given
|
||||
context("customer-admin@xxx.example.com", "rbactest.customer#xxx:ADMIN");
|
||||
context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN");
|
||||
final var givenArbitrarySubjectUuid = rbacSubjectRepository.findByName("pac-admin-zzz00@zzz.example.com").getUuid();
|
||||
final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName("rbactest.package#xxx00:ADMIN").getUuid();
|
||||
final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName("test_package#xxx00:ADMIN").getUuid();
|
||||
|
||||
// when
|
||||
final var grant = RbacGrantEntity.builder()
|
||||
@ -126,7 +126,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
assertThat(rbacGrantRepository.findAll())
|
||||
.extracting(RbacGrantEntity::toDisplay)
|
||||
.contains(
|
||||
"{ grant role:rbactest.package#xxx00:ADMIN to user:pac-admin-zzz00@zzz.example.com by role:rbactest.customer#xxx:ADMIN and assume }");
|
||||
"{ grant role:test_package#xxx00:ADMIN to user:pac-admin-zzz00@zzz.example.com by role:test_customer#xxx:ADMIN and assume }");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -139,14 +139,14 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
context("customer-admin@xxx.example.com", null);
|
||||
return new Given(
|
||||
createNewUser(),
|
||||
rbacRoleRepository.findByRoleName("rbactest.package#xxx00:OWNER").getUuid()
|
||||
rbacRoleRepository.findByRoleName("test_package#xxx00:OWNER").getUuid()
|
||||
);
|
||||
}).assumeSuccessful().returnedValue();
|
||||
|
||||
// when
|
||||
final var attempt = jpaAttempt.transacted(() -> {
|
||||
// now we try to use these uuids as a less privileged user
|
||||
context("pac-admin-xxx00@xxx.example.com", "rbactest.package#xxx00:ADMIN");
|
||||
context("pac-admin-xxx00@xxx.example.com", "test_package#xxx00:ADMIN");
|
||||
final var grant = RbacGrantEntity.builder()
|
||||
.granteeSubjectUuid(given.arbitraryUser.getUuid())
|
||||
.grantedRoleUuid(given.packageOwnerRoleUuid)
|
||||
@ -158,8 +158,8 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
// then
|
||||
attempt.assertExceptionWithRootCauseMessage(
|
||||
JpaSystemException.class,
|
||||
"ERROR: [403] Access to granted role rbactest.package#xxx00:OWNER",
|
||||
"forbidden for rbactest.package#xxx00:ADMIN");
|
||||
"ERROR: [403] Access to granted role test_package#xxx00:OWNER",
|
||||
"forbidden for test_package#xxx00:ADMIN");
|
||||
jpaAttempt.transacted(() -> {
|
||||
// finally, we use the new user to make sure, no roles were granted
|
||||
context(given.arbitraryUser.getName(), null);
|
||||
@ -176,16 +176,16 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
public void customerAdmin_canRevokeSelfGrantedPackageAdminRole() {
|
||||
// given
|
||||
final var grant = create(grant()
|
||||
.byUser("customer-admin@xxx.example.com").withAssumedRole("rbactest.customer#xxx:ADMIN")
|
||||
.grantingRole("rbactest.package#xxx00:ADMIN").toUser("pac-admin-zzz00@zzz.example.com"));
|
||||
.byUser("customer-admin@xxx.example.com").withAssumedRole("test_customer#xxx:ADMIN")
|
||||
.grantingRole("test_package#xxx00:ADMIN").toUser("pac-admin-zzz00@zzz.example.com"));
|
||||
|
||||
// when
|
||||
context("customer-admin@xxx.example.com", "rbactest.customer#xxx:ADMIN");
|
||||
context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN");
|
||||
final var revokeAttempt = attempt(em, () ->
|
||||
rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId()));
|
||||
|
||||
// then
|
||||
context("customer-admin@xxx.example.com", "rbactest.customer#xxx:ADMIN");
|
||||
context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN");
|
||||
assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull();
|
||||
assertThat(rbacGrantRepository.findAll())
|
||||
.extracting(RbacGrantEntity::getGranteeSubjectName)
|
||||
@ -197,17 +197,17 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
// given
|
||||
final var newUser = createNewUserTransacted();
|
||||
final var grant = create(grant()
|
||||
.byUser("customer-admin@xxx.example.com").withAssumedRole("rbactest.package#xxx00:ADMIN")
|
||||
.grantingRole("rbactest.package#xxx00:ADMIN").toUser(newUser.getName()));
|
||||
.byUser("customer-admin@xxx.example.com").withAssumedRole("test_package#xxx00:ADMIN")
|
||||
.grantingRole("test_package#xxx00:ADMIN").toUser(newUser.getName()));
|
||||
|
||||
// when
|
||||
context("pac-admin-xxx00@xxx.example.com", "rbactest.package#xxx00:ADMIN");
|
||||
context("pac-admin-xxx00@xxx.example.com", "test_package#xxx00:ADMIN");
|
||||
final var revokeAttempt = attempt(em, () ->
|
||||
rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId()));
|
||||
|
||||
// then
|
||||
assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull();
|
||||
context("customer-admin@xxx.example.com", "rbactest.customer#xxx:ADMIN");
|
||||
context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN");
|
||||
assertThat(rbacGrantRepository.findAll())
|
||||
.extracting(RbacGrantEntity::getGranteeSubjectName)
|
||||
.doesNotContain("pac-admin-zzz00@zzz.example.com");
|
||||
@ -217,19 +217,19 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
public void packageAdmin_canNotRevokeOwnPackageAdminRoleGrantedByOwnerRoleOfThatPackage() {
|
||||
// given
|
||||
final var grant = create(grant()
|
||||
.byUser("customer-admin@xxx.example.com").withAssumedRole("rbactest.package#xxx00:OWNER")
|
||||
.grantingRole("rbactest.package#xxx00:ADMIN").toUser("pac-admin-zzz00@zzz.example.com"));
|
||||
final var grantedByRole = rbacRoleRepository.findByRoleName("rbactest.package#xxx00:OWNER");
|
||||
.byUser("customer-admin@xxx.example.com").withAssumedRole("test_package#xxx00:OWNER")
|
||||
.grantingRole("test_package#xxx00:ADMIN").toUser("pac-admin-zzz00@zzz.example.com"));
|
||||
final var grantedByRole = rbacRoleRepository.findByRoleName("test_package#xxx00:OWNER");
|
||||
|
||||
// when
|
||||
context("pac-admin-xxx00@xxx.example.com", "rbactest.package#xxx00:ADMIN");
|
||||
context("pac-admin-xxx00@xxx.example.com", "test_package#xxx00:ADMIN");
|
||||
final var revokeAttempt = attempt(em, () ->
|
||||
rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId()));
|
||||
|
||||
// then
|
||||
revokeAttempt.assertExceptionWithRootCauseMessage(
|
||||
JpaSystemException.class,
|
||||
"ERROR: [403] Revoking role created by %s is forbidden for {rbactest.package#xxx00:ADMIN}.".formatted(
|
||||
"ERROR: [403] Revoking role created by %s is forbidden for {test_package#xxx00:ADMIN}.".formatted(
|
||||
grantedByRole.getUuid()
|
||||
));
|
||||
}
|
||||
|
@ -54,36 +54,36 @@ class RbacGrantsDiagramServiceIntegrationTest extends ContextBasedTestWithCleanu
|
||||
|
||||
@Test
|
||||
void allGrantsTocurrentSubject() {
|
||||
context("superuser-alex@hostsharing.net", "rbactest.domain#xxx00-aaaa:OWNER");
|
||||
context("superuser-alex@hostsharing.net", "test_domain#xxx00-aaaa:OWNER");
|
||||
final var graph = grantsMermaidService.allGrantsTocurrentSubject(EnumSet.of(Include.TEST_ENTITIES));
|
||||
|
||||
assertThat(graph).isEqualTo("""
|
||||
flowchart TB
|
||||
|
||||
role:rbactest.domain#xxx00-aaaa:ADMIN --> role:rbactest.package#xxx00:TENANT
|
||||
role:rbactest.domain#xxx00-aaaa:OWNER --> role:rbactest.domain#xxx00-aaaa:ADMIN
|
||||
role:rbactest.domain#xxx00-aaaa:OWNER --> role:rbactest.package#xxx00:TENANT
|
||||
role:rbactest.package#xxx00:TENANT --> role:rbactest.customer#xxx:TENANT
|
||||
role:test_domain#xxx00-aaaa:ADMIN --> role:test_package#xxx00:TENANT
|
||||
role:test_domain#xxx00-aaaa:OWNER --> role:test_domain#xxx00-aaaa:ADMIN
|
||||
role:test_domain#xxx00-aaaa:OWNER --> role:test_package#xxx00:TENANT
|
||||
role:test_package#xxx00:TENANT --> role:test_customer#xxx:TENANT
|
||||
""".trim());
|
||||
}
|
||||
|
||||
@Test
|
||||
void allGrantsTocurrentSubjectIncludingPermissions() {
|
||||
context("superuser-alex@hostsharing.net", "rbactest.domain#xxx00-aaaa:OWNER");
|
||||
context("superuser-alex@hostsharing.net", "test_domain#xxx00-aaaa:OWNER");
|
||||
final var graph = grantsMermaidService.allGrantsTocurrentSubject(EnumSet.of(Include.TEST_ENTITIES, Include.PERMISSIONS));
|
||||
|
||||
assertThat(graph).isEqualTo("""
|
||||
flowchart TB
|
||||
|
||||
role:rbactest.customer#xxx:TENANT --> perm:rbactest.customer#xxx:SELECT
|
||||
role:rbactest.domain#xxx00-aaaa:ADMIN --> perm:rbactest.domain#xxx00-aaaa:SELECT
|
||||
role:rbactest.domain#xxx00-aaaa:ADMIN --> role:rbactest.package#xxx00:TENANT
|
||||
role:rbactest.domain#xxx00-aaaa:OWNER --> perm:rbactest.domain#xxx00-aaaa:DELETE
|
||||
role:rbactest.domain#xxx00-aaaa:OWNER --> perm:rbactest.domain#xxx00-aaaa:UPDATE
|
||||
role:rbactest.domain#xxx00-aaaa:OWNER --> role:rbactest.domain#xxx00-aaaa:ADMIN
|
||||
role:rbactest.domain#xxx00-aaaa:OWNER --> role:rbactest.package#xxx00:TENANT
|
||||
role:rbactest.package#xxx00:TENANT --> perm:rbactest.package#xxx00:SELECT
|
||||
role:rbactest.package#xxx00:TENANT --> role:rbactest.customer#xxx:TENANT
|
||||
role:test_customer#xxx:TENANT --> perm:test_customer#xxx:SELECT
|
||||
role:test_domain#xxx00-aaaa:ADMIN --> perm:test_domain#xxx00-aaaa:SELECT
|
||||
role:test_domain#xxx00-aaaa:ADMIN --> role:test_package#xxx00:TENANT
|
||||
role:test_domain#xxx00-aaaa:OWNER --> perm:test_domain#xxx00-aaaa:DELETE
|
||||
role:test_domain#xxx00-aaaa:OWNER --> perm:test_domain#xxx00-aaaa:UPDATE
|
||||
role:test_domain#xxx00-aaaa:OWNER --> role:test_domain#xxx00-aaaa:ADMIN
|
||||
role:test_domain#xxx00-aaaa:OWNER --> role:test_package#xxx00:TENANT
|
||||
role:test_package#xxx00:TENANT --> perm:test_package#xxx00:SELECT
|
||||
role:test_package#xxx00:TENANT --> role:test_customer#xxx:TENANT
|
||||
""".trim());
|
||||
}
|
||||
|
||||
|
@ -42,14 +42,14 @@ class RbacRoleControllerAcceptanceTest {
|
||||
.then().assertThat()
|
||||
.statusCode(200)
|
||||
.contentType("application/json")
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.customer#xxx:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.customer#xxx:OWNER")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.customer#xxx:TENANT")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_customer#xxx:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_customer#xxx:OWNER")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_customer#xxx:TENANT")))
|
||||
// ...
|
||||
.body("", hasItem(hasEntry("roleName", "rbac.global#global:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.customer#yyy:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.package#yyy00:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.domain#yyy00-aaaa:OWNER")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_customer#yyy:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_package#yyy00:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER")))
|
||||
.body( "size()", greaterThanOrEqualTo(73)); // increases with new test data
|
||||
// @formatter:on
|
||||
}
|
||||
@ -61,7 +61,7 @@ class RbacRoleControllerAcceptanceTest {
|
||||
RestAssured
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "rbactest.package#yyy00:ADMIN")
|
||||
.header("assumed-roles", "test_package#yyy00:ADMIN")
|
||||
.port(port)
|
||||
.when()
|
||||
.get("http://localhost/api/rbac/roles")
|
||||
@ -71,18 +71,18 @@ class RbacRoleControllerAcceptanceTest {
|
||||
.statusCode(200)
|
||||
.contentType("application/json")
|
||||
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.customer#yyy:TENANT")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.domain#yyy00-aaaa:OWNER")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.domain#yyy00-aaaa:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.domain#yyy00-aaab:OWNER")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.domain#yyy00-aaab:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.package#yyy00:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.package#yyy00:TENANT")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_customer#yyy:TENANT")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaaa:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaab:OWNER")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaab:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_package#yyy00:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_package#yyy00:TENANT")))
|
||||
|
||||
.body("", not(hasItem(hasEntry("roleName", "rbactest.customer#xxx:TENANT"))))
|
||||
.body("", not(hasItem(hasEntry("roleName", "rbactest.domain#xxx00-aaaa:ADMIN"))))
|
||||
.body("", not(hasItem(hasEntry("roleName", "rbactest.package#xxx00:ADMIN"))))
|
||||
.body("", not(hasItem(hasEntry("roleName", "rbactest.package#xxx00:TENANT"))))
|
||||
.body("", not(hasItem(hasEntry("roleName", "test_customer#xxx:TENANT"))))
|
||||
.body("", not(hasItem(hasEntry("roleName", "test_domain#xxx00-aaaa:ADMIN"))))
|
||||
.body("", not(hasItem(hasEntry("roleName", "test_package#xxx00:ADMIN"))))
|
||||
.body("", not(hasItem(hasEntry("roleName", "test_package#xxx00:TENANT"))))
|
||||
;
|
||||
// @formatter:on
|
||||
}
|
||||
@ -101,15 +101,15 @@ class RbacRoleControllerAcceptanceTest {
|
||||
.statusCode(200)
|
||||
.contentType("application/json")
|
||||
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.customer#zzz:TENANT")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.domain#zzz00-aaaa:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.package#zzz00:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "rbactest.package#zzz00:TENANT")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_customer#zzz:TENANT")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_domain#zzz00-aaaa:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_package#zzz00:ADMIN")))
|
||||
.body("", hasItem(hasEntry("roleName", "test_package#zzz00:TENANT")))
|
||||
|
||||
.body("", not(hasItem(hasEntry("roleName", "rbactest.customer#yyy:TENANT"))))
|
||||
.body("", not(hasItem(hasEntry("roleName", "rbactest.domain#yyy00-aaaa:ADMIN"))))
|
||||
.body("", not(hasItem(hasEntry("roleName", "rbactest.package#yyy00:ADMIN"))))
|
||||
.body("", not(hasItem(hasEntry("roleName", "rbactest.package#yyy00:TENANT"))));
|
||||
.body("", not(hasItem(hasEntry("roleName", "test_customer#yyy:TENANT"))))
|
||||
.body("", not(hasItem(hasEntry("roleName", "test_domain#yyy00-aaaa:ADMIN"))))
|
||||
.body("", not(hasItem(hasEntry("roleName", "test_package#yyy00:ADMIN"))))
|
||||
.body("", not(hasItem(hasEntry("roleName", "test_package#yyy00:TENANT"))));
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
|
@ -74,8 +74,8 @@ class RbacRoleControllerRestTest {
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$", hasSize(3)))
|
||||
.andExpect(jsonPath("$[0].roleName", is("rbac.global#global:ADMIN")))
|
||||
.andExpect(jsonPath("$[1].roleName", is("rbactest.customer#xxx:OWNER")))
|
||||
.andExpect(jsonPath("$[2].roleName", is("rbactest.customer#xxx:ADMIN")))
|
||||
.andExpect(jsonPath("$[1].roleName", is("test_customer#xxx:OWNER")))
|
||||
.andExpect(jsonPath("$[2].roleName", is("test_customer#xxx:ADMIN")))
|
||||
.andExpect(jsonPath("$[2].uuid", is(customerXxxAdmin.getUuid().toString())))
|
||||
.andExpect(jsonPath("$[2].objectUuid", is(customerXxxAdmin.getObjectUuid().toString())))
|
||||
.andExpect(jsonPath("$[2].objectTable", is(customerXxxAdmin.getObjectTable().toString())))
|
||||
|
@ -40,18 +40,18 @@ class RbacRoleRepositoryIntegrationTest {
|
||||
private static final String[] ALL_TEST_DATA_ROLES = Array.of(
|
||||
// @formatter:off
|
||||
"rbac.global#global:ADMIN",
|
||||
"rbactest.customer#xxx:ADMIN", "rbactest.customer#xxx:OWNER", "rbactest.customer#xxx:TENANT",
|
||||
"rbactest.package#xxx00:ADMIN", "rbactest.package#xxx00:OWNER", "rbactest.package#xxx00:TENANT",
|
||||
"rbactest.package#xxx01:ADMIN", "rbactest.package#xxx01:OWNER", "rbactest.package#xxx01:TENANT",
|
||||
"rbactest.package#xxx02:ADMIN", "rbactest.package#xxx02:OWNER", "rbactest.package#xxx02:TENANT",
|
||||
"rbactest.customer#yyy:ADMIN", "rbactest.customer#yyy:OWNER", "rbactest.customer#yyy:TENANT",
|
||||
"rbactest.package#yyy00:ADMIN", "rbactest.package#yyy00:OWNER", "rbactest.package#yyy00:TENANT",
|
||||
"rbactest.package#yyy01:ADMIN", "rbactest.package#yyy01:OWNER", "rbactest.package#yyy01:TENANT",
|
||||
"rbactest.package#yyy02:ADMIN", "rbactest.package#yyy02:OWNER", "rbactest.package#yyy02:TENANT",
|
||||
"rbactest.customer#zzz:ADMIN", "rbactest.customer#zzz:OWNER", "rbactest.customer#zzz:TENANT",
|
||||
"rbactest.package#zzz00:ADMIN", "rbactest.package#zzz00:OWNER", "rbactest.package#zzz00:TENANT",
|
||||
"rbactest.package#zzz01:ADMIN", "rbactest.package#zzz01:OWNER", "rbactest.package#zzz01:TENANT",
|
||||
"rbactest.package#zzz02:ADMIN", "rbactest.package#zzz02:OWNER", "rbactest.package#zzz02:TENANT"
|
||||
"test_customer#xxx:ADMIN", "test_customer#xxx:OWNER", "test_customer#xxx:TENANT",
|
||||
"test_package#xxx00:ADMIN", "test_package#xxx00:OWNER", "test_package#xxx00:TENANT",
|
||||
"test_package#xxx01:ADMIN", "test_package#xxx01:OWNER", "test_package#xxx01:TENANT",
|
||||
"test_package#xxx02:ADMIN", "test_package#xxx02:OWNER", "test_package#xxx02:TENANT",
|
||||
"test_customer#yyy:ADMIN", "test_customer#yyy:OWNER", "test_customer#yyy:TENANT",
|
||||
"test_package#yyy00:ADMIN", "test_package#yyy00:OWNER", "test_package#yyy00:TENANT",
|
||||
"test_package#yyy01:ADMIN", "test_package#yyy01:OWNER", "test_package#yyy01:TENANT",
|
||||
"test_package#yyy02:ADMIN", "test_package#yyy02:OWNER", "test_package#yyy02:TENANT",
|
||||
"test_customer#zzz:ADMIN", "test_customer#zzz:OWNER", "test_customer#zzz:TENANT",
|
||||
"test_package#zzz00:ADMIN", "test_package#zzz00:OWNER", "test_package#zzz00:TENANT",
|
||||
"test_package#zzz01:ADMIN", "test_package#zzz01:OWNER", "test_package#zzz01:TENANT",
|
||||
"test_package#zzz02:ADMIN", "test_package#zzz02:OWNER", "test_package#zzz02:TENANT"
|
||||
// @formatter:on
|
||||
);
|
||||
|
||||
@ -91,49 +91,49 @@ class RbacRoleRepositoryIntegrationTest {
|
||||
allTheseRbacRolesAreReturned(
|
||||
result,
|
||||
// @formatter:off
|
||||
"rbactest.customer#xxx:ADMIN",
|
||||
"rbactest.customer#xxx:TENANT",
|
||||
"rbactest.package#xxx00:ADMIN",
|
||||
"rbactest.package#xxx00:OWNER",
|
||||
"rbactest.package#xxx00:TENANT",
|
||||
"rbactest.package#xxx01:ADMIN",
|
||||
"rbactest.package#xxx01:OWNER",
|
||||
"rbactest.package#xxx01:TENANT",
|
||||
"test_customer#xxx:ADMIN",
|
||||
"test_customer#xxx:TENANT",
|
||||
"test_package#xxx00:ADMIN",
|
||||
"test_package#xxx00:OWNER",
|
||||
"test_package#xxx00:TENANT",
|
||||
"test_package#xxx01:ADMIN",
|
||||
"test_package#xxx01:OWNER",
|
||||
"test_package#xxx01:TENANT",
|
||||
// ...
|
||||
"rbactest.domain#xxx00-aaaa:ADMIN",
|
||||
"rbactest.domain#xxx00-aaaa:OWNER",
|
||||
"test_domain#xxx00-aaaa:ADMIN",
|
||||
"test_domain#xxx00-aaaa:OWNER",
|
||||
// ..
|
||||
"rbactest.domain#xxx01-aaab:ADMIN",
|
||||
"rbactest.domain#xxx01-aaab:OWNER"
|
||||
"test_domain#xxx01-aaab:ADMIN",
|
||||
"test_domain#xxx01-aaab:OWNER"
|
||||
// @formatter:on
|
||||
);
|
||||
noneOfTheseRbacRolesIsReturned(
|
||||
result,
|
||||
// @formatter:off
|
||||
"rbac.global#global:ADMIN",
|
||||
"rbactest.customer#xxx:OWNER",
|
||||
"rbactest.package#yyy00:ADMIN",
|
||||
"rbactest.package#yyy00:OWNER",
|
||||
"rbactest.package#yyy00:TENANT"
|
||||
"test_customer#xxx:OWNER",
|
||||
"test_package#yyy00:ADMIN",
|
||||
"test_package#yyy00:OWNER",
|
||||
"test_package#yyy00:TENANT"
|
||||
// @formatter:on
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnRbacRole() {
|
||||
context.define("customer-admin@xxx.example.com", "rbactest.package#xxx00:ADMIN");
|
||||
context.define("customer-admin@xxx.example.com", "test_package#xxx00:ADMIN");
|
||||
|
||||
final var result = rbacRoleRepository.findAll();
|
||||
|
||||
exactlyTheseRbacRolesAreReturned(
|
||||
result,
|
||||
"rbactest.customer#xxx:TENANT",
|
||||
"rbactest.package#xxx00:ADMIN",
|
||||
"rbactest.package#xxx00:TENANT",
|
||||
"rbactest.domain#xxx00-aaaa:ADMIN",
|
||||
"rbactest.domain#xxx00-aaaa:OWNER",
|
||||
"rbactest.domain#xxx00-aaab:ADMIN",
|
||||
"rbactest.domain#xxx00-aaab:OWNER");
|
||||
"test_customer#xxx:TENANT",
|
||||
"test_package#xxx00:ADMIN",
|
||||
"test_package#xxx00:TENANT",
|
||||
"test_domain#xxx00-aaaa:ADMIN",
|
||||
"test_domain#xxx00-aaaa:OWNER",
|
||||
"test_domain#xxx00-aaab:ADMIN",
|
||||
"test_domain#xxx00-aaab:OWNER");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -157,10 +157,10 @@ class RbacRoleRepositoryIntegrationTest {
|
||||
void customerAdmin_withoutAssumedRole_canFindItsOwnRolesByName() {
|
||||
context.define("customer-admin@xxx.example.com");
|
||||
|
||||
final var result = rbacRoleRepository.findByRoleName("rbactest.customer#xxx:ADMIN");
|
||||
final var result = rbacRoleRepository.findByRoleName("test_customer#xxx:ADMIN");
|
||||
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getObjectTable()).isEqualTo("rbactest.customer");
|
||||
assertThat(result.getObjectTable()).isEqualTo("test_customer");
|
||||
assertThat(result.getObjectIdName()).isEqualTo("xxx");
|
||||
assertThat(result.getRoleType()).isEqualTo(RbacRoleType.ADMIN);
|
||||
}
|
||||
@ -169,7 +169,7 @@ class RbacRoleRepositoryIntegrationTest {
|
||||
void customerAdmin_withoutAssumedRole_canNotFindAlienRolesByName() {
|
||||
context.define("customer-admin@xxx.example.com");
|
||||
|
||||
final var result = rbacRoleRepository.findByRoleName("rbactest.customer#bbb:ADMIN");
|
||||
final var result = rbacRoleRepository.findByRoleName("test_customer#bbb:ADMIN");
|
||||
|
||||
assertThat(result).isNull();
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ import static java.util.UUID.randomUUID;
|
||||
public class TestRbacRole {
|
||||
|
||||
public static final RbacRoleEntity hostmasterRole = rbacRole("rbac.global", "global", RbacRoleType.ADMIN);
|
||||
static final RbacRoleEntity customerXxxOwner = rbacRole("rbactest.customer", "xxx", RbacRoleType.OWNER);
|
||||
static final RbacRoleEntity customerXxxAdmin = rbacRole("rbactest.customer", "xxx", RbacRoleType.ADMIN);
|
||||
static final RbacRoleEntity customerXxxOwner = rbacRole("test_customer", "xxx", RbacRoleType.OWNER);
|
||||
static final RbacRoleEntity customerXxxAdmin = rbacRole("test_customer", "xxx", RbacRoleType.ADMIN);
|
||||
|
||||
static public RbacRoleEntity rbacRole(final String objectTable, final String objectIdName, final RbacRoleType roleType) {
|
||||
return new RbacRoleEntity(randomUUID(), randomUUID(), objectTable, objectIdName, roleType, objectTable+'#'+objectIdName+':'+roleType);
|
||||
|
@ -100,7 +100,7 @@ class RbacSubjectControllerAcceptanceTest {
|
||||
RestAssured
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "rbactest.customer#yyy:ADMIN")
|
||||
.header("assumed-roles", "test_customer#yyy:ADMIN")
|
||||
.port(port)
|
||||
.when()
|
||||
.get("http://localhost/api/rbac/subjects/" + givenUser.getUuid())
|
||||
@ -201,7 +201,7 @@ class RbacSubjectControllerAcceptanceTest {
|
||||
RestAssured
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "rbactest.customer#yyy:ADMIN")
|
||||
.header("assumed-roles", "test_customer#yyy:ADMIN")
|
||||
.port(port)
|
||||
.when()
|
||||
.get("http://localhost/api/rbac/subjects")
|
||||
@ -275,12 +275,12 @@ class RbacSubjectControllerAcceptanceTest {
|
||||
.contentType("application/json")
|
||||
.body("", hasItem(
|
||||
allOf(
|
||||
hasEntry("roleName", "rbactest.customer#yyy:TENANT"),
|
||||
hasEntry("roleName", "test_customer#yyy:TENANT"),
|
||||
hasEntry("op", "SELECT"))
|
||||
))
|
||||
.body("", hasItem(
|
||||
allOf(
|
||||
hasEntry("roleName", "rbactest.domain#yyy00-aaaa:OWNER"),
|
||||
hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER"),
|
||||
hasEntry("op", "DELETE"))
|
||||
))
|
||||
// actual content tested in integration test, so this is enough for here:
|
||||
@ -296,7 +296,7 @@ class RbacSubjectControllerAcceptanceTest {
|
||||
RestAssured
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "rbactest.customer#yyy:ADMIN")
|
||||
.header("assumed-roles", "test_customer#yyy:ADMIN")
|
||||
.port(port)
|
||||
.when()
|
||||
.get("http://localhost/api/rbac/subjects/" + givenUser.getUuid() + "/permissions")
|
||||
@ -305,12 +305,12 @@ class RbacSubjectControllerAcceptanceTest {
|
||||
.contentType("application/json")
|
||||
.body("", hasItem(
|
||||
allOf(
|
||||
hasEntry("roleName", "rbactest.customer#yyy:TENANT"),
|
||||
hasEntry("roleName", "test_customer#yyy:TENANT"),
|
||||
hasEntry("op", "SELECT"))
|
||||
))
|
||||
.body("", hasItem(
|
||||
allOf(
|
||||
hasEntry("roleName", "rbactest.domain#yyy00-aaaa:OWNER"),
|
||||
hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER"),
|
||||
hasEntry("op", "DELETE"))
|
||||
))
|
||||
// actual content tested in integration test, so this is enough for here:
|
||||
@ -334,12 +334,12 @@ class RbacSubjectControllerAcceptanceTest {
|
||||
.contentType("application/json")
|
||||
.body("", hasItem(
|
||||
allOf(
|
||||
hasEntry("roleName", "rbactest.customer#yyy:TENANT"),
|
||||
hasEntry("roleName", "test_customer#yyy:TENANT"),
|
||||
hasEntry("op", "SELECT"))
|
||||
))
|
||||
.body("", hasItem(
|
||||
allOf(
|
||||
hasEntry("roleName", "rbactest.domain#yyy00-aaaa:OWNER"),
|
||||
hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER"),
|
||||
hasEntry("op", "DELETE"))
|
||||
))
|
||||
// actual content tested in integration test, so this is enough for here:
|
||||
|
@ -128,7 +128,7 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest {
|
||||
@Test
|
||||
public void globalAdmin_withAssumedCustomerAdminRole_canViewOnlyUsersHavingRolesInThatCustomersRealm() {
|
||||
given:
|
||||
context("superuser-alex@hostsharing.net", "rbactest.customer#xxx:ADMIN");
|
||||
context("superuser-alex@hostsharing.net", "test_customer#xxx:ADMIN");
|
||||
|
||||
// when
|
||||
final var result = rbacSubjectRepository.findByOptionalNameLike(null);
|
||||
@ -159,7 +159,7 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest {
|
||||
|
||||
@Test
|
||||
public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyUsersHavingRolesInThatPackage() {
|
||||
context("customer-admin@xxx.example.com", "rbactest.package#xxx00:ADMIN");
|
||||
context("customer-admin@xxx.example.com", "test_package#xxx00:ADMIN");
|
||||
|
||||
final var result = rbacSubjectRepository.findByOptionalNameLike(null);
|
||||
|
||||
@ -182,47 +182,47 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest {
|
||||
|
||||
private static final String[] ALL_USER_PERMISSIONS = Array.of(
|
||||
// @formatter:off
|
||||
"rbactest.customer#xxx:ADMIN -> rbactest.customer#xxx: SELECT",
|
||||
"rbactest.customer#xxx:OWNER -> rbactest.customer#xxx: DELETE",
|
||||
"rbactest.customer#xxx:TENANT -> rbactest.customer#xxx: SELECT",
|
||||
"rbactest.customer#xxx:ADMIN -> rbactest.customer#xxx: INSERT:rbactest.package",
|
||||
"rbactest.package#xxx00:ADMIN -> rbactest.package#xxx00: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx00:ADMIN -> rbactest.package#xxx00: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx00:TENANT -> rbactest.package#xxx00: SELECT",
|
||||
"rbactest.package#xxx01:ADMIN -> rbactest.package#xxx01: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx01:ADMIN -> rbactest.package#xxx01: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx01:TENANT -> rbactest.package#xxx01: SELECT",
|
||||
"rbactest.package#xxx02:ADMIN -> rbactest.package#xxx02: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx02:ADMIN -> rbactest.package#xxx02: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx02:TENANT -> rbactest.package#xxx02: SELECT",
|
||||
"test_customer#xxx:ADMIN -> test_customer#xxx: SELECT",
|
||||
"test_customer#xxx:OWNER -> test_customer#xxx: DELETE",
|
||||
"test_customer#xxx:TENANT -> test_customer#xxx: SELECT",
|
||||
"test_customer#xxx:ADMIN -> test_customer#xxx: INSERT:test_package",
|
||||
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
|
||||
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
|
||||
"test_package#xxx00:TENANT -> test_package#xxx00: SELECT",
|
||||
"test_package#xxx01:ADMIN -> test_package#xxx01: INSERT:test_domain",
|
||||
"test_package#xxx01:ADMIN -> test_package#xxx01: INSERT:test_domain",
|
||||
"test_package#xxx01:TENANT -> test_package#xxx01: SELECT",
|
||||
"test_package#xxx02:ADMIN -> test_package#xxx02: INSERT:test_domain",
|
||||
"test_package#xxx02:ADMIN -> test_package#xxx02: INSERT:test_domain",
|
||||
"test_package#xxx02:TENANT -> test_package#xxx02: SELECT",
|
||||
|
||||
"rbactest.customer#yyy:ADMIN -> rbactest.customer#yyy: SELECT",
|
||||
"rbactest.customer#yyy:OWNER -> rbactest.customer#yyy: DELETE",
|
||||
"rbactest.customer#yyy:TENANT -> rbactest.customer#yyy: SELECT",
|
||||
"rbactest.customer#yyy:ADMIN -> rbactest.customer#yyy: INSERT:rbactest.package",
|
||||
"rbactest.package#yyy00:ADMIN -> rbactest.package#yyy00: INSERT:rbactest.domain",
|
||||
"rbactest.package#yyy00:ADMIN -> rbactest.package#yyy00: INSERT:rbactest.domain",
|
||||
"rbactest.package#yyy00:TENANT -> rbactest.package#yyy00: SELECT",
|
||||
"rbactest.package#yyy01:ADMIN -> rbactest.package#yyy01: INSERT:rbactest.domain",
|
||||
"rbactest.package#yyy01:ADMIN -> rbactest.package#yyy01: INSERT:rbactest.domain",
|
||||
"rbactest.package#yyy01:TENANT -> rbactest.package#yyy01: SELECT",
|
||||
"rbactest.package#yyy02:ADMIN -> rbactest.package#yyy02: INSERT:rbactest.domain",
|
||||
"rbactest.package#yyy02:ADMIN -> rbactest.package#yyy02: INSERT:rbactest.domain",
|
||||
"rbactest.package#yyy02:TENANT -> rbactest.package#yyy02: SELECT",
|
||||
"test_customer#yyy:ADMIN -> test_customer#yyy: SELECT",
|
||||
"test_customer#yyy:OWNER -> test_customer#yyy: DELETE",
|
||||
"test_customer#yyy:TENANT -> test_customer#yyy: SELECT",
|
||||
"test_customer#yyy:ADMIN -> test_customer#yyy: INSERT:test_package",
|
||||
"test_package#yyy00:ADMIN -> test_package#yyy00: INSERT:test_domain",
|
||||
"test_package#yyy00:ADMIN -> test_package#yyy00: INSERT:test_domain",
|
||||
"test_package#yyy00:TENANT -> test_package#yyy00: SELECT",
|
||||
"test_package#yyy01:ADMIN -> test_package#yyy01: INSERT:test_domain",
|
||||
"test_package#yyy01:ADMIN -> test_package#yyy01: INSERT:test_domain",
|
||||
"test_package#yyy01:TENANT -> test_package#yyy01: SELECT",
|
||||
"test_package#yyy02:ADMIN -> test_package#yyy02: INSERT:test_domain",
|
||||
"test_package#yyy02:ADMIN -> test_package#yyy02: INSERT:test_domain",
|
||||
"test_package#yyy02:TENANT -> test_package#yyy02: SELECT",
|
||||
|
||||
"rbactest.customer#zzz:ADMIN -> rbactest.customer#zzz: SELECT",
|
||||
"rbactest.customer#zzz:OWNER -> rbactest.customer#zzz: DELETE",
|
||||
"rbactest.customer#zzz:TENANT -> rbactest.customer#zzz: SELECT",
|
||||
"rbactest.customer#zzz:ADMIN -> rbactest.customer#zzz: INSERT:rbactest.package",
|
||||
"rbactest.package#zzz00:ADMIN -> rbactest.package#zzz00: INSERT:rbactest.domain",
|
||||
"rbactest.package#zzz00:ADMIN -> rbactest.package#zzz00: INSERT:rbactest.domain",
|
||||
"rbactest.package#zzz00:TENANT -> rbactest.package#zzz00: SELECT",
|
||||
"rbactest.package#zzz01:ADMIN -> rbactest.package#zzz01: INSERT:rbactest.domain",
|
||||
"rbactest.package#zzz01:ADMIN -> rbactest.package#zzz01: INSERT:rbactest.domain",
|
||||
"rbactest.package#zzz01:TENANT -> rbactest.package#zzz01: SELECT",
|
||||
"rbactest.package#zzz02:ADMIN -> rbactest.package#zzz02: INSERT:rbactest.domain",
|
||||
"rbactest.package#zzz02:ADMIN -> rbactest.package#zzz02: INSERT:rbactest.domain",
|
||||
"rbactest.package#zzz02:TENANT -> rbactest.package#zzz02: SELECT"
|
||||
"test_customer#zzz:ADMIN -> test_customer#zzz: SELECT",
|
||||
"test_customer#zzz:OWNER -> test_customer#zzz: DELETE",
|
||||
"test_customer#zzz:TENANT -> test_customer#zzz: SELECT",
|
||||
"test_customer#zzz:ADMIN -> test_customer#zzz: INSERT:test_package",
|
||||
"test_package#zzz00:ADMIN -> test_package#zzz00: INSERT:test_domain",
|
||||
"test_package#zzz00:ADMIN -> test_package#zzz00: INSERT:test_domain",
|
||||
"test_package#zzz00:TENANT -> test_package#zzz00: SELECT",
|
||||
"test_package#zzz01:ADMIN -> test_package#zzz01: INSERT:test_domain",
|
||||
"test_package#zzz01:ADMIN -> test_package#zzz01: INSERT:test_domain",
|
||||
"test_package#zzz01:TENANT -> test_package#zzz01: SELECT",
|
||||
"test_package#zzz02:ADMIN -> test_package#zzz02: INSERT:test_domain",
|
||||
"test_package#zzz02:ADMIN -> test_package#zzz02: INSERT:test_domain",
|
||||
"test_package#zzz02:TENANT -> test_package#zzz02: SELECT"
|
||||
// @formatter:on
|
||||
);
|
||||
|
||||
@ -233,7 +233,7 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest {
|
||||
|
||||
// when
|
||||
final var result = rbacSubjectRepository.findPermissionsOfUserByUuid(subjectUuid("superuser-fran@hostsharing.net"))
|
||||
.stream().filter(p -> p.getObjectTable().contains("rbactest."))
|
||||
.stream().filter(p -> p.getObjectTable().contains("test_"))
|
||||
.sorted(comparing(RbacSubjectPermission::toString)).toList();
|
||||
|
||||
// then
|
||||
@ -252,32 +252,32 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest {
|
||||
allTheseRbacPermissionsAreReturned(
|
||||
result,
|
||||
// @formatter:off
|
||||
"rbactest.customer#xxx:ADMIN -> rbactest.customer#xxx: INSERT:rbactest.package",
|
||||
"rbactest.customer#xxx:ADMIN -> rbactest.customer#xxx: SELECT",
|
||||
"rbactest.customer#xxx:TENANT -> rbactest.customer#xxx: SELECT",
|
||||
"test_customer#xxx:ADMIN -> test_customer#xxx: INSERT:test_package",
|
||||
"test_customer#xxx:ADMIN -> test_customer#xxx: SELECT",
|
||||
"test_customer#xxx:TENANT -> test_customer#xxx: SELECT",
|
||||
|
||||
"rbactest.package#xxx00:ADMIN -> rbactest.package#xxx00: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx00:ADMIN -> rbactest.package#xxx00: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx00:TENANT -> rbactest.package#xxx00: SELECT",
|
||||
"rbactest.domain#xxx00-aaaa:OWNER -> rbactest.domain#xxx00-aaaa: DELETE",
|
||||
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
|
||||
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
|
||||
"test_package#xxx00:TENANT -> test_package#xxx00: SELECT",
|
||||
"test_domain#xxx00-aaaa:OWNER -> test_domain#xxx00-aaaa: DELETE",
|
||||
|
||||
"rbactest.package#xxx01:ADMIN -> rbactest.package#xxx01: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx01:ADMIN -> rbactest.package#xxx01: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx01:TENANT -> rbactest.package#xxx01: SELECT",
|
||||
"rbactest.domain#xxx01-aaaa:OWNER -> rbactest.domain#xxx01-aaaa: DELETE",
|
||||
"test_package#xxx01:ADMIN -> test_package#xxx01: INSERT:test_domain",
|
||||
"test_package#xxx01:ADMIN -> test_package#xxx01: INSERT:test_domain",
|
||||
"test_package#xxx01:TENANT -> test_package#xxx01: SELECT",
|
||||
"test_domain#xxx01-aaaa:OWNER -> test_domain#xxx01-aaaa: DELETE",
|
||||
|
||||
"rbactest.package#xxx02:ADMIN -> rbactest.package#xxx02: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx02:ADMIN -> rbactest.package#xxx02: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx02:TENANT -> rbactest.package#xxx02: SELECT",
|
||||
"rbactest.domain#xxx02-aaaa:OWNER -> rbactest.domain#xxx02-aaaa: DELETE"
|
||||
"test_package#xxx02:ADMIN -> test_package#xxx02: INSERT:test_domain",
|
||||
"test_package#xxx02:ADMIN -> test_package#xxx02: INSERT:test_domain",
|
||||
"test_package#xxx02:TENANT -> test_package#xxx02: SELECT",
|
||||
"test_domain#xxx02-aaaa:OWNER -> test_domain#xxx02-aaaa: DELETE"
|
||||
// @formatter:on
|
||||
);
|
||||
noneOfTheseRbacPermissionsAreReturned(
|
||||
result,
|
||||
// @formatter:off
|
||||
"rbactest.customer#yyy:ADMIN -> rbactest.customer#yyy: INSERT:rbactest.package",
|
||||
"rbactest.customer#yyy:ADMIN -> rbactest.customer#yyy: SELECT",
|
||||
"rbactest.customer#yyy:TENANT -> rbactest.customer#yyy: SELECT"
|
||||
"test_customer#yyy:ADMIN -> test_customer#yyy: INSERT:test_package",
|
||||
"test_customer#yyy:ADMIN -> test_customer#yyy: SELECT",
|
||||
"test_customer#yyy:TENANT -> test_customer#yyy: SELECT"
|
||||
// @formatter:on
|
||||
);
|
||||
}
|
||||
@ -312,26 +312,26 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest {
|
||||
allTheseRbacPermissionsAreReturned(
|
||||
result,
|
||||
// @formatter:off
|
||||
"rbactest.customer#xxx:TENANT -> rbactest.customer#xxx: SELECT",
|
||||
// "rbactest.customer#xxx:ADMIN -> rbactest.customer#xxx: view" - Not permissions through the customer admin!
|
||||
"rbactest.package#xxx00:ADMIN -> rbactest.package#xxx00: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx00:ADMIN -> rbactest.package#xxx00: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx00:TENANT -> rbactest.package#xxx00: SELECT",
|
||||
"rbactest.domain#xxx00-aaaa:OWNER -> rbactest.domain#xxx00-aaaa: DELETE",
|
||||
"rbactest.domain#xxx00-aaab:OWNER -> rbactest.domain#xxx00-aaab: DELETE"
|
||||
"test_customer#xxx:TENANT -> test_customer#xxx: SELECT",
|
||||
// "test_customer#xxx:ADMIN -> test_customer#xxx: view" - Not permissions through the customer admin!
|
||||
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
|
||||
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
|
||||
"test_package#xxx00:TENANT -> test_package#xxx00: SELECT",
|
||||
"test_domain#xxx00-aaaa:OWNER -> test_domain#xxx00-aaaa: DELETE",
|
||||
"test_domain#xxx00-aaab:OWNER -> test_domain#xxx00-aaab: DELETE"
|
||||
// @formatter:on
|
||||
);
|
||||
noneOfTheseRbacPermissionsAreReturned(
|
||||
result,
|
||||
// @formatter:off
|
||||
"rbactest.customer#yyy:ADMIN -> rbactest.customer#yyy: INSERT:rbactest.package",
|
||||
"rbactest.customer#yyy:ADMIN -> rbactest.customer#yyy: SELECT",
|
||||
"rbactest.customer#yyy:TENANT -> rbactest.customer#yyy: SELECT",
|
||||
"rbactest.package#yyy00:ADMIN -> rbactest.package#yyy00: INSERT:rbactest.domain",
|
||||
"rbactest.package#yyy00:ADMIN -> rbactest.package#yyy00: INSERT:rbactest.domain",
|
||||
"rbactest.package#yyy00:TENANT -> rbactest.package#yyy00: SELECT",
|
||||
"rbactest.domain#yyy00-aaaa:OWNER -> rbactest.domain#yyy00-aaaa: DELETE",
|
||||
"rbactest.domain#yyy00-aaab:OWNER -> rbactest.domain#yyy00-aaab: DELETE"
|
||||
"test_customer#yyy:ADMIN -> test_customer#yyy: INSERT:test_package",
|
||||
"test_customer#yyy:ADMIN -> test_customer#yyy: SELECT",
|
||||
"test_customer#yyy:TENANT -> test_customer#yyy: SELECT",
|
||||
"test_package#yyy00:ADMIN -> test_package#yyy00: INSERT:test_domain",
|
||||
"test_package#yyy00:ADMIN -> test_package#yyy00: INSERT:test_domain",
|
||||
"test_package#yyy00:TENANT -> test_package#yyy00: SELECT",
|
||||
"test_domain#yyy00-aaaa:OWNER -> test_domain#yyy00-aaaa: DELETE",
|
||||
"test_domain#yyy00-aaab:OWNER -> test_domain#yyy00-aaab: DELETE"
|
||||
// @formatter:on
|
||||
);
|
||||
}
|
||||
@ -360,26 +360,26 @@ class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest {
|
||||
allTheseRbacPermissionsAreReturned(
|
||||
result,
|
||||
// @formatter:off
|
||||
"rbactest.customer#xxx:TENANT -> rbactest.customer#xxx: SELECT",
|
||||
// "rbactest.customer#xxx:ADMIN -> rbactest.customer#xxx: view" - Not permissions through the customer admin!
|
||||
"rbactest.package#xxx00:ADMIN -> rbactest.package#xxx00: INSERT:rbactest.domain",
|
||||
"rbactest.package#xxx00:TENANT -> rbactest.package#xxx00: SELECT"
|
||||
"test_customer#xxx:TENANT -> test_customer#xxx: SELECT",
|
||||
// "test_customer#xxx:ADMIN -> test_customer#xxx: view" - Not permissions through the customer admin!
|
||||
"test_package#xxx00:ADMIN -> test_package#xxx00: INSERT:test_domain",
|
||||
"test_package#xxx00:TENANT -> test_package#xxx00: SELECT"
|
||||
// @formatter:on
|
||||
);
|
||||
noneOfTheseRbacPermissionsAreReturned(
|
||||
result,
|
||||
// @formatter:off
|
||||
// no customer admin permissions
|
||||
"rbactest.customer#xxx:ADMIN -> rbactest.customer#xxx: add-package",
|
||||
"test_customer#xxx:ADMIN -> test_customer#xxx: add-package",
|
||||
// no permissions on other customer's objects
|
||||
"rbactest.customer#yyy:ADMIN -> rbactest.customer#yyy: add-package",
|
||||
"rbactest.customer#yyy:ADMIN -> rbactest.customer#yyy: SELECT",
|
||||
"rbactest.customer#yyy:TENANT -> rbactest.customer#yyy: SELECT",
|
||||
"rbactest.package#yyy00:ADMIN -> rbactest.package#yyy00: INSERT:rbactest.domain",
|
||||
"rbactest.package#yyy00:ADMIN -> rbactest.package#yyy00: INSERT:rbactest.domain",
|
||||
"rbactest.package#yyy00:TENANT -> rbactest.package#yyy00: SELECT",
|
||||
"rbactest.domain#yyy00-aaaa:OWNER -> rbactest.domain#yyy00-aaaa: DELETE",
|
||||
"rbactest.domain#yyy00-xxxb:OWNER -> rbactest.domain#yyy00-xxxb: DELETE"
|
||||
"test_customer#yyy:ADMIN -> test_customer#yyy: add-package",
|
||||
"test_customer#yyy:ADMIN -> test_customer#yyy: SELECT",
|
||||
"test_customer#yyy:TENANT -> test_customer#yyy: SELECT",
|
||||
"test_package#yyy00:ADMIN -> test_package#yyy00: INSERT:test_domain",
|
||||
"test_package#yyy00:ADMIN -> test_package#yyy00: INSERT:test_domain",
|
||||
"test_package#yyy00:TENANT -> test_package#yyy00: SELECT",
|
||||
"test_domain#yyy00-aaaa:OWNER -> test_domain#yyy00-aaaa: DELETE",
|
||||
"test_domain#yyy00-xxxb:OWNER -> test_domain#yyy00-xxxb: DELETE"
|
||||
// @formatter:on
|
||||
);
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ class TestCustomerControllerAcceptanceTest {
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "rbactest.customer#yyy:ADMIN")
|
||||
.header("assumed-roles", "test_customer#yyy:ADMIN")
|
||||
.port(port)
|
||||
.when()
|
||||
.get("http://localhost/api/test/customers")
|
||||
@ -148,7 +148,7 @@ class TestCustomerControllerAcceptanceTest {
|
||||
// finally, the new customer can be viewed by its own admin
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
context.define("superuser-fran@hostsharing.net", "rbactest.customer#uuu:ADMIN");
|
||||
context.define("superuser-fran@hostsharing.net", "test_customer#uuu:ADMIN");
|
||||
assertThat(testCustomerRepository.findByUuid(newSubjectUuid))
|
||||
.hasValueSatisfying(c -> assertThat(c.getPrefix()).isEqualTo("uuu"));
|
||||
}
|
||||
@ -159,7 +159,7 @@ class TestCustomerControllerAcceptanceTest {
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "rbactest.customer#xxx:ADMIN")
|
||||
.header("assumed-roles", "test_customer#xxx:ADMIN")
|
||||
.contentType(ContentType.JSON)
|
||||
.body("""
|
||||
{
|
||||
@ -175,8 +175,8 @@ class TestCustomerControllerAcceptanceTest {
|
||||
.statusCode(403)
|
||||
.contentType(ContentType.JSON)
|
||||
.statusCode(403)
|
||||
.body("message", containsString("ERROR: [403] insert into rbactest.customer "))
|
||||
.body("message", containsString(" not allowed for current subjects {rbactest.customer#xxx:ADMIN}"));
|
||||
.body("message", containsString("ERROR: [403] insert into test_customer "))
|
||||
.body("message", containsString(" not allowed for current subjects {test_customer#xxx:ADMIN}"));
|
||||
// @formatter:on
|
||||
|
||||
// finally, the new customer was not created
|
||||
@ -205,7 +205,7 @@ class TestCustomerControllerAcceptanceTest {
|
||||
.statusCode(403)
|
||||
.contentType(ContentType.JSON)
|
||||
.statusCode(403)
|
||||
.body("message", containsString("ERROR: [403] insert into rbactest.customer "))
|
||||
.body("message", containsString("ERROR: [403] insert into test_customer "))
|
||||
.body("message", containsString(" not allowed for current subjects"));
|
||||
// @formatter:on
|
||||
|
||||
|
@ -54,7 +54,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
|
||||
@Test
|
||||
public void globalAdmin_withAssumedCustomerRole_cannotCreateNewCustomer() {
|
||||
// given
|
||||
context("superuser-alex@hostsharing.net", "rbactest.customer#xxx:ADMIN");
|
||||
context("superuser-alex@hostsharing.net", "test_customer#xxx:ADMIN");
|
||||
|
||||
// when
|
||||
final var result = attempt(em, () -> {
|
||||
@ -66,8 +66,8 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
|
||||
// then
|
||||
result.assertExceptionWithRootCauseMessage(
|
||||
PersistenceException.class,
|
||||
"ERROR: [403] insert into rbactest.customer ",
|
||||
"not allowed for current subjects {rbactest.customer#xxx:ADMIN}");
|
||||
"ERROR: [403] insert into test_customer ",
|
||||
"not allowed for current subjects {test_customer#xxx:ADMIN}");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -85,7 +85,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
|
||||
// then
|
||||
result.assertExceptionWithRootCauseMessage(
|
||||
PersistenceException.class,
|
||||
"ERROR: [403] insert into rbactest.customer ",
|
||||
"ERROR: [403] insert into test_customer ",
|
||||
" not allowed for current subjects {customer-admin@xxx.example.com}");
|
||||
|
||||
}
|
||||
@ -114,7 +114,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
|
||||
@Test
|
||||
public void globalAdmin_withAssumedCustomerOwnerRole_canViewExactlyThatCustomer() {
|
||||
given:
|
||||
context("superuser-alex@hostsharing.net", "rbactest.customer#yyy:OWNER");
|
||||
context("superuser-alex@hostsharing.net", "test_customer#yyy:OWNER");
|
||||
|
||||
// when
|
||||
final var result = testCustomerRepository.findCustomerByOptionalPrefixLike(null);
|
||||
@ -139,7 +139,7 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
|
||||
public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnCustomer() {
|
||||
context("customer-admin@xxx.example.com");
|
||||
|
||||
context("customer-admin@xxx.example.com", "rbactest.package#xxx00:ADMIN");
|
||||
context("customer-admin@xxx.example.com", "test_package#xxx00:ADMIN");
|
||||
|
||||
final var result = testCustomerRepository.findCustomerByOptionalPrefixLike(null);
|
||||
|
||||
|
@ -44,7 +44,7 @@ class TestPackageControllerAcceptanceTest {
|
||||
RestAssured
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "rbactest.customer#xxx:ADMIN")
|
||||
.header("assumed-roles", "test_customer#xxx:ADMIN")
|
||||
.port(port)
|
||||
.when()
|
||||
.get("http://localhost/api/test/packages")
|
||||
@ -66,7 +66,7 @@ class TestPackageControllerAcceptanceTest {
|
||||
RestAssured
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "rbactest.customer#xxx:ADMIN")
|
||||
.header("assumed-roles", "test_customer#xxx:ADMIN")
|
||||
.port(port)
|
||||
.when()
|
||||
.get("http://localhost/api/test/packages?name=xxx01")
|
||||
@ -95,7 +95,7 @@ class TestPackageControllerAcceptanceTest {
|
||||
RestAssured
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "rbactest.customer#xxx:ADMIN")
|
||||
.header("assumed-roles", "test_customer#xxx:ADMIN")
|
||||
.contentType(ContentType.JSON)
|
||||
.body(format("""
|
||||
{
|
||||
@ -126,7 +126,7 @@ class TestPackageControllerAcceptanceTest {
|
||||
RestAssured
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "rbactest.customer#xxx:ADMIN")
|
||||
.header("assumed-roles", "test_customer#xxx:ADMIN")
|
||||
.contentType(ContentType.JSON)
|
||||
.body("""
|
||||
{
|
||||
@ -156,7 +156,7 @@ class TestPackageControllerAcceptanceTest {
|
||||
RestAssured
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "rbactest.customer#xxx:ADMIN")
|
||||
.header("assumed-roles", "test_customer#xxx:ADMIN")
|
||||
.contentType(ContentType.JSON)
|
||||
.body("{}")
|
||||
.port(port)
|
||||
@ -176,7 +176,7 @@ class TestPackageControllerAcceptanceTest {
|
||||
return UUID.fromString(RestAssured
|
||||
.given()
|
||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "rbactest.customer#xxx:ADMIN")
|
||||
.header("assumed-roles", "test_customer#xxx:ADMIN")
|
||||
.port(port)
|
||||
.when()
|
||||
.get("http://localhost/api/test/packages?name={packageName}", packageName)
|
||||
@ -188,7 +188,7 @@ class TestPackageControllerAcceptanceTest {
|
||||
}
|
||||
|
||||
String getDescriptionOfPackage(final String packageName) {
|
||||
context.define("superuser-alex@hostsharing.net","rbactest.customer#xxx:ADMIN");
|
||||
context.define("superuser-alex@hostsharing.net","test_customer#xxx:ADMIN");
|
||||
return testPackageRepository.findAllByOptionalNameLike(packageName).get(0).getDescription();
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ class TestPackageRepositoryIntegrationTest extends ContextBasedTest {
|
||||
|
||||
@Test
|
||||
public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnPackages() {
|
||||
context.define("customer-admin@xxx.example.com", "rbactest.package#xxx00:ADMIN");
|
||||
context.define("customer-admin@xxx.example.com", "test_package#xxx00:ADMIN");
|
||||
|
||||
final var result = testPackageRepository.findAllByOptionalNameLike(null);
|
||||
|
||||
@ -90,17 +90,17 @@ class TestPackageRepositoryIntegrationTest extends ContextBasedTest {
|
||||
@Test
|
||||
public void supportsOptimisticLocking() {
|
||||
// given
|
||||
globalAdminWithAssumedRole("rbactest.package#xxx00:ADMIN");
|
||||
globalAdminWithAssumedRole("test_package#xxx00:ADMIN");
|
||||
final var pac = testPackageRepository.findAllByOptionalNameLike("%").get(0);
|
||||
|
||||
// when
|
||||
final var result1 = jpaAttempt.transacted(() -> {
|
||||
globalAdminWithAssumedRole("rbactest.package#xxx00:OWNER");
|
||||
globalAdminWithAssumedRole("test_package#xxx00:OWNER");
|
||||
pac.setDescription("description set by thread 1");
|
||||
testPackageRepository.save(pac);
|
||||
});
|
||||
final var result2 = jpaAttempt.transacted(() -> {
|
||||
globalAdminWithAssumedRole("rbactest.package#xxx00:OWNER");
|
||||
globalAdminWithAssumedRole("test_package#xxx00:OWNER");
|
||||
pac.setDescription("description set by thread 2");
|
||||
testPackageRepository.save(pac);
|
||||
sleep(1500);
|
||||
|
@ -5,7 +5,6 @@ spring:
|
||||
|
||||
datasource:
|
||||
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: ${spring.datasource.url-tc}
|
||||
username: postgres
|
||||
|
Loading…
Reference in New Issue
Block a user