RBAC generator with conditional grants used for REPRESENTATIVE-Relation #33

Merged
hsh-michaelhoennig merged 31 commits from rbac-generator-with-conditional-grants into master 2024-04-08 11:16:07 +02:00
89 changed files with 1129 additions and 1327 deletions
Showing only changes of commit da5eea8000 - Show all commits

View File

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

View File

@ -27,8 +27,8 @@ Objektorientiert gedacht, enthalten solche Objekte die Zusatzdaten einer Subklas
- Für die Rollenzuordnung zwischen referenzierten Objekten gilt: - Für die Rollenzuordnung zwischen referenzierten Objekten gilt:
- Für Objekte vom Typ Root werden die Rollen des zugehörigen Aggregator-Objektes verwendet. - Für Objekte vom Typ Root werden die Rollen des zugehörigen Aggregator-Objektes verwendet.
- Gibt es Referenzen auf hierarchisch verbundene Objekte (z.B. Debitor.refundBankAccount) gilt folgende Faustregel: - Gibt es Referenzen auf hierarchisch verbundene Objekte (z.B. Debitor.refundBankAccount) gilt folgende Faustregel:
***Nach oben absteigen, nach unten halten oder aufsteigen.*** An einem fachlich übergeordneten Objekt wird also eine niedrigere Rolle (z.B. Debitor-admin -> Partner.agent), einem fachlich untergeordneten Objekt eine gleichwertige Rolle (z.B. Partner.admin -> Debitor.admin) zugewiesen oder sogar aufgestiegen (Debitor.admin -> Package.tenant). ***Nach oben absteigen, nach unten halten oder aufsteigen.*** An einem fachlich übergeordneten Objekt wird also eine niedrigere Rolle (z.B. Debitor.ADMIN -> Partner.AGENT), einem fachlich untergeordneten Objekt eine gleichwertige Rolle (z.B. Partner.ADMIN -> Debitor.ADMIN) zugewiesen oder sogar aufgestiegen (Debitor.ADMIN -> Package.TENANT).
- Für Referenzen zwischen Objekten, die nicht hierarchisch zueinander stehen (z.B. Debitor und Bankverbindung), wird auf beiden seiten abgestiegen (also Debitor.admin -> BankAccount.referrer und BankAccount.admin -> Debitor.tenant). - Für Referenzen zwischen Objekten, die nicht hierarchisch zueinander stehen (z.B. Debitor und Bankverbindung), wird auf beiden seiten abgestiegen (also Debitor.ADMIN -> BankAccount.REFERRER und BankAccount.ADMIN -> Debitor.TENANT).
Anmerkung: Der Typ-Begriff *Root* bezieht sich auf die Rolle im fachlichen Datenmodell. Im Bezug auf den Teilgraphen eines fachlichen Kontexts ist dies auch eine Wurzel im Sinne der Graphentheorie. Aber in anderen fachlichen Kontexten können auch diese Objekte von anderen Teilgraphen referenziert werden und werden dann zum inneren Knoten. Anmerkung: Der Typ-Begriff *Root* bezieht sich auf die Rolle im fachlichen Datenmodell. Im Bezug auf den Teilgraphen eines fachlichen Kontexts ist dies auch eine Wurzel im Sinne der Graphentheorie. Aber in anderen fachlichen Kontexten können auch diese Objekte von anderen Teilgraphen referenziert werden und werden dann zum inneren Knoten.

View File

@ -16,11 +16,11 @@ Beim Debitor ist das nämlich selbst mit Generator die Hölle, zumal eben auch Q
Mit anderen Worten, um als Repräsentant eines Geschäftspartners auf den Bank-Account der Sepa-Mandate sehen zu dürfen, wird derzeut folgende Grant-Kette durchlaufen (bzw. eben noch nicht, weil es noch nicht funktioniert): Mit anderen Worten, um als Repräsentant eines Geschäftspartners auf den Bank-Account der Sepa-Mandate sehen zu dürfen, wird derzeut folgende Grant-Kette durchlaufen (bzw. eben noch nicht, weil es noch nicht funktioniert):
User -> Partner-Holder-Person:Admin -> Partner-Relation:Agent -> Debitor-Relation:Agent -> Sepa-Mandat:Admin -> BankAccount:Admin -> BankAccount:SELECT User -> Partner-Holder-Person:ADMIN -> Partner-Relation:AGENT -> Debitor-Relation:AGENT -> Sepa-Mandat:ADMIN -> BankAccount:ADMIN -> BankAccount:SELECT
Daraus würde: Daraus würde:
User -> Partner-Relation:Agent -> Debitor-Relation:Agent -> Sepa-Mandat:Admin -> Sepa-Mandat:SELECT* User -> Partner-Relation:AGENT -> Debitor-Relation:AGENT -> Sepa-Mandat:ADMIN -> Sepa-Mandat:SELECT*
(*mit JOIN auf RawBankAccount, also implizitem Leserecht) (*mit JOIN auf RawBankAccount, also implizitem Leserecht)

View File

@ -196,24 +196,24 @@ E.g. if a new package is added, the admin-role of the related customer has to be
There can be global roles like 'administrators'. There can be global roles like 'administrators'.
Most roles, though, are specific for certain business-objects and automatically generated as such: Most roles, though, are specific for certain business-objects and automatically generated as such:
business-object-table#business-object-name.relative-role business-object-table#business-object-name.role-stereotype
Where *business-object-table* is the name of the SQL table of the business object (e.g *customer* or 'package'), Where *business-object-table* is the name of the SQL table of the business object (e.g *customer* or 'package'),
*business-object-name* is generated from an immutable business key(e.g. a prefix like 'xyz' or 'xyz00') *business-object-name* is generated from an immutable business key(e.g. a prefix like 'xyz' or 'xyz00')
and the *relative-role*' describes the role relative to the referenced business-object as follows: and the *role-stereotype* describes a role relative to a referenced business-object as follows:
#### owner #### owner
The owner-role is granted to the subject which created the business object. The owner-role is granted to the subject which created the business object.
E.g. for a new *customer* it would be granted to 'administrators' and for a new *package* to the 'customer#...admin'. E.g. for a new *customer* it would be granted to 'administrators' and for a new *package* to the 'customer#...:admin'.
Whoever has the owner-role assigned can do everything with the related business-object, including deleting (or deactivating) it. Whoever has the owner-role assigned can do everything with the related business-object, including deleting (or deactivating) it.
In most cases, the permissions to other operations than 'DELETE' are granted through the 'admin' role. In most cases, the permissions to other operations than 'DELETE' are granted through the 'admin' role.
By this, all roles ob sub-objects, which are assigned to the 'admin' role, are also granted to the 'owner'. By this, all roles ob sub-objects, which are assigned to the 'admin' role, are also granted to the 'owner'.
#### admin #### ADMIN
The admin-role is granted to a role of those subjects who manage the business object. The admin-role is granted to a role of those subjects who manage the business object.
E.g. a 'package' is manged by the admin of the customer. E.g. a 'package' is manged by the admin of the customer.
@ -222,7 +222,7 @@ Whoever has the admin-role assigned, can usually update the related business-obj
The admin-role also comprises lesser roles, through which the SELECT-permission is granted. The admin-role also comprises lesser roles, through which the SELECT-permission is granted.
#### agent #### AGENT
The agent-role is not used in the examples of this document, because it's for more complex cases. The agent-role is not used in the examples of this document, because it's for more complex cases.
It's usually granted to those roles and users who represent the related business-object, but are not allowed to update it. It's usually granted to those roles and users who represent the related business-object, but are not allowed to update it.
@ -231,21 +231,25 @@ Other than the tenant-role, it usually offers broader visibility of sub-business
E.g. a package-admin is allowed to see the related debitor-business-object, E.g. a package-admin is allowed to see the related debitor-business-object,
but not its banking data. but not its banking data.
#### tenant #### TENANT
The tenant-role is granted to everybody who needs to be able to select the business-object and (probably some) related business-objects. The tenant-role is granted to everybody who needs to be able to select the business-object and (probably some) related business-objects.
Usually all owners, admins and tenants of sub-objects get this role granted. Usually all owners, admins and tenants of sub-objects get this role granted.
Some business-objects only have very limited data directly in the main business-object and store more sensitive data in special sub-objects (e.g. 'customer-details') to which tenants of sub-objects of the main-object (e.g. package admins) do not get SELECT permission. Some business-objects only have very limited data directly in the main business-object and store more sensitive data in special sub-objects (e.g. 'customer-details') to which tenants of sub-objects of the main-object (e.g. package admins) do not get SELECT permission.
#### guest #### GUEST
(Deprecated)
#### REFERRER
Like the agent-role, the guest-role too is not used in the examples of this document, because it's for more complex cases. Like the agent-role, the guest-role too is not used in the examples of this document, because it's for more complex cases.
If the guest-role exists, the SELECT-permission is granted to it, instead of to the tenant-role. If the referrer-role exists, the SELECT-permission is granted to it, instead of to the tenant-role.
Other than the tenant-role, the guest-roles does never grant any roles of related objects. Other than the tenant-role, the referrer-roles does never grant any roles of related objects.
Also, if the guest-role exists, the tenant-role receives the SELECT-permission through the guest-role. Also, if the referrer-role exists, the tenant-role receives the SELECT-permission through the referrer-role.
### Referenced Business Objects and Role-Depreciation ### Referenced Business Objects and Role-Depreciation
@ -372,7 +376,7 @@ That user is also used for historicization and audit log, but which is a differe
If the session variable `hsadminng.assumedRoles` is set to a non-empty value, its content is interpreted as a list of semicolon-separated role names. If the session variable `hsadminng.assumedRoles` is set to a non-empty value, its content is interpreted as a list of semicolon-separated role names.
Example: Example:
SET LOCAL hsadminng.assumedRoles = 'customer#aab.admin;customer#aac.admin'; SET LOCAL hsadminng.assumedRoles = 'customer#aab:admin;customer#aac:admin';
In this case, not the current user but the assumed roles are used as a starting point for any further queries. In this case, not the current user but the assumed roles are used as a starting point for any further queries.
Roles which are not granted to the current user, directly or indirectly, cannot be assumed. Roles which are not granted to the current user, directly or indirectly, cannot be assumed.
@ -385,7 +389,7 @@ A full example is shown here:
BEGIN TRANSACTION; BEGIN TRANSACTION;
SET SESSION SESSION AUTHORIZATION restricted; SET SESSION SESSION AUTHORIZATION restricted;
SET LOCAL hsadminng.currentUser = 'mike@hostsharing.net'; SET LOCAL hsadminng.currentUser = 'mike@hostsharing.net';
SET LOCAL hsadminng.assumedRoles = 'customer#aab.admin;customer#aac.admin'; SET LOCAL hsadminng.assumedRoles = 'customer#aab:admin;customer#aac:admin';
SELECT c.prefix, p.name as "package", ema.localPart || '@' || dom.name as "email-address" SELECT c.prefix, p.name as "package", ema.localPart || '@' || dom.name as "email-address"
FROM emailaddress_rv ema FROM emailaddress_rv ema
@ -466,14 +470,14 @@ together {
permCustomerXyzSELECT--> boCustXyz permCustomerXyzSELECT--> boCustXyz
} }
entity "Role customer#xyz.tenant" as roleCustXyzTenant entity "Role customer#xyz:tenant" as roleCustXyzTenant
roleCustXyzTenant --> permCustomerXyzSELECT roleCustXyzTenant --> permCustomerXyzSELECT
entity "Role customer#xyz.admin" as roleCustXyzAdmin entity "Role customer#xyz:admin" as roleCustXyzAdmin
roleCustXyzAdmin --> roleCustXyzTenant roleCustXyzAdmin --> roleCustXyzTenant
roleCustXyzAdmin --> permCustomerXyzINSERT:package roleCustXyzAdmin --> permCustomerXyzINSERT:package
entity "Role customer#xyz.owner" as roleCustXyzOwner entity "Role customer#xyz:owner" as roleCustXyzOwner
roleCustXyzOwner ..> roleCustXyzAdmin roleCustXyzOwner ..> roleCustXyzAdmin
roleCustXyzOwner --> permCustomerXyzDELETE roleCustXyzOwner --> permCustomerXyzDELETE
@ -489,7 +493,7 @@ actorHostmaster --> roleAdmins
``` ```
As you can see, there something special: As you can see, there something special:
From the 'Role customer#xyz.owner' to the 'Role customer#xyz.admin' there is a dashed line, whereas all other lines are solid lines. From the 'Role customer#xyz:owner' to the 'Role customer#xyz:admin' there is a dashed line, whereas all other lines are solid lines.
Solid lines means, that one role is granted to another and automatically assumed in all queries to the restricted views. Solid lines means, that one role is granted to another and automatically assumed in all queries to the restricted views.
The dashed line means that one role is granted to another but not automatically assumed in queries to the restricted views. The dashed line means that one role is granted to another but not automatically assumed in queries to the restricted views.
@ -537,15 +541,15 @@ together {
} }
package { package {
entity "Role customer#xyz.tenant" as roleCustXyzTenant entity "Role customer#xyz:tenant" as roleCustXyzTenant
entity "Role customer#xyz.admin" as roleCustXyzAdmin entity "Role customer#xyz:admin" as roleCustXyzAdmin
entity "Role customer#xyz.owner" as roleCustXyzOwner entity "Role customer#xyz:owner" as roleCustXyzOwner
} }
package { package {
entity "Role package#xyz00.owner" as rolePacXyz00Owner entity "Role package#xyz00:owner" as rolePacXyz00Owner
entity "Role package#xyz00.admin" as rolePacXyz00Admin entity "Role package#xyz00:admin" as rolePacXyz00Admin
entity "Role package#xyz00.tenant" as rolePacXyz00Tenant entity "Role package#xyz00:tenant" as rolePacXyz00Tenant
} }
rolePacXyz00Tenant --> permPacXyz00SELECT rolePacXyz00Tenant --> permPacXyz00SELECT

View File

@ -3,10 +3,10 @@
-- -------------------------------------------------------- -- --------------------------------------------------------
select isGranted(findRoleId('administrators'), findRoleId('test_package#aaa00.owner')); select isGranted(findRoleId('administrators'), findRoleId('test_package#aaa00:OWNER'));
select isGranted(findRoleId('test_package#aaa00.owner'), findRoleId('administrators')); select isGranted(findRoleId('test_package#aaa00:OWNER'), findRoleId('administrators'));
-- call grantRoleToRole(findRoleId('test_package#aaa00.owner'), findRoleId('administrators')); -- call grantRoleToRole(findRoleId('test_package#aaa00:OWNER'), findRoleId('administrators'));
-- call grantRoleToRole(findRoleId('administrators'), findRoleId('test_package#aaa00.owner')); -- call grantRoleToRole(findRoleId('administrators'), findRoleId('test_package#aaa00:OWNER'));
select count(*) select count(*)
FROM queryAllPermissionsOfSubjectIdForObjectUuids(findRbacUser('superuser-fran@hostsharing.net'), FROM queryAllPermissionsOfSubjectIdForObjectUuids(findRbacUser('superuser-fran@hostsharing.net'),

View File

@ -83,7 +83,7 @@ select rr.uuid, rr.type from RbacGrants g
select uuid from queryAllPermissionsOfSubjectId(findRbacUser('alex@example.com')) select uuid from queryAllPermissionsOfSubjectId(findRbacUser('alex@example.com'))
where objectTable='test_customer'); where objectTable='test_customer');
call grantRoleToUser(findRoleId('test_customer#aaa.admin'), findRbacUser('aaaaouq@example.com')); call grantRoleToUser(findRoleId('test_customer#aaa:ADMIN'), findRbacUser('aaaaouq@example.com'));
select queryAllPermissionsOfSubjectId(findRbacUser('aaaaouq@example.com')); select queryAllPermissionsOfSubjectId(findRbacUser('aaaaouq@example.com'));

View File

@ -24,8 +24,11 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.REFERRER; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.REFERRER;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify; import static net.hostsharing.hsadminng.stringify.Stringify.stringify;

View File

@ -68,7 +68,7 @@ public class HsOfficePartnerDetailsEntity implements HasUuid, Stringifyable {
public static RbacView rbac() { public static RbacView rbac() {
return rbacViewFor("partnerDetails", HsOfficePartnerDetailsEntity.class) return rbacViewFor("partnerDetails", HsOfficePartnerDetailsEntity.class)
.withIdentityView(SQL.query(""" .withIdentityView(SQL.query("""
SELECT partnerDetails.uuid as uuid, partner_iv.idName || '-details' as idName SELECT partnerDetails.uuid as uuid, partner_iv.idName as idName
FROM hs_office_partner_details AS partnerDetails FROM hs_office_partner_details AS partnerDetails
JOIN hs_office_partner partner ON partner.detailsUuid = partnerDetails.uuid JOIN hs_office_partner partner ON partner.detailsUuid = partnerDetails.uuid
JOIN hs_office_partner_iv partner_iv ON partner_iv.uuid = partner.uuid JOIN hs_office_partner_iv partner_iv ON partner_iv.uuid = partner.uuid

View File

@ -120,7 +120,7 @@ public class InsertTriggerGenerator {
} }
}, },
() -> { () -> {
System.err.println("WARNING: no explicit INSERT grant for " + rbacDef.getRootEntityAlias().simpleName() + " => implicitly grant INSERT to global.admin"); System.err.println("WARNING: no explicit INSERT grant for " + rbacDef.getRootEntityAlias().simpleName() + " => implicitly grant INSERT to global:ADMIN");
generateInsertPermissionTriggerAllowOnlyGlobalAdmin(plPgSql); generateInsertPermissionTriggerAllowOnlyGlobalAdmin(plPgSql);
}); });
} }
@ -246,7 +246,7 @@ public class InsertTriggerGenerator {
} }
private static String toVar(final RbacView.RbacRoleDefinition roleDef) { private static String toVar(final RbacView.RbacRoleDefinition roleDef) {
return uncapitalize(roleDef.getEntityAlias().simpleName()) + capitalize(roleDef.getRole().roleName()); return uncapitalize(roleDef.getEntityAlias().simpleName()) + capitalize(roleDef.getRole().name());
} }

View File

@ -113,7 +113,7 @@ public class RbacView {
* <p>An identity view is a view which maps an objectUuid to an idName. * <p>An identity view is a view which maps an objectUuid to an idName.
* The idName should be a human-readable representation of the row, but as short as possible. * The idName should be a human-readable representation of the row, but as short as possible.
* The idName must only consist of letters (A-Z, a-z), digits (0-9), dash (-), dot (.) and unserscore '_'. * The idName must only consist of letters (A-Z, a-z), digits (0-9), dash (-), dot (.) and unserscore '_'.
* It's used to create the object-specific-role-names like test_customer#abc.admin - here 'abc' is the idName. * It's used to create the object-specific-role-names like test_customer#abc:ADMIN - here 'abc' is the idName.
* The idName not necessarily unique in a table, but it should be avoided. * The idName not necessarily unique in a table, but it should be avoided.
* </p> * </p>
* *
@ -882,15 +882,12 @@ public class RbacView {
TENANT, TENANT,
REFERRER, REFERRER,
@Deprecated
GUEST; GUEST;
@Override @Override
public String toString() { public String toString() {
return ":" + roleName(); return ":" + name();
}
String roleName() {
return name().toLowerCase();
} }
} }

View File

@ -48,7 +48,7 @@ public class RbacViewMermaidFlowchartGenerator {
flowchart.indented( () -> { flowchart.indented( () -> {
rbacDef.getEntityAliases().values().stream() rbacDef.getEntityAliases().values().stream()
.filter(e -> e.aliasName().startsWith(entity.aliasName() + ".")) .filter(e -> e.aliasName().startsWith(entity.aliasName() + ":"))
.forEach(this::renderEntitySubgraph); .forEach(this::renderEntitySubgraph);
wrapOutputInSubgraph(entity.aliasName() + ":roles", color, wrapOutputInSubgraph(entity.aliasName() + ":roles", color,

View File

@ -333,7 +333,7 @@ class RolesGrantsAndPermissionsGenerator {
return "globalAdmin()"; return "globalAdmin()";
} }
final String entityRefVar = entityRefVar(rootRefVar, roleDef.getEntityAlias()); final String entityRefVar = entityRefVar(rootRefVar, roleDef.getEntityAlias());
return roleDef.getEntityAlias().simpleName() + capitalize(roleDef.getRole().roleName()) return roleDef.getEntityAlias().simpleName() + capitalize(roleDef.getRole().name())
+ "(" + entityRefVar + ")"; + "(" + entityRefVar + ")";
} }
@ -359,7 +359,7 @@ class RolesGrantsAndPermissionsGenerator {
plPgSql.indented(() -> { plPgSql.indented(() -> {
plPgSql.writeLn("${simpleVarName)${roleSuffix}(NEW)," plPgSql.writeLn("${simpleVarName)${roleSuffix}(NEW),"
.replace("${simpleVarName)", simpleEntityVarName) .replace("${simpleVarName)", simpleEntityVarName)
.replace("${roleSuffix}", capitalize(role.roleName()))); .replace("${roleSuffix}", capitalize(role.name())));
generatePermissionsForRole(plPgSql, role); generatePermissionsForRole(plPgSql, role);
@ -562,7 +562,7 @@ class RolesGrantsAndPermissionsGenerator {
} }
private static String toRoleRef(final RbacView.RbacRoleDefinition roleDef) { private static String toRoleRef(final RbacView.RbacRoleDefinition roleDef) {
return uncapitalize(roleDef.getEntityAlias().simpleName()) + capitalize(roleDef.getRole().roleName()); return uncapitalize(roleDef.getEntityAlias().simpleName()) + capitalize(roleDef.getRole().name());
} }
private static String toTriggerReference( private static String toTriggerReference(

View File

@ -59,9 +59,9 @@ public class RbacGrantEntity {
} }
public String toDisplay() { public String toDisplay() {
return "{ grant role " + grantedRoleIdName + return "{ grant role:" + grantedRoleIdName +
" to user " + granteeUserName + " to user:" + granteeUserName +
" by role " + grantedByRoleIdName + " by role:" + grantedByRoleIdName +
(assumed ? " and assume" : "") + (assumed ? " and assume" : "") +
" }"; " }";
} }

View File

@ -71,14 +71,14 @@ public class RbacGrantsDiagramService {
private void traverseGrantsTo(final Set<RawRbacGrantEntity> graph, final UUID refUuid, final EnumSet<Include> includes) { private void traverseGrantsTo(final Set<RawRbacGrantEntity> graph, final UUID refUuid, final EnumSet<Include> includes) {
final var grants = rawGrantRepo.findByAscendingUuid(refUuid); final var grants = rawGrantRepo.findByAscendingUuid(refUuid);
grants.forEach(g -> { grants.forEach(g -> {
if (!includes.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm ")) { if (!includes.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm:")) {
return; return;
} }
if ( !g.getDescendantIdName().startsWith("role global")) { if ( !g.getDescendantIdName().startsWith("role:global")) {
if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(" test_")) { if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(":test_")) {
return; return;
} }
if (!includes.contains(NON_TEST_ENTITIES) && !g.getDescendantIdName().contains(" test_")) { if (!includes.contains(NON_TEST_ENTITIES) && !g.getDescendantIdName().contains(":test_")) {
return; return;
} }
} }
@ -102,7 +102,7 @@ public class RbacGrantsDiagramService {
private void traverseGrantsFrom(final Set<RawRbacGrantEntity> graph, final UUID refUuid, final EnumSet<Include> option) { private void traverseGrantsFrom(final Set<RawRbacGrantEntity> graph, final UUID refUuid, final EnumSet<Include> option) {
final var grants = rawGrantRepo.findByDescendantUuid(refUuid); final var grants = rawGrantRepo.findByDescendantUuid(refUuid);
grants.forEach(g -> { grants.forEach(g -> {
if (!option.contains(USERS) && g.getAscendantIdName().startsWith("user ")) { if (!option.contains(USERS) && g.getAscendantIdName().startsWith("user:")) {
return; return;
} }
graph.add(g); graph.add(g);
@ -171,7 +171,7 @@ public class RbacGrantsDiagramService {
} }
if (refType.equals("role")) { if (refType.equals("role")) {
final var withoutRolePrefix = node.idName().substring("role:".length()); final var withoutRolePrefix = node.idName().substring("role:".length());
return withoutRolePrefix.substring(0, withoutRolePrefix.lastIndexOf('.')); return withoutRolePrefix.substring(0, withoutRolePrefix.lastIndexOf(':'));
} }
throw new IllegalArgumentException("unknown refType '" + refType + "' in '" + node.idName() + "'"); throw new IllegalArgumentException("unknown refType '" + refType + "' in '" + node.idName() + "'");
} }
@ -188,23 +188,23 @@ public class RbacGrantsDiagramService {
return "(" + displayName + "\nref:" + uuid + ")"; return "(" + displayName + "\nref:" + uuid + ")";
} }
if (refType.equals("role")) { if (refType.equals("role")) {
final var roleType = idName.substring(idName.lastIndexOf('.') + 1); final var roleType = idName.substring(idName.lastIndexOf(':') + 1);
return "[" + roleType + "\nref:" + uuid + "]"; return "[" + roleType + "\nref:" + uuid + "]";
} }
if (refType.equals("perm")) { if (refType.equals("perm")) {
final var roleType = idName.split(" ")[1]; final var roleType = idName.split(":")[1];
return "{{" + roleType + "\nref:" + uuid + "}}"; return "{{" + roleType + "\nref:" + uuid + "}}";
} }
return ""; return "";
} }
private static String refType(final String idName) { private static String refType(final String idName) {
return idName.split(" ", 2)[0]; return idName.split(":", 2)[0];
} }
@NotNull @NotNull
private static String cleanId(final String idName) { private static String cleanId(final String idName) {
return idName.replace(" ", ":").replaceAll("@.*", "") return idName.replaceAll("@.*", "")
.replace("[", "").replace("]", "").replace("(", "").replace(")", "").replace(",", ""); .replace("[", "").replace("]", "").replace("(", "").replace(")", "").replace(",", "");
} }

View File

@ -31,7 +31,7 @@ public class RbacRoleController implements RbacRolesApi {
context.define(currentUser, assumedRoles); context.define(currentUser, assumedRoles);
final List<RbacRoleEntity> result = rbacRoleRepository.findAll(); final List<RbacRoleRvEntity> result = rbacRoleRepository.findAll();
return ResponseEntity.ok(mapper.mapList(result, RbacRoleResource.class)); return ResponseEntity.ok(mapper.mapList(result, RbacRoleResource.class));
} }

View File

@ -5,7 +5,7 @@ import org.springframework.data.repository.Repository;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
public interface RbacRoleRepository extends Repository<RbacRoleEntity, UUID> { public interface RbacRoleRepository extends Repository<RbacRoleRvEntity, UUID> {
/** /**
* @return the number of persistent RbacRoleEntity instances, mostly for testing purposes. * @return the number of persistent RbacRoleEntity instances, mostly for testing purposes.
@ -15,7 +15,7 @@ public interface RbacRoleRepository extends Repository<RbacRoleEntity, UUID> {
/** /**
* @return all persistent RbacRoleEntity instances, assigned to the current subject (user or assumed roles) * @return all persistent RbacRoleEntity instances, assigned to the current subject (user or assumed roles)
*/ */
List<RbacRoleEntity> findAll(); List<RbacRoleRvEntity> findAll();
RbacRoleEntity findByRoleName(String roleName); RbacRoleRvEntity findByRoleName(String roleName);
} }

View File

@ -15,7 +15,7 @@ import java.util.UUID;
@Immutable @Immutable
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class RbacRoleEntity { public class RbacRoleRvEntity {
@Id @Id
@GeneratedValue @GeneratedValue
@ -34,6 +34,6 @@ public class RbacRoleEntity {
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
private RbacRoleType roleType; private RbacRoleType roleType;
@Formula("objectTable||'#'||objectIdName||'.'||roleType") @Formula("objectTable||'#'||objectIdName||':'||roleType")
private String roleName; private String roleName;
} }

View File

@ -1,5 +1,5 @@
package net.hostsharing.hsadminng.rbac.rbacrole; package net.hostsharing.hsadminng.rbac.rbacrole;
public enum RbacRoleType { public enum RbacRoleType {
owner, admin, agent, tenant, guest, referrer OWNER, ADMIN, AGENT, TENANT, GUEST, REFERRER
} }

View File

@ -19,9 +19,11 @@ components:
roleType: roleType:
type: string type: string
enum: enum:
- owner - OWNER
- admin - ADMIN
- tenant - AGENT
- referrer - TENANT
- GUEST
- REFERRER
roleName: roleName:
type: string type: string

View File

@ -149,8 +149,7 @@ create or replace function cleanIdentifier(rawIdentifier varchar)
declare declare
cleanIdentifier varchar; cleanIdentifier varchar;
begin begin
-- TODO: remove the ':' from the list of allowed characters as soon as it's not used anymore cleanIdentifier := regexp_replace(rawIdentifier, '[^A-Za-z0-9\-._]+', '', 'g');
cleanIdentifier := regexp_replace(rawIdentifier, '[^A-Za-z0-9\-._:]+', '', 'g');
return cleanIdentifier; return cleanIdentifier;
end; $$; end; $$;

View File

@ -164,7 +164,7 @@ end; $$;
*/ */
create type RbacRoleType as enum ('owner', 'admin', 'agent', 'tenant', 'guest', 'referrer'); create type RbacRoleType as enum ('OWNER', 'ADMIN', 'AGENT', 'TENANT', 'GUEST', 'REFERRER');
create table RbacRole create table RbacRole
( (
@ -249,7 +249,7 @@ declare
roleUuid uuid; roleUuid uuid;
begin begin
-- TODO.refact: extract function toRbacRoleDescriptor(roleIdName varchar) + find other occurrences -- TODO.refact: extract function toRbacRoleDescriptor(roleIdName varchar) + find other occurrences
roleParts = overlay(roleIdName placing '#' from length(roleIdName) + 1 - strpos(reverse(roleIdName), '.')); roleParts = overlay(roleIdName placing '#' from length(roleIdName) + 1 - strpos(reverse(roleIdName), ':'));
objectTableFromRoleIdName = split_part(roleParts, '#', 1); objectTableFromRoleIdName = split_part(roleParts, '#', 1);
objectNameFromRoleIdName = split_part(roleParts, '#', 2); objectNameFromRoleIdName = split_part(roleParts, '#', 2);
roleTypeFromRoleIdName = split_part(roleParts, '#', 3); roleTypeFromRoleIdName = split_part(roleParts, '#', 3);

View File

@ -50,7 +50,7 @@ begin
foreach roleName in array string_to_array(assumedRoles, ';') foreach roleName in array string_to_array(assumedRoles, ';')
loop loop
roleNameParts = overlay(roleName placing '#' from length(roleName) + 1 - strpos(reverse(roleName), '.')); roleNameParts = overlay(roleName placing '#' from length(roleName) + 1 - strpos(reverse(roleName), ':'));
objectTableToAssume = split_part(roleNameParts, '#', 1); objectTableToAssume = split_part(roleNameParts, '#', 1);
objectNameToAssume = split_part(roleNameParts, '#', 2); objectNameToAssume = split_part(roleNameParts, '#', 2);
roleTypeToAssume = split_part(roleNameParts, '#', 3); roleTypeToAssume = split_part(roleNameParts, '#', 3);

View File

@ -9,7 +9,7 @@
*/ */
drop view if exists rbacrole_ev; drop view if exists rbacrole_ev;
create or replace view rbacrole_ev as create or replace view rbacrole_ev as
select (objectTable || '#' || objectIdName || '.' || roleType) as roleIdName, * select (objectTable || '#' || objectIdName || ':' || roleType) as roleIdName, *
-- @formatter:off -- @formatter:off
from ( from (
select r.*, select r.*,
@ -40,7 +40,7 @@ select *
where isGranted(currentSubjectsUuids(), r.uuid) where isGranted(currentSubjectsUuids(), r.uuid)
) as unordered ) as unordered
-- @formatter:on -- @formatter:on
order by objectTable || '#' || objectIdName || '.' || roleType; order by objectTable || '#' || objectIdName || ':' || roleType;
grant all privileges on rbacrole_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}; grant all privileges on rbacrole_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
--// --//
@ -57,7 +57,7 @@ create or replace view rbacgrants_ev as
-- @formatter:off -- @formatter:off
select x.grantUuid as uuid, select x.grantUuid as uuid,
x.grantedByTriggerOf as grantedByTriggerOf, x.grantedByTriggerOf as grantedByTriggerOf,
go.objectTable || '#' || findIdNameByObjectUuid(go.objectTable, go.uuid) || '.' || r.roletype as grantedByRoleIdName, go.objectTable || '#' || findIdNameByObjectUuid(go.objectTable, go.uuid) || ':' || r.roletype as grantedByRoleIdName,
x.ascendingIdName as ascendantIdName, x.ascendingIdName as ascendantIdName,
x.descendingIdName as descendantIdName, x.descendingIdName as descendantIdName,
x.grantedByRoleUuid, x.grantedByRoleUuid,
@ -71,16 +71,16 @@ create or replace view rbacgrants_ev as
g.grantedbyroleuuid, g.ascendantuuid, g.descendantuuid, g.assumed, g.grantedbyroleuuid, g.ascendantuuid, g.descendantuuid, g.assumed,
coalesce( coalesce(
'user ' || au.name, 'user:' || au.name,
'role ' || aro.objectTable || '#' || findIdNameByObjectUuid(aro.objectTable, aro.uuid) || '.' || ar.roletype 'role:' || aro.objectTable || '#' || findIdNameByObjectUuid(aro.objectTable, aro.uuid) || ':' || ar.roletype
) as ascendingIdName, ) as ascendingIdName,
aro.objectTable, aro.uuid, aro.objectTable, aro.uuid,
( case ( case
when dro is not null when dro is not null
then ('role ' || dro.objectTable || '#' || findIdNameByObjectUuid(dro.objectTable, dro.uuid) || '.' || dr.roletype) then ('role:' || dro.objectTable || '#' || findIdNameByObjectUuid(dro.objectTable, dro.uuid) || ':' || dr.roletype)
when dp.op = 'INSERT' when dp.op = 'INSERT'
then 'perm ' || dp.op || ' into ' || dp.opTableName || ' with ' || dpo.objecttable || '#' || findIdNameByObjectUuid(dpo.objectTable, dpo.uuid) then 'perm:' || dpo.objecttable || '#' || findIdNameByObjectUuid(dpo.objectTable, dpo.uuid) || ':' || dp.op || '>' || dp.opTableName
else 'perm ' || dp.op || ' on ' || dpo.objecttable || '#' || findIdNameByObjectUuid(dpo.objectTable, dpo.uuid) else 'perm:' || dpo.objecttable || '#' || findIdNameByObjectUuid(dpo.objectTable, dpo.uuid) || ':' || dp.op
end end
) as descendingIdName, ) as descendingIdName,
dro.objectTable, dro.uuid, dro.objectTable, dro.uuid,
@ -115,8 +115,8 @@ create or replace view rbacgrants_ev as
drop view if exists rbacgrants_rv; drop view if exists rbacgrants_rv;
create or replace view rbacgrants_rv as create or replace view rbacgrants_rv as
-- @formatter:off -- @formatter:off
select o.objectTable || '#' || findIdNameByObjectUuid(o.objectTable, o.uuid) || '.' || r.roletype as grantedByRoleIdName, select o.objectTable || '#' || findIdNameByObjectUuid(o.objectTable, o.uuid) || ':' || r.roletype as grantedByRoleIdName,
g.objectTable || '#' || g.objectIdName || '.' || g.roletype as grantedRoleIdName, g.userName, g.assumed, g.objectTable || '#' || g.objectIdName || ':' || g.roletype as grantedRoleIdName, g.userName, g.assumed,
g.grantedByRoleUuid, g.descendantUuid as grantedRoleUuid, g.ascendantUuid as userUuid, g.grantedByRoleUuid, g.descendantUuid as grantedRoleUuid, g.ascendantUuid as userUuid,
g.objectTable, g.objectUuid, g.objectIdName, g.roleType as grantedRoleType g.objectTable, g.objectUuid, g.objectIdName, g.roleType as grantedRoleType
from ( from (
@ -327,7 +327,7 @@ execute function deleteRbacUser();
drop view if exists RbacOwnGrantedPermissions_rv; drop view if exists RbacOwnGrantedPermissions_rv;
create or replace view RbacOwnGrantedPermissions_rv as create or replace view RbacOwnGrantedPermissions_rv as
select r.uuid as roleuuid, p.uuid as permissionUuid, select r.uuid as roleuuid, p.uuid as permissionUuid,
(r.objecttable || '#' || r.objectidname || '.' || r.roletype) as roleName, p.op, (r.objecttable || ':' || r.objectidname || ':' || r.roletype) as roleName, p.op,
o.objecttable, r.objectidname, o.uuid as objectuuid o.objecttable, r.objectidname, o.uuid as objectuuid
from rbacrole_rv r from rbacrole_rv r
join rbacgrants g on g.ascendantuuid = r.uuid join rbacgrants g on g.ascendantuuid = r.uuid
@ -359,7 +359,7 @@ begin
return query select return query select
xp.roleUuid, xp.roleUuid,
(xp.roleObjectTable || '#' || xp.roleObjectIdName || '.' || xp.roleType) as roleName, (xp.roleObjectTable || '#' || xp.roleObjectIdName || ':' || xp.roleType) as roleName,
xp.permissionUuid, xp.op, xp.opTableName, xp.permissionUuid, xp.op, xp.opTableName,
xp.permissionObjectTable, xp.permissionObjectIdName, xp.permissionObjectUuid xp.permissionObjectTable, xp.permissionObjectIdName, xp.permissionObjectUuid
from (select from (select

View File

@ -46,7 +46,7 @@ begin
language plpgsql language plpgsql
strict as $f$ strict as $f$
begin begin
return roleDescriptor('%2$s', entity.uuid, 'owner', assumed); return roleDescriptor('%2$s', entity.uuid, 'OWNER', assumed);
end; $f$; end; $f$;
create or replace function %1$sAdmin(entity %2$s, assumed boolean = true) create or replace function %1$sAdmin(entity %2$s, assumed boolean = true)
@ -54,7 +54,7 @@ begin
language plpgsql language plpgsql
strict as $f$ strict as $f$
begin begin
return roleDescriptor('%2$s', entity.uuid, 'admin', assumed); return roleDescriptor('%2$s', entity.uuid, 'ADMIN', assumed);
end; $f$; end; $f$;
create or replace function %1$sAgent(entity %2$s, assumed boolean = true) create or replace function %1$sAgent(entity %2$s, assumed boolean = true)
@ -62,7 +62,7 @@ begin
language plpgsql language plpgsql
strict as $f$ strict as $f$
begin begin
return roleDescriptor('%2$s', entity.uuid, 'agent', assumed); return roleDescriptor('%2$s', entity.uuid, 'AGENT', assumed);
end; $f$; end; $f$;
create or replace function %1$sTenant(entity %2$s, assumed boolean = true) create or replace function %1$sTenant(entity %2$s, assumed boolean = true)
@ -70,7 +70,7 @@ begin
language plpgsql language plpgsql
strict as $f$ strict as $f$
begin begin
return roleDescriptor('%2$s', entity.uuid, 'tenant', assumed); return roleDescriptor('%2$s', entity.uuid, 'TENANT', assumed);
end; $f$; end; $f$;
-- TODO: remove guest role -- TODO: remove guest role
@ -79,7 +79,7 @@ begin
language plpgsql language plpgsql
strict as $f$ strict as $f$
begin begin
return roleDescriptor('%2$s', entity.uuid, 'guest', assumed); return roleDescriptor('%2$s', entity.uuid, 'GUEST', assumed);
end; $f$; end; $f$;
create or replace function %1$sReferrer(entity %2$s) create or replace function %1$sReferrer(entity %2$s)
@ -87,7 +87,7 @@ begin
language plpgsql language plpgsql
strict as $f$ strict as $f$
begin begin
return roleDescriptor('%2$s', entity.uuid, 'referrer'); return roleDescriptor('%2$s', entity.uuid, 'REFERRER');
end; $f$; end; $f$;
$sql$, prefix, targetTable); $sql$, prefix, targetTable);

View File

@ -114,11 +114,11 @@ create or replace function globalAdmin(assumed boolean = true)
returns null on null input returns null on null input
stable -- leakproof stable -- leakproof
language sql as $$ language sql as $$
select 'global', (select uuid from RbacObject where objectTable = 'global'), 'admin'::RbacRoleType, assumed; select 'global', (select uuid from RbacObject where objectTable = 'global'), 'ADMIN'::RbacRoleType, assumed;
$$; $$;
begin transaction; begin transaction;
call defineContext('creating global admin role', null, null, null); call defineContext('creating role:global#global:ADMIN', null, null, null);
select createRole(globalAdmin()); select createRole(globalAdmin());
commit; commit;
--// --//
@ -135,11 +135,11 @@ create or replace function globalGuest(assumed boolean = true)
returns null on null input returns null on null input
stable -- leakproof stable -- leakproof
language sql as $$ language sql as $$
select 'global', (select uuid from RbacObject where objectTable = 'global'), 'guest'::RbacRoleType, assumed; select 'global', (select uuid from RbacObject where objectTable = 'global'), 'GUEST'::RbacRoleType, assumed;
$$; $$;
begin transaction; begin transaction;
call defineContext('creating global guest role', null, null, null); call defineContext('creating role:global#loba:guest', null, null, null);
select createRole(globalGuest()); select createRole(globalGuest());
commit; commit;
--// --//

View File

@ -13,9 +13,9 @@ subgraph customer["`**customer**`"]
subgraph customer:roles[ ] subgraph customer:roles[ ]
style customer:roles fill:#dd4901,stroke:white style customer:roles fill:#dd4901,stroke:white
role:customer:owner[[customer:owner]] role:customer:OWNER[[customer:OWNER]]
role:customer:admin[[customer:admin]] role:customer:ADMIN[[customer:ADMIN]]
role:customer:tenant[[customer:tenant]] role:customer:TENANT[[customer:TENANT]]
end end
subgraph customer:permissions[ ] subgraph customer:permissions[ ]
@ -29,17 +29,17 @@ subgraph customer["`**customer**`"]
end end
%% granting roles to users %% granting roles to users
user:creator ==>|XX| role:customer:owner user:creator ==>|XX| role:customer:OWNER
%% granting roles to roles %% granting roles to roles
role:global:admin ==>|XX| role:customer:owner role:global:ADMIN ==>|XX| role:customer:OWNER
role:customer:owner ==> role:customer:admin role:customer:OWNER ==> role:customer:ADMIN
role:customer:admin ==> role:customer:tenant role:customer:ADMIN ==> role:customer:TENANT
%% granting permissions to roles %% granting permissions to roles
role:global:admin ==> perm:customer:INSERT role:global:ADMIN ==> perm:customer:INSERT
role:customer:owner ==> perm:customer:DELETE role:customer:OWNER ==> perm:customer:DELETE
role:customer:admin ==> perm:customer:UPDATE role:customer:ADMIN ==> perm:customer:UPDATE
role:customer:tenant ==> perm:customer:SELECT role:customer:TENANT ==> perm:customer:SELECT
``` ```

View File

@ -35,22 +35,22 @@ begin
call enterTriggerForObjectUuid(NEW.uuid); call enterTriggerForObjectUuid(NEW.uuid);
perform createRoleWithGrants( perform createRoleWithGrants(
testCustomerOwner(NEW), testCustomerOWNER(NEW),
permissions => array['DELETE'], permissions => array['DELETE'],
incomingSuperRoles => array[globalAdmin(unassumed())], incomingSuperRoles => array[globalADMIN(unassumed())],
userUuids => array[currentUserUuid()] userUuids => array[currentUserUuid()]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
testCustomerAdmin(NEW), testCustomerADMIN(NEW),
permissions => array['UPDATE'], permissions => array['UPDATE'],
incomingSuperRoles => array[testCustomerOwner(NEW)] incomingSuperRoles => array[testCustomerOWNER(NEW)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
testCustomerTenant(NEW), testCustomerTENANT(NEW),
permissions => array['SELECT'], permissions => array['SELECT'],
incomingSuperRoles => array[testCustomerAdmin(NEW)] incomingSuperRoles => array[testCustomerADMIN(NEW)]
); );
call leaveTriggerForObjectUuid(NEW.uuid); call leaveTriggerForObjectUuid(NEW.uuid);
@ -93,7 +93,7 @@ do language plpgsql $$
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'test_customer'), createPermission(row.uuid, 'INSERT', 'test_customer'),
globalAdmin()); globalADMIN());
END LOOP; END LOOP;
END; END;
$$; $$;
@ -108,7 +108,7 @@ create or replace function test_customer_global_insert_tf()
begin begin
call grantPermissionToRole( call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'test_customer'), createPermission(NEW.uuid, 'INSERT', 'test_customer'),
globalAdmin()); globalADMIN());
return NEW; return NEW;
end; $$; end; $$;

View File

@ -32,7 +32,7 @@ declare
newCust test_customer; newCust test_customer;
begin begin
currentTask = 'creating RBAC test customer #' || custReference || '/' || custPrefix; currentTask = 'creating RBAC test customer #' || custReference || '/' || custPrefix;
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin'); call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
execute format('set local hsadminng.currentTask to %L', currentTask); execute format('set local hsadminng.currentTask to %L', currentTask);
custRowId = uuid_generate_v4(); custRowId = uuid_generate_v4();

View File

@ -13,9 +13,9 @@ subgraph package["`**package**`"]
subgraph package:roles[ ] subgraph package:roles[ ]
style package:roles fill:#dd4901,stroke:white style package:roles fill:#dd4901,stroke:white
role:package:owner[[package:owner]] role:package:OWNER[[package:OWNER]]
role:package:admin[[package:admin]] role:package:ADMIN[[package:ADMIN]]
role:package:tenant[[package:tenant]] role:package:TENANT[[package:TENANT]]
end end
subgraph package:permissions[ ] subgraph package:permissions[ ]
@ -35,25 +35,25 @@ subgraph customer["`**customer**`"]
subgraph customer:roles[ ] subgraph customer:roles[ ]
style customer:roles fill:#99bcdb,stroke:white style customer:roles fill:#99bcdb,stroke:white
role:customer:owner[[customer:owner]] role:customer:OWNER[[customer:OWNER]]
role:customer:admin[[customer:admin]] role:customer:ADMIN[[customer:ADMIN]]
role:customer:tenant[[customer:tenant]] role:customer:TENANT[[customer:TENANT]]
end end
end end
%% granting roles to roles %% granting roles to roles
role:global:admin -.->|XX| role:customer:owner role:global:ADMIN -.->|XX| role:customer:OWNER
role:customer:owner -.-> role:customer:admin role:customer:OWNER -.-> role:customer:ADMIN
role:customer:admin -.-> role:customer:tenant role:customer:ADMIN -.-> role:customer:TENANT
role:customer:admin ==> role:package:owner role:customer:ADMIN ==> role:package:OWNER
role:package:owner ==> role:package:admin role:package:OWNER ==> role:package:ADMIN
role:package:admin ==> role:package:tenant role:package:ADMIN ==> role:package:TENANT
role:package:tenant ==> role:customer:tenant role:package:TENANT ==> role:customer:TENANT
%% granting permissions to roles %% granting permissions to roles
role:customer:admin ==> perm:package:INSERT role:customer:ADMIN ==> perm:package:INSERT
role:package:owner ==> perm:package:DELETE role:package:OWNER ==> perm:package:DELETE
role:package:owner ==> perm:package:UPDATE role:package:OWNER ==> perm:package:UPDATE
role:package:tenant ==> perm:package:SELECT role:package:TENANT ==> perm:package:SELECT
``` ```

View File

@ -40,21 +40,21 @@ begin
perform createRoleWithGrants( perform createRoleWithGrants(
testPackageOwner(NEW), testPackageOWNER(NEW),
permissions => array['DELETE', 'UPDATE'], permissions => array['DELETE', 'UPDATE'],
incomingSuperRoles => array[testCustomerAdmin(newCustomer)] incomingSuperRoles => array[testCustomerADMIN(newCustomer)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
testPackageAdmin(NEW), testPackageADMIN(NEW),
incomingSuperRoles => array[testPackageOwner(NEW)] incomingSuperRoles => array[testPackageOWNER(NEW)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
testPackageTenant(NEW), testPackageTENANT(NEW),
permissions => array['SELECT'], permissions => array['SELECT'],
incomingSuperRoles => array[testPackageAdmin(NEW)], incomingSuperRoles => array[testPackageADMIN(NEW)],
outgoingSubRoles => array[testCustomerTenant(newCustomer)] outgoingSubRoles => array[testCustomerTENANT(newCustomer)]
); );
call leaveTriggerForObjectUuid(NEW.uuid); call leaveTriggerForObjectUuid(NEW.uuid);
@ -110,11 +110,11 @@ begin
if NEW.customerUuid <> OLD.customerUuid then if NEW.customerUuid <> OLD.customerUuid then
call revokeRoleFromRole(testPackageOwner(OLD), testCustomerAdmin(oldCustomer)); call revokeRoleFromRole(testPackageOWNER(OLD), testCustomerADMIN(oldCustomer));
call grantRoleToRole(testPackageOwner(NEW), testCustomerAdmin(newCustomer)); call grantRoleToRole(testPackageOWNER(NEW), testCustomerADMIN(newCustomer));
call revokeRoleFromRole(testCustomerTenant(oldCustomer), testPackageTenant(OLD)); call revokeRoleFromRole(testCustomerTENANT(oldCustomer), testPackageTENANT(OLD));
call grantRoleToRole(testCustomerTenant(newCustomer), testPackageTenant(NEW)); call grantRoleToRole(testCustomerTENANT(newCustomer), testPackageTENANT(NEW));
end if; end if;
@ -158,7 +158,7 @@ do language plpgsql $$
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'test_package'), createPermission(row.uuid, 'INSERT', 'test_package'),
testCustomerAdmin(row)); testCustomerADMIN(row));
END LOOP; END LOOP;
END; END;
$$; $$;
@ -173,7 +173,7 @@ create or replace function test_package_test_customer_insert_tf()
begin begin
call grantPermissionToRole( call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'test_package'), createPermission(NEW.uuid, 'INSERT', 'test_package'),
testCustomerAdmin(NEW)); testCustomerADMIN(NEW));
return NEW; return NEW;
end; $$; end; $$;

View File

@ -25,7 +25,7 @@ begin
cust.uuid; cust.uuid;
custAdminUser = 'customer-admin@' || cust.prefix || '.example.com'; custAdminUser = 'customer-admin@' || cust.prefix || '.example.com';
custAdminRole = 'test_customer#' || cust.prefix || '.admin'; custAdminRole = 'test_customer#' || cust.prefix || ':ADMIN';
call defineContext(currentTask, null, 'superuser-fran@hostsharing.net', custAdminRole); call defineContext(currentTask, null, 'superuser-fran@hostsharing.net', custAdminRole);
raise notice 'task: % by % as %', currentTask, custAdminUser, custAdminRole; raise notice 'task: % by % as %', currentTask, custAdminUser, custAdminRole;

View File

@ -13,9 +13,9 @@ subgraph package.customer["`**package.customer**`"]
subgraph package.customer:roles[ ] subgraph package.customer:roles[ ]
style package.customer:roles fill:#99bcdb,stroke:white style package.customer:roles fill:#99bcdb,stroke:white
role:package.customer:owner[[package.customer:owner]] role:package.customer:OWNER[[package.customer:OWNER]]
role:package.customer:admin[[package.customer:admin]] role:package.customer:ADMIN[[package.customer:ADMIN]]
role:package.customer:tenant[[package.customer:tenant]] role:package.customer:TENANT[[package.customer:TENANT]]
end end
end end
@ -23,25 +23,12 @@ subgraph package["`**package**`"]
direction TB direction TB
style package fill:#99bcdb,stroke:#274d6e,stroke-width:8px style package fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph package.customer["`**package.customer**`"]
direction TB
style package.customer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph package.customer:roles[ ]
style package.customer:roles fill:#99bcdb,stroke:white
role:package.customer:owner[[package.customer:owner]]
role:package.customer:admin[[package.customer:admin]]
role:package.customer:tenant[[package.customer:tenant]]
end
end
subgraph package:roles[ ] subgraph package:roles[ ]
style package:roles fill:#99bcdb,stroke:white style package:roles fill:#99bcdb,stroke:white
role:package:owner[[package:owner]] role:package:OWNER[[package:OWNER]]
role:package:admin[[package:admin]] role:package:ADMIN[[package:ADMIN]]
role:package:tenant[[package:tenant]] role:package:TENANT[[package:TENANT]]
end end
end end
@ -52,8 +39,8 @@ subgraph domain["`**domain**`"]
subgraph domain:roles[ ] subgraph domain:roles[ ]
style domain:roles fill:#dd4901,stroke:white style domain:roles fill:#dd4901,stroke:white
role:domain:owner[[domain:owner]] role:domain:OWNER[[domain:OWNER]]
role:domain:admin[[domain:admin]] role:domain:ADMIN[[domain:ADMIN]]
end end
subgraph domain:permissions[ ] subgraph domain:permissions[ ]
@ -67,22 +54,22 @@ subgraph domain["`**domain**`"]
end end
%% granting roles to roles %% granting roles to roles
role:global:admin -.->|XX| role:package.customer:owner role:global:ADMIN -.->|XX| role:package.customer:OWNER
role:package.customer:owner -.-> role:package.customer:admin role:package.customer:OWNER -.-> role:package.customer:ADMIN
role:package.customer:admin -.-> role:package.customer:tenant role:package.customer:ADMIN -.-> role:package.customer:TENANT
role:package.customer:admin -.-> role:package:owner role:package.customer:ADMIN -.-> role:package:OWNER
role:package:owner -.-> role:package:admin role:package:OWNER -.-> role:package:ADMIN
role:package:admin -.-> role:package:tenant role:package:ADMIN -.-> role:package:TENANT
role:package:tenant -.-> role:package.customer:tenant role:package:TENANT -.-> role:package.customer:TENANT
role:package:admin ==> role:domain:owner role:package:ADMIN ==> role:domain:OWNER
role:domain:owner ==> role:package:tenant role:domain:OWNER ==> role:package:TENANT
role:domain:owner ==> role:domain:admin role:domain:OWNER ==> role:domain:ADMIN
role:domain:admin ==> role:package:tenant role:domain:ADMIN ==> role:package:TENANT
%% granting permissions to roles %% granting permissions to roles
role:package:admin ==> perm:domain:INSERT role:package:ADMIN ==> perm:domain:INSERT
role:domain:owner ==> perm:domain:DELETE role:domain:OWNER ==> perm:domain:DELETE
role:domain:owner ==> perm:domain:UPDATE role:domain:OWNER ==> perm:domain:UPDATE
role:domain:admin ==> perm:domain:SELECT role:domain:ADMIN ==> perm:domain:SELECT
``` ```

View File

@ -40,17 +40,17 @@ begin
perform createRoleWithGrants( perform createRoleWithGrants(
testDomainOwner(NEW), testDomainOWNER(NEW),
permissions => array['DELETE', 'UPDATE'], permissions => array['DELETE', 'UPDATE'],
incomingSuperRoles => array[testPackageAdmin(newPackage)], incomingSuperRoles => array[testPackageADMIN(newPackage)],
outgoingSubRoles => array[testPackageTenant(newPackage)] outgoingSubRoles => array[testPackageTENANT(newPackage)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
testDomainAdmin(NEW), testDomainADMIN(NEW),
permissions => array['SELECT'], permissions => array['SELECT'],
incomingSuperRoles => array[testDomainOwner(NEW)], incomingSuperRoles => array[testDomainOWNER(NEW)],
outgoingSubRoles => array[testPackageTenant(newPackage)] outgoingSubRoles => array[testPackageTENANT(newPackage)]
); );
call leaveTriggerForObjectUuid(NEW.uuid); call leaveTriggerForObjectUuid(NEW.uuid);
@ -106,14 +106,14 @@ begin
if NEW.packageUuid <> OLD.packageUuid then if NEW.packageUuid <> OLD.packageUuid then
call revokeRoleFromRole(testDomainOwner(OLD), testPackageAdmin(oldPackage)); call revokeRoleFromRole(testDomainOWNER(OLD), testPackageADMIN(oldPackage));
call grantRoleToRole(testDomainOwner(NEW), testPackageAdmin(newPackage)); call grantRoleToRole(testDomainOWNER(NEW), testPackageADMIN(newPackage));
call revokeRoleFromRole(testPackageTenant(oldPackage), testDomainOwner(OLD)); call revokeRoleFromRole(testPackageTENANT(oldPackage), testDomainOWNER(OLD));
call grantRoleToRole(testPackageTenant(newPackage), testDomainOwner(NEW)); call grantRoleToRole(testPackageTENANT(newPackage), testDomainOWNER(NEW));
call revokeRoleFromRole(testPackageTenant(oldPackage), testDomainAdmin(OLD)); call revokeRoleFromRole(testPackageTENANT(oldPackage), testDomainADMIN(OLD));
call grantRoleToRole(testPackageTenant(newPackage), testDomainAdmin(NEW)); call grantRoleToRole(testPackageTENANT(newPackage), testDomainADMIN(NEW));
end if; end if;
@ -157,7 +157,7 @@ do language plpgsql $$
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'test_domain'), createPermission(row.uuid, 'INSERT', 'test_domain'),
testPackageAdmin(row)); testPackageADMIN(row));
END LOOP; END LOOP;
END; END;
$$; $$;
@ -172,7 +172,7 @@ create or replace function test_domain_test_package_insert_tf()
begin begin
call grantPermissionToRole( call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'test_domain'), createPermission(NEW.uuid, 'INSERT', 'test_domain'),
testPackageAdmin(NEW)); testPackageADMIN(NEW));
return NEW; return NEW;
end; $$; end; $$;

View File

@ -13,9 +13,9 @@ subgraph contact["`**contact**`"]
subgraph contact:roles[ ] subgraph contact:roles[ ]
style contact:roles fill:#dd4901,stroke:white style contact:roles fill:#dd4901,stroke:white
role:contact:owner[[contact:owner]] role:contact:OWNER[[contact:OWNER]]
role:contact:admin[[contact:admin]] role:contact:ADMIN[[contact:ADMIN]]
role:contact:referrer[[contact:referrer]] role:contact:REFERRER[[contact:REFERRER]]
end end
subgraph contact:permissions[ ] subgraph contact:permissions[ ]
@ -29,17 +29,17 @@ subgraph contact["`**contact**`"]
end end
%% granting roles to users %% granting roles to users
user:creator ==> role:contact:owner user:creator ==> role:contact:OWNER
%% granting roles to roles %% granting roles to roles
role:global:admin ==> role:contact:owner role:global:ADMIN ==> role:contact:OWNER
role:contact:owner ==> role:contact:admin role:contact:OWNER ==> role:contact:ADMIN
role:contact:admin ==> role:contact:referrer role:contact:ADMIN ==> role:contact:REFERRER
%% granting permissions to roles %% granting permissions to roles
role:contact:owner ==> perm:contact:DELETE role:contact:OWNER ==> perm:contact:DELETE
role:contact:admin ==> perm:contact:UPDATE role:contact:ADMIN ==> perm:contact:UPDATE
role:contact:referrer ==> perm:contact:SELECT role:contact:REFERRER ==> perm:contact:SELECT
role:global:guest ==> perm:contact:INSERT role:global:GUEST ==> perm:contact:INSERT
``` ```

View File

@ -35,22 +35,22 @@ begin
call enterTriggerForObjectUuid(NEW.uuid); call enterTriggerForObjectUuid(NEW.uuid);
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeContactOwner(NEW), hsOfficeContactOWNER(NEW),
permissions => array['DELETE'], permissions => array['DELETE'],
incomingSuperRoles => array[globalAdmin()], incomingSuperRoles => array[globalADMIN()],
userUuids => array[currentUserUuid()] userUuids => array[currentUserUuid()]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeContactAdmin(NEW), hsOfficeContactADMIN(NEW),
permissions => array['UPDATE'], permissions => array['UPDATE'],
incomingSuperRoles => array[hsOfficeContactOwner(NEW)] incomingSuperRoles => array[hsOfficeContactOWNER(NEW)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeContactReferrer(NEW), hsOfficeContactREFERRER(NEW),
permissions => array['SELECT'], permissions => array['SELECT'],
incomingSuperRoles => array[hsOfficeContactAdmin(NEW)] incomingSuperRoles => array[hsOfficeContactADMIN(NEW)]
); );
call leaveTriggerForObjectUuid(NEW.uuid); call leaveTriggerForObjectUuid(NEW.uuid);
@ -93,7 +93,7 @@ do language plpgsql $$
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'hs_office_contact'), createPermission(row.uuid, 'INSERT', 'hs_office_contact'),
globalGuest()); globalGUEST());
END LOOP; END LOOP;
END; END;
$$; $$;
@ -108,7 +108,7 @@ create or replace function hs_office_contact_global_insert_tf()
begin begin
call grantPermissionToRole( call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'hs_office_contact'), createPermission(NEW.uuid, 'INSERT', 'hs_office_contact'),
globalGuest()); globalGUEST());
return NEW; return NEW;
end; $$; end; $$;

View File

@ -13,9 +13,9 @@ subgraph person["`**person**`"]
subgraph person:roles[ ] subgraph person:roles[ ]
style person:roles fill:#dd4901,stroke:white style person:roles fill:#dd4901,stroke:white
role:person:owner[[person:owner]] role:person:OWNER[[person:OWNER]]
role:person:admin[[person:admin]] role:person:ADMIN[[person:ADMIN]]
role:person:referrer[[person:referrer]] role:person:REFERRER[[person:REFERRER]]
end end
subgraph person:permissions[ ] subgraph person:permissions[ ]
@ -29,17 +29,17 @@ subgraph person["`**person**`"]
end end
%% granting roles to users %% granting roles to users
user:creator ==> role:person:owner user:creator ==> role:person:OWNER
%% granting roles to roles %% granting roles to roles
role:global:admin ==> role:person:owner role:global:ADMIN ==> role:person:OWNER
role:person:owner ==> role:person:admin role:person:OWNER ==> role:person:ADMIN
role:person:admin ==> role:person:referrer role:person:ADMIN ==> role:person:REFERRER
%% granting permissions to roles %% granting permissions to roles
role:global:guest ==> perm:person:INSERT role:global:GUEST ==> perm:person:INSERT
role:person:owner ==> perm:person:DELETE role:person:OWNER ==> perm:person:DELETE
role:person:admin ==> perm:person:UPDATE role:person:ADMIN ==> perm:person:UPDATE
role:person:referrer ==> perm:person:SELECT role:person:REFERRER ==> perm:person:SELECT
``` ```

View File

@ -35,22 +35,22 @@ begin
call enterTriggerForObjectUuid(NEW.uuid); call enterTriggerForObjectUuid(NEW.uuid);
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficePersonOwner(NEW), hsOfficePersonOWNER(NEW),
permissions => array['DELETE'], permissions => array['DELETE'],
incomingSuperRoles => array[globalAdmin()], incomingSuperRoles => array[globalADMIN()],
userUuids => array[currentUserUuid()] userUuids => array[currentUserUuid()]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficePersonAdmin(NEW), hsOfficePersonADMIN(NEW),
permissions => array['UPDATE'], permissions => array['UPDATE'],
incomingSuperRoles => array[hsOfficePersonOwner(NEW)] incomingSuperRoles => array[hsOfficePersonOWNER(NEW)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficePersonReferrer(NEW), hsOfficePersonREFERRER(NEW),
permissions => array['SELECT'], permissions => array['SELECT'],
incomingSuperRoles => array[hsOfficePersonAdmin(NEW)] incomingSuperRoles => array[hsOfficePersonADMIN(NEW)]
); );
call leaveTriggerForObjectUuid(NEW.uuid); call leaveTriggerForObjectUuid(NEW.uuid);
@ -93,7 +93,7 @@ do language plpgsql $$
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'hs_office_person'), createPermission(row.uuid, 'INSERT', 'hs_office_person'),
globalGuest()); globalGUEST());
END LOOP; END LOOP;
END; END;
$$; $$;
@ -108,7 +108,7 @@ create or replace function hs_office_person_global_insert_tf()
begin begin
call grantPermissionToRole( call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'hs_office_person'), createPermission(NEW.uuid, 'INSERT', 'hs_office_person'),
globalGuest()); globalGUEST());
return NEW; return NEW;
end; $$; end; $$;

View File

@ -13,9 +13,9 @@ subgraph holderPerson["`**holderPerson**`"]
subgraph holderPerson:roles[ ] subgraph holderPerson:roles[ ]
style holderPerson:roles fill:#99bcdb,stroke:white style holderPerson:roles fill:#99bcdb,stroke:white
role:holderPerson:owner[[holderPerson:owner]] role:holderPerson:OWNER[[holderPerson:OWNER]]
role:holderPerson:admin[[holderPerson:admin]] role:holderPerson:ADMIN[[holderPerson:ADMIN]]
role:holderPerson:referrer[[holderPerson:referrer]] role:holderPerson:REFERRER[[holderPerson:REFERRER]]
end end
end end
@ -26,9 +26,9 @@ subgraph anchorPerson["`**anchorPerson**`"]
subgraph anchorPerson:roles[ ] subgraph anchorPerson:roles[ ]
style anchorPerson:roles fill:#99bcdb,stroke:white style anchorPerson:roles fill:#99bcdb,stroke:white
role:anchorPerson:owner[[anchorPerson:owner]] role:anchorPerson:OWNER[[anchorPerson:OWNER]]
role:anchorPerson:admin[[anchorPerson:admin]] role:anchorPerson:ADMIN[[anchorPerson:ADMIN]]
role:anchorPerson:referrer[[anchorPerson:referrer]] role:anchorPerson:REFERRER[[anchorPerson:REFERRER]]
end end
end end
@ -39,9 +39,9 @@ subgraph contact["`**contact**`"]
subgraph contact:roles[ ] subgraph contact:roles[ ]
style contact:roles fill:#99bcdb,stroke:white style contact:roles fill:#99bcdb,stroke:white
role:contact:owner[[contact:owner]] role:contact:OWNER[[contact:OWNER]]
role:contact:admin[[contact:admin]] role:contact:ADMIN[[contact:ADMIN]]
role:contact:referrer[[contact:referrer]] role:contact:REFERRER[[contact:REFERRER]]
end end
end end
@ -52,10 +52,10 @@ subgraph relation["`**relation**`"]
subgraph relation:roles[ ] subgraph relation:roles[ ]
style relation:roles fill:#dd4901,stroke:white style relation:roles fill:#dd4901,stroke:white
role:relation:owner[[relation:owner]] role:relation:OWNER[[relation:OWNER]]
role:relation:admin[[relation:admin]] role:relation:ADMIN[[relation:ADMIN]]
role:relation:agent[[relation:agent]] role:relation:AGENT[[relation:AGENT]]
role:relation:tenant[[relation:tenant]] role:relation:TENANT[[relation:TENANT]]
end end
subgraph relation:permissions[ ] subgraph relation:permissions[ ]
@ -69,34 +69,34 @@ subgraph relation["`**relation**`"]
end end
%% granting roles to users %% granting roles to users
user:creator ==> role:relation:owner user:creator ==> role:relation:OWNER
%% granting roles to roles %% granting roles to roles
role:global:admin -.-> role:anchorPerson:owner role:global:ADMIN -.-> role:anchorPerson:OWNER
role:anchorPerson:owner -.-> role:anchorPerson:admin role:anchorPerson:OWNER -.-> role:anchorPerson:ADMIN
role:anchorPerson:admin -.-> role:anchorPerson:referrer role:anchorPerson:ADMIN -.-> role:anchorPerson:REFERRER
role:global:admin -.-> role:holderPerson:owner role:global:ADMIN -.-> role:holderPerson:OWNER
role:holderPerson:owner -.-> role:holderPerson:admin role:holderPerson:OWNER -.-> role:holderPerson:ADMIN
role:holderPerson:admin -.-> role:holderPerson:referrer role:holderPerson:ADMIN -.-> role:holderPerson:REFERRER
role:global:admin -.-> role:contact:owner role:global:ADMIN -.-> role:contact:OWNER
role:contact:owner -.-> role:contact:admin role:contact:OWNER -.-> role:contact:ADMIN
role:contact:admin -.-> role:contact:referrer role:contact:ADMIN -.-> role:contact:REFERRER
role:global:admin ==> role:relation:owner role:global:ADMIN ==> role:relation:OWNER
role:relation:owner ==> role:relation:admin role:relation:OWNER ==> role:relation:ADMIN
role:anchorPerson:admin ==> role:relation:admin role:anchorPerson:ADMIN ==> role:relation:ADMIN
role:relation:admin ==> role:relation:agent role:relation:ADMIN ==> role:relation:AGENT
role:holderPerson:admin ==> role:relation:agent role:holderPerson:ADMIN ==> role:relation:AGENT
role:relation:agent ==> role:relation:tenant role:relation:AGENT ==> role:relation:TENANT
role:holderPerson:admin ==> role:relation:tenant role:holderPerson:ADMIN ==> role:relation:TENANT
role:contact:admin ==> role:relation:tenant role:contact:ADMIN ==> role:relation:TENANT
role:relation:tenant ==> role:anchorPerson:referrer role:relation:TENANT ==> role:anchorPerson:REFERRER
role:relation:tenant ==> role:holderPerson:referrer role:relation:TENANT ==> role:holderPerson:REFERRER
role:relation:tenant ==> role:contact:referrer role:relation:TENANT ==> role:contact:REFERRER
%% granting permissions to roles %% granting permissions to roles
role:relation:owner ==> perm:relation:DELETE role:relation:OWNER ==> perm:relation:DELETE
role:relation:admin ==> perm:relation:UPDATE role:relation:ADMIN ==> perm:relation:UPDATE
role:relation:tenant ==> perm:relation:SELECT role:relation:TENANT ==> perm:relation:SELECT
role:anchorPerson:admin ==> perm:relation:INSERT role:anchorPerson:ADMIN ==> perm:relation:INSERT
``` ```

View File

@ -48,38 +48,38 @@ begin
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeRelationOwner(NEW), hsOfficeRelationOWNER(NEW),
permissions => array['DELETE'], permissions => array['DELETE'],
incomingSuperRoles => array[globalAdmin()], incomingSuperRoles => array[globalADMIN()],
userUuids => array[currentUserUuid()] userUuids => array[currentUserUuid()]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeRelationAdmin(NEW), hsOfficeRelationADMIN(NEW),
permissions => array['UPDATE'], permissions => array['UPDATE'],
incomingSuperRoles => array[ incomingSuperRoles => array[
hsOfficePersonAdmin(newAnchorPerson), hsOfficePersonADMIN(newAnchorPerson),
hsOfficeRelationOwner(NEW)] hsOfficeRelationOWNER(NEW)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeRelationAgent(NEW), hsOfficeRelationAGENT(NEW),
incomingSuperRoles => array[ incomingSuperRoles => array[
hsOfficePersonAdmin(newHolderPerson), hsOfficePersonADMIN(newHolderPerson),
hsOfficeRelationAdmin(NEW)] hsOfficeRelationADMIN(NEW)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeRelationTenant(NEW), hsOfficeRelationTENANT(NEW),
permissions => array['SELECT'], permissions => array['SELECT'],
incomingSuperRoles => array[ incomingSuperRoles => array[
hsOfficeContactAdmin(newContact), hsOfficeContactADMIN(newContact),
hsOfficePersonAdmin(newHolderPerson), hsOfficePersonADMIN(newHolderPerson),
hsOfficeRelationAgent(NEW)], hsOfficeRelationAGENT(NEW)],
outgoingSubRoles => array[ outgoingSubRoles => array[
hsOfficeContactReferrer(newContact), hsOfficeContactREFERRER(newContact),
hsOfficePersonReferrer(newAnchorPerson), hsOfficePersonREFERRER(newAnchorPerson),
hsOfficePersonReferrer(newHolderPerson)] hsOfficePersonREFERRER(newHolderPerson)]
); );
call leaveTriggerForObjectUuid(NEW.uuid); call leaveTriggerForObjectUuid(NEW.uuid);
@ -151,11 +151,11 @@ begin
if NEW.contactUuid <> OLD.contactUuid then if NEW.contactUuid <> OLD.contactUuid then
call revokeRoleFromRole(hsOfficeRelationTenant(OLD), hsOfficeContactAdmin(oldContact)); call revokeRoleFromRole(hsOfficeRelationTENANT(OLD), hsOfficeContactADMIN(oldContact));
call grantRoleToRole(hsOfficeRelationTenant(NEW), hsOfficeContactAdmin(newContact)); call grantRoleToRole(hsOfficeRelationTENANT(NEW), hsOfficeContactADMIN(newContact));
call revokeRoleFromRole(hsOfficeContactReferrer(oldContact), hsOfficeRelationTenant(OLD)); call revokeRoleFromRole(hsOfficeContactREFERRER(oldContact), hsOfficeRelationTENANT(OLD));
call grantRoleToRole(hsOfficeContactReferrer(newContact), hsOfficeRelationTenant(NEW)); call grantRoleToRole(hsOfficeContactREFERRER(newContact), hsOfficeRelationTENANT(NEW));
end if; end if;
@ -199,7 +199,7 @@ do language plpgsql $$
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'hs_office_relation'), createPermission(row.uuid, 'INSERT', 'hs_office_relation'),
hsOfficePersonAdmin(row)); hsOfficePersonADMIN(row));
END LOOP; END LOOP;
END; END;
$$; $$;
@ -214,7 +214,7 @@ create or replace function hs_office_relation_hs_office_person_insert_tf()
begin begin
call grantPermissionToRole( call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'hs_office_relation'), createPermission(NEW.uuid, 'INSERT', 'hs_office_relation'),
hsOfficePersonAdmin(NEW)); hsOfficePersonADMIN(NEW));
return NEW; return NEW;
end; $$; end; $$;

View File

@ -25,7 +25,7 @@ declare
begin begin
idName := cleanIdentifier( anchorPersonName || '-' || holderPersonName); idName := cleanIdentifier( anchorPersonName || '-' || holderPersonName);
currentTask := 'creating relation test-data ' || idName; currentTask := 'creating relation test-data ' || idName;
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin'); call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
execute format('set local hsadminng.currentTask to %L', currentTask); execute format('set local hsadminng.currentTask to %L', currentTask);
select p.* select p.*

View File

@ -13,9 +13,9 @@ subgraph partnerRel.contact["`**partnerRel.contact**`"]
subgraph partnerRel.contact:roles[ ] subgraph partnerRel.contact:roles[ ]
style partnerRel.contact:roles fill:#99bcdb,stroke:white style partnerRel.contact:roles fill:#99bcdb,stroke:white
role:partnerRel.contact:owner[[partnerRel.contact:owner]] role:partnerRel.contact:OWNER[[partnerRel.contact:OWNER]]
role:partnerRel.contact:admin[[partnerRel.contact:admin]] role:partnerRel.contact:ADMIN[[partnerRel.contact:ADMIN]]
role:partnerRel.contact:referrer[[partnerRel.contact:referrer]] role:partnerRel.contact:REFERRER[[partnerRel.contact:REFERRER]]
end end
end end
@ -35,52 +35,14 @@ subgraph partner["`**partner**`"]
subgraph partnerRel["`**partnerRel**`"] subgraph partnerRel["`**partnerRel**`"]
direction TB direction TB
style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph partnerRel.contact["`**partnerRel.contact**`"]
direction TB
style partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph partnerRel.contact:roles[ ]
style partnerRel.contact:roles fill:#99bcdb,stroke:white
role:partnerRel.contact:owner[[partnerRel.contact:owner]]
role:partnerRel.contact:admin[[partnerRel.contact:admin]]
role:partnerRel.contact:referrer[[partnerRel.contact:referrer]]
end
end
subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
direction TB
style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph partnerRel.anchorPerson:roles[ ]
style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
role:partnerRel.anchorPerson:owner[[partnerRel.anchorPerson:owner]]
role:partnerRel.anchorPerson:admin[[partnerRel.anchorPerson:admin]]
role:partnerRel.anchorPerson:referrer[[partnerRel.anchorPerson:referrer]]
end
end
subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"]
direction TB
style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph partnerRel.holderPerson:roles[ ]
style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
role:partnerRel.holderPerson:owner[[partnerRel.holderPerson:owner]]
role:partnerRel.holderPerson:admin[[partnerRel.holderPerson:admin]]
role:partnerRel.holderPerson:referrer[[partnerRel.holderPerson:referrer]]
end
end
subgraph partnerRel:roles[ ] subgraph partnerRel:roles[ ]
style partnerRel:roles fill:#99bcdb,stroke:white style partnerRel:roles fill:#99bcdb,stroke:white
role:partnerRel:owner[[partnerRel:owner]] role:partnerRel:OWNER[[partnerRel:OWNER]]
role:partnerRel:admin[[partnerRel:admin]] role:partnerRel:ADMIN[[partnerRel:ADMIN]]
role:partnerRel:agent[[partnerRel:agent]] role:partnerRel:AGENT[[partnerRel:AGENT]]
role:partnerRel:tenant[[partnerRel:tenant]] role:partnerRel:TENANT[[partnerRel:TENANT]]
end end
end end
end end
@ -105,9 +67,9 @@ subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
subgraph partnerRel.anchorPerson:roles[ ] subgraph partnerRel.anchorPerson:roles[ ]
style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
role:partnerRel.anchorPerson:owner[[partnerRel.anchorPerson:owner]] role:partnerRel.anchorPerson:OWNER[[partnerRel.anchorPerson:OWNER]]
role:partnerRel.anchorPerson:admin[[partnerRel.anchorPerson:admin]] role:partnerRel.anchorPerson:ADMIN[[partnerRel.anchorPerson:ADMIN]]
role:partnerRel.anchorPerson:referrer[[partnerRel.anchorPerson:referrer]] role:partnerRel.anchorPerson:REFERRER[[partnerRel.anchorPerson:REFERRER]]
end end
end end
@ -118,41 +80,41 @@ subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"]
subgraph partnerRel.holderPerson:roles[ ] subgraph partnerRel.holderPerson:roles[ ]
style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
role:partnerRel.holderPerson:owner[[partnerRel.holderPerson:owner]] role:partnerRel.holderPerson:OWNER[[partnerRel.holderPerson:OWNER]]
role:partnerRel.holderPerson:admin[[partnerRel.holderPerson:admin]] role:partnerRel.holderPerson:ADMIN[[partnerRel.holderPerson:ADMIN]]
role:partnerRel.holderPerson:referrer[[partnerRel.holderPerson:referrer]] role:partnerRel.holderPerson:REFERRER[[partnerRel.holderPerson:REFERRER]]
end end
end end
%% granting roles to roles %% granting roles to roles
role:global:admin -.-> role:partnerRel.anchorPerson:owner role:global:ADMIN -.-> role:partnerRel.anchorPerson:OWNER
role:partnerRel.anchorPerson:owner -.-> role:partnerRel.anchorPerson:admin role:partnerRel.anchorPerson:OWNER -.-> role:partnerRel.anchorPerson:ADMIN
role:partnerRel.anchorPerson:admin -.-> role:partnerRel.anchorPerson:referrer role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel.anchorPerson:REFERRER
role:global:admin -.-> role:partnerRel.holderPerson:owner role:global:ADMIN -.-> role:partnerRel.holderPerson:OWNER
role:partnerRel.holderPerson:owner -.-> role:partnerRel.holderPerson:admin role:partnerRel.holderPerson:OWNER -.-> role:partnerRel.holderPerson:ADMIN
role:partnerRel.holderPerson:admin -.-> role:partnerRel.holderPerson:referrer role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel.holderPerson:REFERRER
role:global:admin -.-> role:partnerRel.contact:owner role:global:ADMIN -.-> role:partnerRel.contact:OWNER
role:partnerRel.contact:owner -.-> role:partnerRel.contact:admin role:partnerRel.contact:OWNER -.-> role:partnerRel.contact:ADMIN
role:partnerRel.contact:admin -.-> role:partnerRel.contact:referrer role:partnerRel.contact:ADMIN -.-> role:partnerRel.contact:REFERRER
role:global:admin -.-> role:partnerRel:owner role:global:ADMIN -.-> role:partnerRel:OWNER
role:partnerRel:owner -.-> role:partnerRel:admin role:partnerRel:OWNER -.-> role:partnerRel:ADMIN
role:partnerRel.anchorPerson:admin -.-> role:partnerRel:admin role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:ADMIN
role:partnerRel:admin -.-> role:partnerRel:agent role:partnerRel:ADMIN -.-> role:partnerRel:AGENT
role:partnerRel.holderPerson:admin -.-> role:partnerRel:agent role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT
role:partnerRel:agent -.-> role:partnerRel:tenant role:partnerRel:AGENT -.-> role:partnerRel:TENANT
role:partnerRel.holderPerson:admin -.-> role:partnerRel:tenant role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:TENANT
role:partnerRel.contact:admin -.-> role:partnerRel:tenant role:partnerRel.contact:ADMIN -.-> role:partnerRel:TENANT
role:partnerRel:tenant -.-> role:partnerRel.anchorPerson:referrer role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER
role:partnerRel:tenant -.-> role:partnerRel.holderPerson:referrer role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER
role:partnerRel:tenant -.-> role:partnerRel.contact:referrer role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER
%% granting permissions to roles %% granting permissions to roles
role:global:admin ==> perm:partner:INSERT role:global:ADMIN ==> perm:partner:INSERT
role:partnerRel:admin ==> perm:partner:DELETE role:partnerRel:ADMIN ==> perm:partner:DELETE
role:partnerRel:agent ==> perm:partner:UPDATE role:partnerRel:AGENT ==> perm:partner:UPDATE
role:partnerRel:tenant ==> perm:partner:SELECT role:partnerRel:TENANT ==> perm:partner:SELECT
role:partnerRel:admin ==> perm:partnerDetails:DELETE role:partnerRel:ADMIN ==> perm:partnerDetails:DELETE
role:partnerRel:agent ==> perm:partnerDetails:UPDATE role:partnerRel:AGENT ==> perm:partnerDetails:UPDATE
role:partnerRel:agent ==> perm:partnerDetails:SELECT role:partnerRel:AGENT ==> perm:partnerDetails:SELECT
``` ```

View File

@ -42,12 +42,12 @@ begin
SELECT * FROM hs_office_partner_details WHERE uuid = NEW.detailsUuid INTO newPartnerDetails; SELECT * FROM hs_office_partner_details WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s', NEW.detailsUuid); assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s', NEW.detailsUuid);
call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationAdmin(newPartnerRel)); call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationADMIN(newPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationTenant(newPartnerRel)); call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationTENANT(newPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationAgent(newPartnerRel)); call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationAGENT(newPartnerRel));
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'DELETE'), hsOfficeRelationAdmin(newPartnerRel)); call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'DELETE'), hsOfficeRelationADMIN(newPartnerRel));
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'SELECT'), hsOfficeRelationAgent(newPartnerRel)); call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'SELECT'), hsOfficeRelationAGENT(newPartnerRel));
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAgent(newPartnerRel)); call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAGENT(newPartnerRel));
call leaveTriggerForObjectUuid(NEW.uuid); call leaveTriggerForObjectUuid(NEW.uuid);
end; $$; end; $$;
@ -110,23 +110,23 @@ begin
if NEW.partnerRelUuid <> OLD.partnerRelUuid then if NEW.partnerRelUuid <> OLD.partnerRelUuid then
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'DELETE'), hsOfficeRelationAdmin(oldPartnerRel)); call revokePermissionFromRole(getPermissionId(OLD.uuid, 'DELETE'), hsOfficeRelationADMIN(oldPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationAdmin(newPartnerRel)); call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationADMIN(newPartnerRel));
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'UPDATE'), hsOfficeRelationAgent(oldPartnerRel)); call revokePermissionFromRole(getPermissionId(OLD.uuid, 'UPDATE'), hsOfficeRelationAGENT(oldPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationAgent(newPartnerRel)); call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationAGENT(newPartnerRel));
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'SELECT'), hsOfficeRelationTenant(oldPartnerRel)); call revokePermissionFromRole(getPermissionId(OLD.uuid, 'SELECT'), hsOfficeRelationTENANT(oldPartnerRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationTenant(newPartnerRel)); call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationTENANT(newPartnerRel));
call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'DELETE'), hsOfficeRelationAdmin(oldPartnerRel)); call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'DELETE'), hsOfficeRelationADMIN(oldPartnerRel));
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'DELETE'), hsOfficeRelationAdmin(newPartnerRel)); call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'DELETE'), hsOfficeRelationADMIN(newPartnerRel));
call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAgent(oldPartnerRel)); call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAGENT(oldPartnerRel));
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAgent(newPartnerRel)); call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAGENT(newPartnerRel));
call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'SELECT'), hsOfficeRelationAgent(oldPartnerRel)); call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'SELECT'), hsOfficeRelationAGENT(oldPartnerRel));
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'SELECT'), hsOfficeRelationAgent(newPartnerRel)); call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'SELECT'), hsOfficeRelationAGENT(newPartnerRel));
end if; end if;
@ -170,7 +170,7 @@ do language plpgsql $$
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'hs_office_partner'), createPermission(row.uuid, 'INSERT', 'hs_office_partner'),
globalAdmin()); globalADMIN());
END LOOP; END LOOP;
END; END;
$$; $$;
@ -185,7 +185,7 @@ create or replace function hs_office_partner_global_insert_tf()
begin begin
call grantPermissionToRole( call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'hs_office_partner'), createPermission(NEW.uuid, 'INSERT', 'hs_office_partner'),
globalAdmin()); globalADMIN());
return NEW; return NEW;
end; $$; end; $$;

View File

@ -18,6 +18,6 @@ subgraph partnerDetails["`**partnerDetails**`"]
end end
%% granting permissions to roles %% granting permissions to roles
role:global:admin ==> perm:partnerDetails:INSERT role:global:ADMIN ==> perm:partnerDetails:INSERT
``` ```

View File

@ -74,7 +74,7 @@ do language plpgsql $$
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'hs_office_partner_details'), createPermission(row.uuid, 'INSERT', 'hs_office_partner_details'),
globalAdmin()); globalADMIN());
END LOOP; END LOOP;
END; END;
$$; $$;
@ -89,7 +89,7 @@ create or replace function hs_office_partner_details_global_insert_tf()
begin begin
call grantPermissionToRole( call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'hs_office_partner_details'), createPermission(NEW.uuid, 'INSERT', 'hs_office_partner_details'),
globalAdmin()); globalADMIN());
return NEW; return NEW;
end; $$; end; $$;
@ -107,8 +107,8 @@ create or replace function hs_office_partner_details_insert_permission_missing_t
returns trigger returns trigger
language plpgsql as $$ language plpgsql as $$
begin begin
raise exception '[403] insert into hs_office_partner_details not allowed for current subjects % (%) assumed by user % (%)', raise exception '[403] insert into hs_office_partner_details not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids(), currentUser(), currentUserUuid(); currentSubjects(), currentSubjectsUuids();
end; $$; end; $$;
create trigger hs_office_partner_details_insert_permission_check_tg create trigger hs_office_partner_details_insert_permission_check_tg
@ -124,7 +124,7 @@ create trigger hs_office_partner_details_insert_permission_check_tg
call generateRbacIdentityViewFromQuery('hs_office_partner_details', call generateRbacIdentityViewFromQuery('hs_office_partner_details',
$idName$ $idName$
SELECT partnerDetails.uuid as uuid, partner_iv.idName || '-details' as idName SELECT partnerDetails.uuid as uuid, partner_iv.idName as idName
FROM hs_office_partner_details AS partnerDetails FROM hs_office_partner_details AS partnerDetails
JOIN hs_office_partner partner ON partner.detailsUuid = partnerDetails.uuid JOIN hs_office_partner partner ON partner.detailsUuid = partnerDetails.uuid
JOIN hs_office_partner_iv partner_iv ON partner_iv.uuid = partner.uuid JOIN hs_office_partner_iv partner_iv ON partner_iv.uuid = partner.uuid

View File

@ -24,7 +24,7 @@ declare
begin begin
idName := cleanIdentifier( partnerPersonName|| '-' || contactLabel); idName := cleanIdentifier( partnerPersonName|| '-' || contactLabel);
currentTask := 'creating partner test-data ' || idName; currentTask := 'creating partner test-data ' || idName;
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin'); call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
execute format('set local hsadminng.currentTask to %L', currentTask); execute format('set local hsadminng.currentTask to %L', currentTask);
select p.* from hs_office_person p select p.* from hs_office_person p

View File

@ -13,9 +13,9 @@ subgraph bankAccount["`**bankAccount**`"]
subgraph bankAccount:roles[ ] subgraph bankAccount:roles[ ]
style bankAccount:roles fill:#dd4901,stroke:white style bankAccount:roles fill:#dd4901,stroke:white
role:bankAccount:owner[[bankAccount:owner]] role:bankAccount:OWNER[[bankAccount:OWNER]]
role:bankAccount:admin[[bankAccount:admin]] role:bankAccount:ADMIN[[bankAccount:ADMIN]]
role:bankAccount:referrer[[bankAccount:referrer]] role:bankAccount:REFERRER[[bankAccount:REFERRER]]
end end
subgraph bankAccount:permissions[ ] subgraph bankAccount:permissions[ ]
@ -29,17 +29,17 @@ subgraph bankAccount["`**bankAccount**`"]
end end
%% granting roles to users %% granting roles to users
user:creator ==> role:bankAccount:owner user:creator ==> role:bankAccount:OWNER
%% granting roles to roles %% granting roles to roles
role:global:admin ==> role:bankAccount:owner role:global:ADMIN ==> role:bankAccount:OWNER
role:bankAccount:owner ==> role:bankAccount:admin role:bankAccount:OWNER ==> role:bankAccount:ADMIN
role:bankAccount:admin ==> role:bankAccount:referrer role:bankAccount:ADMIN ==> role:bankAccount:REFERRER
%% granting permissions to roles %% granting permissions to roles
role:global:guest ==> perm:bankAccount:INSERT role:global:GUEST ==> perm:bankAccount:INSERT
role:bankAccount:owner ==> perm:bankAccount:DELETE role:bankAccount:OWNER ==> perm:bankAccount:DELETE
role:bankAccount:admin ==> perm:bankAccount:UPDATE role:bankAccount:ADMIN ==> perm:bankAccount:UPDATE
role:bankAccount:referrer ==> perm:bankAccount:SELECT role:bankAccount:REFERRER ==> perm:bankAccount:SELECT
``` ```

View File

@ -35,22 +35,22 @@ begin
call enterTriggerForObjectUuid(NEW.uuid); call enterTriggerForObjectUuid(NEW.uuid);
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeBankAccountOwner(NEW), hsOfficeBankAccountOWNER(NEW),
permissions => array['DELETE'], permissions => array['DELETE'],
incomingSuperRoles => array[globalAdmin()], incomingSuperRoles => array[globalADMIN()],
userUuids => array[currentUserUuid()] userUuids => array[currentUserUuid()]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeBankAccountAdmin(NEW), hsOfficeBankAccountADMIN(NEW),
permissions => array['UPDATE'], permissions => array['UPDATE'],
incomingSuperRoles => array[hsOfficeBankAccountOwner(NEW)] incomingSuperRoles => array[hsOfficeBankAccountOWNER(NEW)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeBankAccountReferrer(NEW), hsOfficeBankAccountREFERRER(NEW),
permissions => array['SELECT'], permissions => array['SELECT'],
incomingSuperRoles => array[hsOfficeBankAccountAdmin(NEW)] incomingSuperRoles => array[hsOfficeBankAccountADMIN(NEW)]
); );
call leaveTriggerForObjectUuid(NEW.uuid); call leaveTriggerForObjectUuid(NEW.uuid);
@ -93,7 +93,7 @@ do language plpgsql $$
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'hs_office_bankaccount'), createPermission(row.uuid, 'INSERT', 'hs_office_bankaccount'),
globalGuest()); globalGUEST());
END LOOP; END LOOP;
END; END;
$$; $$;
@ -108,7 +108,7 @@ create or replace function hs_office_bankaccount_global_insert_tf()
begin begin
call grantPermissionToRole( call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'hs_office_bankaccount'), createPermission(NEW.uuid, 'INSERT', 'hs_office_bankaccount'),
globalGuest()); globalGUEST());
return NEW; return NEW;
end; $$; end; $$;

View File

@ -13,9 +13,9 @@ subgraph bankAccount["`**bankAccount**`"]
subgraph bankAccount:roles[ ] subgraph bankAccount:roles[ ]
style bankAccount:roles fill:#99bcdb,stroke:white style bankAccount:roles fill:#99bcdb,stroke:white
role:bankAccount:owner[[bankAccount:owner]] role:bankAccount:OWNER[[bankAccount:OWNER]]
role:bankAccount:admin[[bankAccount:admin]] role:bankAccount:ADMIN[[bankAccount:ADMIN]]
role:bankAccount:referrer[[bankAccount:referrer]] role:bankAccount:REFERRER[[bankAccount:REFERRER]]
end end
end end
@ -26,9 +26,9 @@ subgraph debitorRel.contact["`**debitorRel.contact**`"]
subgraph debitorRel.contact:roles[ ] subgraph debitorRel.contact:roles[ ]
style debitorRel.contact:roles fill:#99bcdb,stroke:white style debitorRel.contact:roles fill:#99bcdb,stroke:white
role:debitorRel.contact:owner[[debitorRel.contact:owner]] role:debitorRel.contact:OWNER[[debitorRel.contact:OWNER]]
role:debitorRel.contact:admin[[debitorRel.contact:admin]] role:debitorRel.contact:ADMIN[[debitorRel.contact:ADMIN]]
role:debitorRel.contact:referrer[[debitorRel.contact:referrer]] role:debitorRel.contact:REFERRER[[debitorRel.contact:REFERRER]]
end end
end end
@ -39,9 +39,9 @@ subgraph debitorRel.anchorPerson["`**debitorRel.anchorPerson**`"]
subgraph debitorRel.anchorPerson:roles[ ] subgraph debitorRel.anchorPerson:roles[ ]
style debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white style debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
role:debitorRel.anchorPerson:owner[[debitorRel.anchorPerson:owner]] role:debitorRel.anchorPerson:OWNER[[debitorRel.anchorPerson:OWNER]]
role:debitorRel.anchorPerson:admin[[debitorRel.anchorPerson:admin]] role:debitorRel.anchorPerson:ADMIN[[debitorRel.anchorPerson:ADMIN]]
role:debitorRel.anchorPerson:referrer[[debitorRel.anchorPerson:referrer]] role:debitorRel.anchorPerson:REFERRER[[debitorRel.anchorPerson:REFERRER]]
end end
end end
@ -52,9 +52,9 @@ subgraph debitorRel.holderPerson["`**debitorRel.holderPerson**`"]
subgraph debitorRel.holderPerson:roles[ ] subgraph debitorRel.holderPerson:roles[ ]
style debitorRel.holderPerson:roles fill:#99bcdb,stroke:white style debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
role:debitorRel.holderPerson:owner[[debitorRel.holderPerson:owner]] role:debitorRel.holderPerson:OWNER[[debitorRel.holderPerson:OWNER]]
role:debitorRel.holderPerson:admin[[debitorRel.holderPerson:admin]] role:debitorRel.holderPerson:ADMIN[[debitorRel.holderPerson:ADMIN]]
role:debitorRel.holderPerson:referrer[[debitorRel.holderPerson:referrer]] role:debitorRel.holderPerson:REFERRER[[debitorRel.holderPerson:REFERRER]]
end end
end end
@ -65,10 +65,10 @@ subgraph sepaMandate["`**sepaMandate**`"]
subgraph sepaMandate:roles[ ] subgraph sepaMandate:roles[ ]
style sepaMandate:roles fill:#dd4901,stroke:white style sepaMandate:roles fill:#dd4901,stroke:white
role:sepaMandate:owner[[sepaMandate:owner]] role:sepaMandate:OWNER[[sepaMandate:OWNER]]
role:sepaMandate:admin[[sepaMandate:admin]] role:sepaMandate:ADMIN[[sepaMandate:ADMIN]]
role:sepaMandate:agent[[sepaMandate:agent]] role:sepaMandate:AGENT[[sepaMandate:AGENT]]
role:sepaMandate:referrer[[sepaMandate:referrer]] role:sepaMandate:REFERRER[[sepaMandate:REFERRER]]
end end
subgraph sepaMandate:permissions[ ] subgraph sepaMandate:permissions[ ]
@ -85,96 +85,57 @@ subgraph debitorRel["`**debitorRel**`"]
direction TB direction TB
style debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px style debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph debitorRel.contact["`**debitorRel.contact**`"]
direction TB
style debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph debitorRel.contact:roles[ ]
style debitorRel.contact:roles fill:#99bcdb,stroke:white
role:debitorRel.contact:owner[[debitorRel.contact:owner]]
role:debitorRel.contact:admin[[debitorRel.contact:admin]]
role:debitorRel.contact:referrer[[debitorRel.contact:referrer]]
end
end
subgraph debitorRel.anchorPerson["`**debitorRel.anchorPerson**`"]
direction TB
style debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph debitorRel.anchorPerson:roles[ ]
style debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
role:debitorRel.anchorPerson:owner[[debitorRel.anchorPerson:owner]]
role:debitorRel.anchorPerson:admin[[debitorRel.anchorPerson:admin]]
role:debitorRel.anchorPerson:referrer[[debitorRel.anchorPerson:referrer]]
end
end
subgraph debitorRel.holderPerson["`**debitorRel.holderPerson**`"]
direction TB
style debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph debitorRel.holderPerson:roles[ ]
style debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
role:debitorRel.holderPerson:owner[[debitorRel.holderPerson:owner]]
role:debitorRel.holderPerson:admin[[debitorRel.holderPerson:admin]]
role:debitorRel.holderPerson:referrer[[debitorRel.holderPerson:referrer]]
end
end
subgraph debitorRel:roles[ ] subgraph debitorRel:roles[ ]
style debitorRel:roles fill:#99bcdb,stroke:white style debitorRel:roles fill:#99bcdb,stroke:white
role:debitorRel:owner[[debitorRel:owner]] role:debitorRel:OWNER[[debitorRel:OWNER]]
role:debitorRel:admin[[debitorRel:admin]] role:debitorRel:ADMIN[[debitorRel:ADMIN]]
role:debitorRel:agent[[debitorRel:agent]] role:debitorRel:AGENT[[debitorRel:AGENT]]
role:debitorRel:tenant[[debitorRel:tenant]] role:debitorRel:TENANT[[debitorRel:TENANT]]
end end
end end
%% granting roles to users %% granting roles to users
user:creator ==> role:sepaMandate:owner user:creator ==> role:sepaMandate:OWNER
%% granting roles to roles %% granting roles to roles
role:global:admin -.-> role:debitorRel.anchorPerson:owner role:global:ADMIN -.-> role:debitorRel.anchorPerson:OWNER
role:debitorRel.anchorPerson:owner -.-> role:debitorRel.anchorPerson:admin role:debitorRel.anchorPerson:OWNER -.-> role:debitorRel.anchorPerson:ADMIN
role:debitorRel.anchorPerson:admin -.-> role:debitorRel.anchorPerson:referrer role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel.anchorPerson:REFERRER
role:global:admin -.-> role:debitorRel.holderPerson:owner role:global:ADMIN -.-> role:debitorRel.holderPerson:OWNER
role:debitorRel.holderPerson:owner -.-> role:debitorRel.holderPerson:admin role:debitorRel.holderPerson:OWNER -.-> role:debitorRel.holderPerson:ADMIN
role:debitorRel.holderPerson:admin -.-> role:debitorRel.holderPerson:referrer role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel.holderPerson:REFERRER
role:global:admin -.-> role:debitorRel.contact:owner role:global:ADMIN -.-> role:debitorRel.contact:OWNER
role:debitorRel.contact:owner -.-> role:debitorRel.contact:admin role:debitorRel.contact:OWNER -.-> role:debitorRel.contact:ADMIN
role:debitorRel.contact:admin -.-> role:debitorRel.contact:referrer role:debitorRel.contact:ADMIN -.-> role:debitorRel.contact:REFERRER
role:global:admin -.-> role:debitorRel:owner role:global:ADMIN -.-> role:debitorRel:OWNER
role:debitorRel:owner -.-> role:debitorRel:admin role:debitorRel:OWNER -.-> role:debitorRel:ADMIN
role:debitorRel.anchorPerson:admin -.-> role:debitorRel:admin role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel:ADMIN
role:debitorRel:admin -.-> role:debitorRel:agent role:debitorRel:ADMIN -.-> role:debitorRel:AGENT
role:debitorRel.holderPerson:admin -.-> role:debitorRel:agent role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:AGENT
role:debitorRel:agent -.-> role:debitorRel:tenant role:debitorRel:AGENT -.-> role:debitorRel:TENANT
role:debitorRel.holderPerson:admin -.-> role:debitorRel:tenant role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:TENANT
role:debitorRel.contact:admin -.-> role:debitorRel:tenant role:debitorRel.contact:ADMIN -.-> role:debitorRel:TENANT
role:debitorRel:tenant -.-> role:debitorRel.anchorPerson:referrer role:debitorRel:TENANT -.-> role:debitorRel.anchorPerson:REFERRER
role:debitorRel:tenant -.-> role:debitorRel.holderPerson:referrer role:debitorRel:TENANT -.-> role:debitorRel.holderPerson:REFERRER
role:debitorRel:tenant -.-> role:debitorRel.contact:referrer role:debitorRel:TENANT -.-> role:debitorRel.contact:REFERRER
role:global:admin -.-> role:bankAccount:owner role:global:ADMIN -.-> role:bankAccount:OWNER
role:bankAccount:owner -.-> role:bankAccount:admin role:bankAccount:OWNER -.-> role:bankAccount:ADMIN
role:bankAccount:admin -.-> role:bankAccount:referrer role:bankAccount:ADMIN -.-> role:bankAccount:REFERRER
role:global:admin ==> role:sepaMandate:owner role:global:ADMIN ==> role:sepaMandate:OWNER
role:sepaMandate:owner ==> role:sepaMandate:admin role:sepaMandate:OWNER ==> role:sepaMandate:ADMIN
role:sepaMandate:admin ==> role:sepaMandate:agent role:sepaMandate:ADMIN ==> role:sepaMandate:AGENT
role:sepaMandate:agent ==> role:bankAccount:referrer role:sepaMandate:AGENT ==> role:bankAccount:REFERRER
role:sepaMandate:agent ==> role:debitorRel:agent role:sepaMandate:AGENT ==> role:debitorRel:AGENT
role:sepaMandate:agent ==> role:sepaMandate:referrer role:sepaMandate:AGENT ==> role:sepaMandate:REFERRER
role:bankAccount:admin ==> role:sepaMandate:referrer role:bankAccount:ADMIN ==> role:sepaMandate:REFERRER
role:debitorRel:agent ==> role:sepaMandate:referrer role:debitorRel:AGENT ==> role:sepaMandate:REFERRER
role:sepaMandate:referrer ==> role:debitorRel:tenant role:sepaMandate:REFERRER ==> role:debitorRel:TENANT
%% granting permissions to roles %% granting permissions to roles
role:sepaMandate:owner ==> perm:sepaMandate:DELETE role:sepaMandate:OWNER ==> perm:sepaMandate:DELETE
role:sepaMandate:admin ==> perm:sepaMandate:UPDATE role:sepaMandate:ADMIN ==> perm:sepaMandate:UPDATE
role:sepaMandate:referrer ==> perm:sepaMandate:SELECT role:sepaMandate:REFERRER ==> perm:sepaMandate:SELECT
role:debitorRel:admin ==> perm:sepaMandate:INSERT role:debitorRel:ADMIN ==> perm:sepaMandate:INSERT
``` ```

View File

@ -48,34 +48,34 @@ begin
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeSepaMandateOwner(NEW), hsOfficeSepaMandateOWNER(NEW),
permissions => array['DELETE'], permissions => array['DELETE'],
incomingSuperRoles => array[globalAdmin()], incomingSuperRoles => array[globalADMIN()],
userUuids => array[currentUserUuid()] userUuids => array[currentUserUuid()]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeSepaMandateAdmin(NEW), hsOfficeSepaMandateADMIN(NEW),
permissions => array['UPDATE'], permissions => array['UPDATE'],
incomingSuperRoles => array[hsOfficeSepaMandateOwner(NEW)] incomingSuperRoles => array[hsOfficeSepaMandateOWNER(NEW)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeSepaMandateAgent(NEW), hsOfficeSepaMandateAGENT(NEW),
incomingSuperRoles => array[hsOfficeSepaMandateAdmin(NEW)], incomingSuperRoles => array[hsOfficeSepaMandateADMIN(NEW)],
outgoingSubRoles => array[ outgoingSubRoles => array[
hsOfficeBankAccountReferrer(newBankAccount), hsOfficeBankAccountREFERRER(newBankAccount),
hsOfficeRelationAgent(newDebitorRel)] hsOfficeRelationAGENT(newDebitorRel)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeSepaMandateReferrer(NEW), hsOfficeSepaMandateREFERRER(NEW),
permissions => array['SELECT'], permissions => array['SELECT'],
incomingSuperRoles => array[ incomingSuperRoles => array[
hsOfficeBankAccountAdmin(newBankAccount), hsOfficeBankAccountADMIN(newBankAccount),
hsOfficeRelationAgent(newDebitorRel), hsOfficeRelationAGENT(newDebitorRel),
hsOfficeSepaMandateAgent(NEW)], hsOfficeSepaMandateAGENT(NEW)],
outgoingSubRoles => array[hsOfficeRelationTenant(newDebitorRel)] outgoingSubRoles => array[hsOfficeRelationTENANT(newDebitorRel)]
); );
call leaveTriggerForObjectUuid(NEW.uuid); call leaveTriggerForObjectUuid(NEW.uuid);
@ -118,7 +118,7 @@ do language plpgsql $$
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'hs_office_sepamandate'), createPermission(row.uuid, 'INSERT', 'hs_office_sepamandate'),
hsOfficeRelationAdmin(row)); hsOfficeRelationADMIN(row));
END LOOP; END LOOP;
END; END;
$$; $$;
@ -133,7 +133,7 @@ create or replace function hs_office_sepamandate_hs_office_relation_insert_tf()
begin begin
call grantPermissionToRole( call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'hs_office_sepamandate'), createPermission(NEW.uuid, 'INSERT', 'hs_office_sepamandate'),
hsOfficeRelationAdmin(NEW)); hsOfficeRelationADMIN(NEW));
return NEW; return NEW;
end; $$; end; $$;

View File

@ -20,7 +20,7 @@ declare
relatedBankAccount hs_office_bankAccount; relatedBankAccount hs_office_bankAccount;
begin begin
currentTask := 'creating SEPA-mandate test-data ' || forPartnerNumber::text || forDebitorSuffix::text; currentTask := 'creating SEPA-mandate test-data ' || forPartnerNumber::text || forDebitorSuffix::text;
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin'); call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
execute format('set local hsadminng.currentTask to %L', currentTask); execute format('set local hsadminng.currentTask to %L', currentTask);
select debitor.* into relatedDebitor select debitor.* into relatedDebitor

View File

@ -13,9 +13,9 @@ subgraph debitorRel.anchorPerson["`**debitorRel.anchorPerson**`"]
subgraph debitorRel.anchorPerson:roles[ ] subgraph debitorRel.anchorPerson:roles[ ]
style debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white style debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
role:debitorRel.anchorPerson:owner[[debitorRel.anchorPerson:owner]] role:debitorRel.anchorPerson:OWNER[[debitorRel.anchorPerson:OWNER]]
role:debitorRel.anchorPerson:admin[[debitorRel.anchorPerson:admin]] role:debitorRel.anchorPerson:ADMIN[[debitorRel.anchorPerson:ADMIN]]
role:debitorRel.anchorPerson:referrer[[debitorRel.anchorPerson:referrer]] role:debitorRel.anchorPerson:REFERRER[[debitorRel.anchorPerson:REFERRER]]
end end
end end
@ -26,9 +26,9 @@ subgraph debitorRel.holderPerson["`**debitorRel.holderPerson**`"]
subgraph debitorRel.holderPerson:roles[ ] subgraph debitorRel.holderPerson:roles[ ]
style debitorRel.holderPerson:roles fill:#99bcdb,stroke:white style debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
role:debitorRel.holderPerson:owner[[debitorRel.holderPerson:owner]] role:debitorRel.holderPerson:OWNER[[debitorRel.holderPerson:OWNER]]
role:debitorRel.holderPerson:admin[[debitorRel.holderPerson:admin]] role:debitorRel.holderPerson:ADMIN[[debitorRel.holderPerson:ADMIN]]
role:debitorRel.holderPerson:referrer[[debitorRel.holderPerson:referrer]] role:debitorRel.holderPerson:REFERRER[[debitorRel.holderPerson:REFERRER]]
end end
end end
@ -39,9 +39,9 @@ subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"]
subgraph partnerRel.holderPerson:roles[ ] subgraph partnerRel.holderPerson:roles[ ]
style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
role:partnerRel.holderPerson:owner[[partnerRel.holderPerson:owner]] role:partnerRel.holderPerson:OWNER[[partnerRel.holderPerson:OWNER]]
role:partnerRel.holderPerson:admin[[partnerRel.holderPerson:admin]] role:partnerRel.holderPerson:ADMIN[[partnerRel.holderPerson:ADMIN]]
role:partnerRel.holderPerson:referrer[[partnerRel.holderPerson:referrer]] role:partnerRel.holderPerson:REFERRER[[partnerRel.holderPerson:REFERRER]]
end end
end end
@ -61,52 +61,14 @@ subgraph debitor["`**debitor**`"]
subgraph debitorRel["`**debitorRel**`"] subgraph debitorRel["`**debitorRel**`"]
direction TB direction TB
style debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px style debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph debitorRel.anchorPerson["`**debitorRel.anchorPerson**`"]
direction TB
style debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph debitorRel.anchorPerson:roles[ ]
style debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
role:debitorRel.anchorPerson:owner[[debitorRel.anchorPerson:owner]]
role:debitorRel.anchorPerson:admin[[debitorRel.anchorPerson:admin]]
role:debitorRel.anchorPerson:referrer[[debitorRel.anchorPerson:referrer]]
end
end
subgraph debitorRel.holderPerson["`**debitorRel.holderPerson**`"]
direction TB
style debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph debitorRel.holderPerson:roles[ ]
style debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
role:debitorRel.holderPerson:owner[[debitorRel.holderPerson:owner]]
role:debitorRel.holderPerson:admin[[debitorRel.holderPerson:admin]]
role:debitorRel.holderPerson:referrer[[debitorRel.holderPerson:referrer]]
end
end
subgraph debitorRel.contact["`**debitorRel.contact**`"]
direction TB
style debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph debitorRel.contact:roles[ ]
style debitorRel.contact:roles fill:#99bcdb,stroke:white
role:debitorRel.contact:owner[[debitorRel.contact:owner]]
role:debitorRel.contact:admin[[debitorRel.contact:admin]]
role:debitorRel.contact:referrer[[debitorRel.contact:referrer]]
end
end
subgraph debitorRel:roles[ ] subgraph debitorRel:roles[ ]
style debitorRel:roles fill:#99bcdb,stroke:white style debitorRel:roles fill:#99bcdb,stroke:white
role:debitorRel:owner[[debitorRel:owner]] role:debitorRel:OWNER[[debitorRel:OWNER]]
role:debitorRel:admin[[debitorRel:admin]] role:debitorRel:ADMIN[[debitorRel:ADMIN]]
role:debitorRel:agent[[debitorRel:agent]] role:debitorRel:AGENT[[debitorRel:AGENT]]
role:debitorRel:tenant[[debitorRel:tenant]] role:debitorRel:TENANT[[debitorRel:TENANT]]
end end
end end
end end
@ -115,52 +77,13 @@ subgraph partnerRel["`**partnerRel**`"]
direction TB direction TB
style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"]
direction TB
style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph partnerRel.holderPerson:roles[ ]
style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
role:partnerRel.holderPerson:owner[[partnerRel.holderPerson:owner]]
role:partnerRel.holderPerson:admin[[partnerRel.holderPerson:admin]]
role:partnerRel.holderPerson:referrer[[partnerRel.holderPerson:referrer]]
end
end
subgraph partnerRel.contact["`**partnerRel.contact**`"]
direction TB
style partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph partnerRel.contact:roles[ ]
style partnerRel.contact:roles fill:#99bcdb,stroke:white
role:partnerRel.contact:owner[[partnerRel.contact:owner]]
role:partnerRel.contact:admin[[partnerRel.contact:admin]]
role:partnerRel.contact:referrer[[partnerRel.contact:referrer]]
end
end
subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
direction TB
style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph partnerRel.anchorPerson:roles[ ]
style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
role:partnerRel.anchorPerson:owner[[partnerRel.anchorPerson:owner]]
role:partnerRel.anchorPerson:admin[[partnerRel.anchorPerson:admin]]
role:partnerRel.anchorPerson:referrer[[partnerRel.anchorPerson:referrer]]
end
end
subgraph partnerRel:roles[ ] subgraph partnerRel:roles[ ]
style partnerRel:roles fill:#99bcdb,stroke:white style partnerRel:roles fill:#99bcdb,stroke:white
role:partnerRel:owner[[partnerRel:owner]] role:partnerRel:OWNER[[partnerRel:OWNER]]
role:partnerRel:admin[[partnerRel:admin]] role:partnerRel:ADMIN[[partnerRel:ADMIN]]
role:partnerRel:agent[[partnerRel:agent]] role:partnerRel:AGENT[[partnerRel:AGENT]]
role:partnerRel:tenant[[partnerRel:tenant]] role:partnerRel:TENANT[[partnerRel:TENANT]]
end end
end end
@ -171,9 +94,9 @@ subgraph partnerRel.contact["`**partnerRel.contact**`"]
subgraph partnerRel.contact:roles[ ] subgraph partnerRel.contact:roles[ ]
style partnerRel.contact:roles fill:#99bcdb,stroke:white style partnerRel.contact:roles fill:#99bcdb,stroke:white
role:partnerRel.contact:owner[[partnerRel.contact:owner]] role:partnerRel.contact:OWNER[[partnerRel.contact:OWNER]]
role:partnerRel.contact:admin[[partnerRel.contact:admin]] role:partnerRel.contact:ADMIN[[partnerRel.contact:ADMIN]]
role:partnerRel.contact:referrer[[partnerRel.contact:referrer]] role:partnerRel.contact:REFERRER[[partnerRel.contact:REFERRER]]
end end
end end
@ -184,9 +107,9 @@ subgraph debitorRel.contact["`**debitorRel.contact**`"]
subgraph debitorRel.contact:roles[ ] subgraph debitorRel.contact:roles[ ]
style debitorRel.contact:roles fill:#99bcdb,stroke:white style debitorRel.contact:roles fill:#99bcdb,stroke:white
role:debitorRel.contact:owner[[debitorRel.contact:owner]] role:debitorRel.contact:OWNER[[debitorRel.contact:OWNER]]
role:debitorRel.contact:admin[[debitorRel.contact:admin]] role:debitorRel.contact:ADMIN[[debitorRel.contact:ADMIN]]
role:debitorRel.contact:referrer[[debitorRel.contact:referrer]] role:debitorRel.contact:REFERRER[[debitorRel.contact:REFERRER]]
end end
end end
@ -197,9 +120,9 @@ subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
subgraph partnerRel.anchorPerson:roles[ ] subgraph partnerRel.anchorPerson:roles[ ]
style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
role:partnerRel.anchorPerson:owner[[partnerRel.anchorPerson:owner]] role:partnerRel.anchorPerson:OWNER[[partnerRel.anchorPerson:OWNER]]
role:partnerRel.anchorPerson:admin[[partnerRel.anchorPerson:admin]] role:partnerRel.anchorPerson:ADMIN[[partnerRel.anchorPerson:ADMIN]]
role:partnerRel.anchorPerson:referrer[[partnerRel.anchorPerson:referrer]] role:partnerRel.anchorPerson:REFERRER[[partnerRel.anchorPerson:REFERRER]]
end end
end end
@ -210,66 +133,66 @@ subgraph refundBankAccount["`**refundBankAccount**`"]
subgraph refundBankAccount:roles[ ] subgraph refundBankAccount:roles[ ]
style refundBankAccount:roles fill:#99bcdb,stroke:white style refundBankAccount:roles fill:#99bcdb,stroke:white
role:refundBankAccount:owner[[refundBankAccount:owner]] role:refundBankAccount:OWNER[[refundBankAccount:OWNER]]
role:refundBankAccount:admin[[refundBankAccount:admin]] role:refundBankAccount:ADMIN[[refundBankAccount:ADMIN]]
role:refundBankAccount:referrer[[refundBankAccount:referrer]] role:refundBankAccount:REFERRER[[refundBankAccount:REFERRER]]
end end
end end
%% granting roles to roles %% granting roles to roles
role:global:admin -.-> role:debitorRel.anchorPerson:owner role:global:ADMIN -.-> role:debitorRel.anchorPerson:OWNER
role:debitorRel.anchorPerson:owner -.-> role:debitorRel.anchorPerson:admin role:debitorRel.anchorPerson:OWNER -.-> role:debitorRel.anchorPerson:ADMIN
role:debitorRel.anchorPerson:admin -.-> role:debitorRel.anchorPerson:referrer role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel.anchorPerson:REFERRER
role:global:admin -.-> role:debitorRel.holderPerson:owner role:global:ADMIN -.-> role:debitorRel.holderPerson:OWNER
role:debitorRel.holderPerson:owner -.-> role:debitorRel.holderPerson:admin role:debitorRel.holderPerson:OWNER -.-> role:debitorRel.holderPerson:ADMIN
role:debitorRel.holderPerson:admin -.-> role:debitorRel.holderPerson:referrer role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel.holderPerson:REFERRER
role:global:admin -.-> role:debitorRel.contact:owner role:global:ADMIN -.-> role:debitorRel.contact:OWNER
role:debitorRel.contact:owner -.-> role:debitorRel.contact:admin role:debitorRel.contact:OWNER -.-> role:debitorRel.contact:ADMIN
role:debitorRel.contact:admin -.-> role:debitorRel.contact:referrer role:debitorRel.contact:ADMIN -.-> role:debitorRel.contact:REFERRER
role:global:admin -.-> role:debitorRel:owner role:global:ADMIN -.-> role:debitorRel:OWNER
role:debitorRel:owner -.-> role:debitorRel:admin role:debitorRel:OWNER -.-> role:debitorRel:ADMIN
role:debitorRel.anchorPerson:admin -.-> role:debitorRel:admin role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel:ADMIN
role:debitorRel:admin -.-> role:debitorRel:agent role:debitorRel:ADMIN -.-> role:debitorRel:AGENT
role:debitorRel.holderPerson:admin -.-> role:debitorRel:agent role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:AGENT
role:debitorRel:agent -.-> role:debitorRel:tenant role:debitorRel:AGENT -.-> role:debitorRel:TENANT
role:debitorRel.holderPerson:admin -.-> role:debitorRel:tenant role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:TENANT
role:debitorRel.contact:admin -.-> role:debitorRel:tenant role:debitorRel.contact:ADMIN -.-> role:debitorRel:TENANT
role:debitorRel:tenant -.-> role:debitorRel.anchorPerson:referrer role:debitorRel:TENANT -.-> role:debitorRel.anchorPerson:REFERRER
role:debitorRel:tenant -.-> role:debitorRel.holderPerson:referrer role:debitorRel:TENANT -.-> role:debitorRel.holderPerson:REFERRER
role:debitorRel:tenant -.-> role:debitorRel.contact:referrer role:debitorRel:TENANT -.-> role:debitorRel.contact:REFERRER
role:global:admin -.-> role:refundBankAccount:owner role:global:ADMIN -.-> role:refundBankAccount:OWNER
role:refundBankAccount:owner -.-> role:refundBankAccount:admin role:refundBankAccount:OWNER -.-> role:refundBankAccount:ADMIN
role:refundBankAccount:admin -.-> role:refundBankAccount:referrer role:refundBankAccount:ADMIN -.-> role:refundBankAccount:REFERRER
role:refundBankAccount:admin ==> role:debitorRel:agent role:refundBankAccount:ADMIN ==> role:debitorRel:AGENT
role:debitorRel:agent ==> role:refundBankAccount:referrer role:debitorRel:AGENT ==> role:refundBankAccount:REFERRER
role:global:admin -.-> role:partnerRel.anchorPerson:owner role:global:ADMIN -.-> role:partnerRel.anchorPerson:OWNER
role:partnerRel.anchorPerson:owner -.-> role:partnerRel.anchorPerson:admin role:partnerRel.anchorPerson:OWNER -.-> role:partnerRel.anchorPerson:ADMIN
role:partnerRel.anchorPerson:admin -.-> role:partnerRel.anchorPerson:referrer role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel.anchorPerson:REFERRER
role:global:admin -.-> role:partnerRel.holderPerson:owner role:global:ADMIN -.-> role:partnerRel.holderPerson:OWNER
role:partnerRel.holderPerson:owner -.-> role:partnerRel.holderPerson:admin role:partnerRel.holderPerson:OWNER -.-> role:partnerRel.holderPerson:ADMIN
role:partnerRel.holderPerson:admin -.-> role:partnerRel.holderPerson:referrer role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel.holderPerson:REFERRER
role:global:admin -.-> role:partnerRel.contact:owner role:global:ADMIN -.-> role:partnerRel.contact:OWNER
role:partnerRel.contact:owner -.-> role:partnerRel.contact:admin role:partnerRel.contact:OWNER -.-> role:partnerRel.contact:ADMIN
role:partnerRel.contact:admin -.-> role:partnerRel.contact:referrer role:partnerRel.contact:ADMIN -.-> role:partnerRel.contact:REFERRER
role:global:admin -.-> role:partnerRel:owner role:global:ADMIN -.-> role:partnerRel:OWNER
role:partnerRel:owner -.-> role:partnerRel:admin role:partnerRel:OWNER -.-> role:partnerRel:ADMIN
role:partnerRel.anchorPerson:admin -.-> role:partnerRel:admin role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:ADMIN
role:partnerRel:admin -.-> role:partnerRel:agent role:partnerRel:ADMIN -.-> role:partnerRel:AGENT
role:partnerRel.holderPerson:admin -.-> role:partnerRel:agent role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT
role:partnerRel:agent -.-> role:partnerRel:tenant role:partnerRel:AGENT -.-> role:partnerRel:TENANT
role:partnerRel.holderPerson:admin -.-> role:partnerRel:tenant role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:TENANT
role:partnerRel.contact:admin -.-> role:partnerRel:tenant role:partnerRel.contact:ADMIN -.-> role:partnerRel:TENANT
role:partnerRel:tenant -.-> role:partnerRel.anchorPerson:referrer role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER
role:partnerRel:tenant -.-> role:partnerRel.holderPerson:referrer role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER
role:partnerRel:tenant -.-> role:partnerRel.contact:referrer role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER
role:partnerRel:admin ==> role:debitorRel:admin role:partnerRel:ADMIN ==> role:debitorRel:ADMIN
role:partnerRel:agent ==> role:debitorRel:agent role:partnerRel:AGENT ==> role:debitorRel:AGENT
role:debitorRel:agent ==> role:partnerRel:tenant role:debitorRel:AGENT ==> role:partnerRel:TENANT
%% granting permissions to roles %% granting permissions to roles
role:global:admin ==> perm:debitor:INSERT role:global:ADMIN ==> perm:debitor:INSERT
role:debitorRel:owner ==> perm:debitor:DELETE role:debitorRel:OWNER ==> perm:debitor:DELETE
role:debitorRel:admin ==> perm:debitor:UPDATE role:debitorRel:ADMIN ==> perm:debitor:UPDATE
role:debitorRel:tenant ==> perm:debitor:SELECT role:debitorRel:TENANT ==> perm:debitor:SELECT
``` ```

View File

@ -51,15 +51,15 @@ begin
SELECT * FROM hs_office_bankaccount WHERE uuid = NEW.refundBankAccountUuid INTO newRefundBankAccount; SELECT * FROM hs_office_bankaccount WHERE uuid = NEW.refundBankAccountUuid INTO newRefundBankAccount;
call grantRoleToRole(hsOfficeBankAccountReferrer(newRefundBankAccount), hsOfficeRelationAgent(newDebitorRel)); call grantRoleToRole(hsOfficeBankAccountREFERRER(newRefundBankAccount), hsOfficeRelationAGENT(newDebitorRel));
call grantRoleToRole(hsOfficeRelationAdmin(newDebitorRel), hsOfficeRelationAdmin(newPartnerRel)); call grantRoleToRole(hsOfficeRelationADMIN(newDebitorRel), hsOfficeRelationADMIN(newPartnerRel));
call grantRoleToRole(hsOfficeRelationAgent(newDebitorRel), hsOfficeBankAccountAdmin(newRefundBankAccount)); call grantRoleToRole(hsOfficeRelationAGENT(newDebitorRel), hsOfficeBankAccountADMIN(newRefundBankAccount));
call grantRoleToRole(hsOfficeRelationAgent(newDebitorRel), hsOfficeRelationAgent(newPartnerRel)); call grantRoleToRole(hsOfficeRelationAGENT(newDebitorRel), hsOfficeRelationAGENT(newPartnerRel));
call grantRoleToRole(hsOfficeRelationTenant(newPartnerRel), hsOfficeRelationAgent(newDebitorRel)); call grantRoleToRole(hsOfficeRelationTENANT(newPartnerRel), hsOfficeRelationAGENT(newDebitorRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationOwner(newDebitorRel)); call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationOWNER(newDebitorRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationTenant(newDebitorRel)); call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationTENANT(newDebitorRel));
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationAdmin(newDebitorRel)); call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationADMIN(newDebitorRel));
call leaveTriggerForObjectUuid(NEW.uuid); call leaveTriggerForObjectUuid(NEW.uuid);
end; $$; end; $$;
@ -143,7 +143,7 @@ do language plpgsql $$
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'hs_office_debitor'), createPermission(row.uuid, 'INSERT', 'hs_office_debitor'),
globalAdmin()); globalADMIN());
END LOOP; END LOOP;
END; END;
$$; $$;
@ -158,7 +158,7 @@ create or replace function hs_office_debitor_global_insert_tf()
begin begin
call grantPermissionToRole( call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'hs_office_debitor'), createPermission(NEW.uuid, 'INSERT', 'hs_office_debitor'),
globalAdmin()); globalADMIN());
return NEW; return NEW;
end; $$; end; $$;

View File

@ -23,7 +23,7 @@ declare
begin begin
idName := cleanIdentifier( forPartnerPersonName|| '-' || forBillingContactLabel); idName := cleanIdentifier( forPartnerPersonName|| '-' || forBillingContactLabel);
currentTask := 'creating debitor test-data ' || idName; currentTask := 'creating debitor test-data ' || idName;
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin'); call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
execute format('set local hsadminng.currentTask to %L', currentTask); execute format('set local hsadminng.currentTask to %L', currentTask);
select debitorRel.uuid select debitorRel.uuid

View File

@ -10,52 +10,13 @@ subgraph partnerRel["`**partnerRel**`"]
direction TB direction TB
style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph partnerRel.contact["`**partnerRel.contact**`"]
direction TB
style partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph partnerRel.contact:roles[ ]
style partnerRel.contact:roles fill:#99bcdb,stroke:white
role:partnerRel.contact:owner[[partnerRel.contact:owner]]
role:partnerRel.contact:admin[[partnerRel.contact:admin]]
role:partnerRel.contact:referrer[[partnerRel.contact:referrer]]
end
end
subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
direction TB
style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph partnerRel.anchorPerson:roles[ ]
style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
role:partnerRel.anchorPerson:owner[[partnerRel.anchorPerson:owner]]
role:partnerRel.anchorPerson:admin[[partnerRel.anchorPerson:admin]]
role:partnerRel.anchorPerson:referrer[[partnerRel.anchorPerson:referrer]]
end
end
subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"]
direction TB
style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
subgraph partnerRel.holderPerson:roles[ ]
style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
role:partnerRel.holderPerson:owner[[partnerRel.holderPerson:owner]]
role:partnerRel.holderPerson:admin[[partnerRel.holderPerson:admin]]
role:partnerRel.holderPerson:referrer[[partnerRel.holderPerson:referrer]]
end
end
subgraph partnerRel:roles[ ] subgraph partnerRel:roles[ ]
style partnerRel:roles fill:#99bcdb,stroke:white style partnerRel:roles fill:#99bcdb,stroke:white
role:partnerRel:owner[[partnerRel:owner]] role:partnerRel:OWNER[[partnerRel:OWNER]]
role:partnerRel:admin[[partnerRel:admin]] role:partnerRel:ADMIN[[partnerRel:ADMIN]]
role:partnerRel:agent[[partnerRel:agent]] role:partnerRel:AGENT[[partnerRel:AGENT]]
role:partnerRel:tenant[[partnerRel:tenant]] role:partnerRel:TENANT[[partnerRel:TENANT]]
end end
end end
@ -66,9 +27,9 @@ subgraph partnerRel.contact["`**partnerRel.contact**`"]
subgraph partnerRel.contact:roles[ ] subgraph partnerRel.contact:roles[ ]
style partnerRel.contact:roles fill:#99bcdb,stroke:white style partnerRel.contact:roles fill:#99bcdb,stroke:white
role:partnerRel.contact:owner[[partnerRel.contact:owner]] role:partnerRel.contact:OWNER[[partnerRel.contact:OWNER]]
role:partnerRel.contact:admin[[partnerRel.contact:admin]] role:partnerRel.contact:ADMIN[[partnerRel.contact:ADMIN]]
role:partnerRel.contact:referrer[[partnerRel.contact:referrer]] role:partnerRel.contact:REFERRER[[partnerRel.contact:REFERRER]]
end end
end end
@ -79,9 +40,9 @@ subgraph membership["`**membership**`"]
subgraph membership:roles[ ] subgraph membership:roles[ ]
style membership:roles fill:#dd4901,stroke:white style membership:roles fill:#dd4901,stroke:white
role:membership:owner[[membership:owner]] role:membership:OWNER[[membership:OWNER]]
role:membership:admin[[membership:admin]] role:membership:ADMIN[[membership:ADMIN]]
role:membership:referrer[[membership:referrer]] role:membership:REFERRER[[membership:REFERRER]]
end end
subgraph membership:permissions[ ] subgraph membership:permissions[ ]
@ -101,9 +62,9 @@ subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
subgraph partnerRel.anchorPerson:roles[ ] subgraph partnerRel.anchorPerson:roles[ ]
style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
role:partnerRel.anchorPerson:owner[[partnerRel.anchorPerson:owner]] role:partnerRel.anchorPerson:OWNER[[partnerRel.anchorPerson:OWNER]]
role:partnerRel.anchorPerson:admin[[partnerRel.anchorPerson:admin]] role:partnerRel.anchorPerson:ADMIN[[partnerRel.anchorPerson:ADMIN]]
role:partnerRel.anchorPerson:referrer[[partnerRel.anchorPerson:referrer]] role:partnerRel.anchorPerson:REFERRER[[partnerRel.anchorPerson:REFERRER]]
end end
end end
@ -114,46 +75,46 @@ subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"]
subgraph partnerRel.holderPerson:roles[ ] subgraph partnerRel.holderPerson:roles[ ]
style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
role:partnerRel.holderPerson:owner[[partnerRel.holderPerson:owner]] role:partnerRel.holderPerson:OWNER[[partnerRel.holderPerson:OWNER]]
role:partnerRel.holderPerson:admin[[partnerRel.holderPerson:admin]] role:partnerRel.holderPerson:ADMIN[[partnerRel.holderPerson:ADMIN]]
role:partnerRel.holderPerson:referrer[[partnerRel.holderPerson:referrer]] role:partnerRel.holderPerson:REFERRER[[partnerRel.holderPerson:REFERRER]]
end end
end end
%% granting roles to users %% granting roles to users
user:creator ==> role:membership:owner user:creator ==> role:membership:OWNER
%% granting roles to roles %% granting roles to roles
role:global:admin -.-> role:partnerRel.anchorPerson:owner role:global:ADMIN -.-> role:partnerRel.anchorPerson:OWNER
role:partnerRel.anchorPerson:owner -.-> role:partnerRel.anchorPerson:admin role:partnerRel.anchorPerson:OWNER -.-> role:partnerRel.anchorPerson:ADMIN
role:partnerRel.anchorPerson:admin -.-> role:partnerRel.anchorPerson:referrer role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel.anchorPerson:REFERRER
role:global:admin -.-> role:partnerRel.holderPerson:owner role:global:ADMIN -.-> role:partnerRel.holderPerson:OWNER
role:partnerRel.holderPerson:owner -.-> role:partnerRel.holderPerson:admin role:partnerRel.holderPerson:OWNER -.-> role:partnerRel.holderPerson:ADMIN
role:partnerRel.holderPerson:admin -.-> role:partnerRel.holderPerson:referrer role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel.holderPerson:REFERRER
role:global:admin -.-> role:partnerRel.contact:owner role:global:ADMIN -.-> role:partnerRel.contact:OWNER
role:partnerRel.contact:owner -.-> role:partnerRel.contact:admin role:partnerRel.contact:OWNER -.-> role:partnerRel.contact:ADMIN
role:partnerRel.contact:admin -.-> role:partnerRel.contact:referrer role:partnerRel.contact:ADMIN -.-> role:partnerRel.contact:REFERRER
role:global:admin -.-> role:partnerRel:owner role:global:ADMIN -.-> role:partnerRel:OWNER
role:partnerRel:owner -.-> role:partnerRel:admin role:partnerRel:OWNER -.-> role:partnerRel:ADMIN
role:partnerRel.anchorPerson:admin -.-> role:partnerRel:admin role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:ADMIN
role:partnerRel:admin -.-> role:partnerRel:agent role:partnerRel:ADMIN -.-> role:partnerRel:AGENT
role:partnerRel.holderPerson:admin -.-> role:partnerRel:agent role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT
role:partnerRel:agent -.-> role:partnerRel:tenant role:partnerRel:AGENT -.-> role:partnerRel:TENANT
role:partnerRel.holderPerson:admin -.-> role:partnerRel:tenant role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:TENANT
role:partnerRel.contact:admin -.-> role:partnerRel:tenant role:partnerRel.contact:ADMIN -.-> role:partnerRel:TENANT
role:partnerRel:tenant -.-> role:partnerRel.anchorPerson:referrer role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER
role:partnerRel:tenant -.-> role:partnerRel.holderPerson:referrer role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER
role:partnerRel:tenant -.-> role:partnerRel.contact:referrer role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER
role:partnerRel:admin ==> role:membership:owner role:partnerRel:ADMIN ==> role:membership:OWNER
role:membership:owner ==> role:membership:admin role:membership:OWNER ==> role:membership:ADMIN
role:partnerRel:agent ==> role:membership:admin role:partnerRel:AGENT ==> role:membership:ADMIN
role:membership:admin ==> role:membership:referrer role:membership:ADMIN ==> role:membership:REFERRER
role:membership:referrer ==> role:partnerRel:tenant role:membership:REFERRER ==> role:partnerRel:TENANT
%% granting permissions to roles %% granting permissions to roles
role:global:admin ==> perm:membership:INSERT role:global:ADMIN ==> perm:membership:INSERT
role:membership:owner ==> perm:membership:DELETE role:membership:OWNER ==> perm:membership:DELETE
role:membership:admin ==> perm:membership:UPDATE role:membership:ADMIN ==> perm:membership:UPDATE
role:membership:referrer ==> perm:membership:SELECT role:membership:REFERRER ==> perm:membership:SELECT
``` ```

View File

@ -44,25 +44,25 @@ begin
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeMembershipOwner(NEW), hsOfficeMembershipOWNER(NEW),
permissions => array['DELETE'], permissions => array['DELETE'],
incomingSuperRoles => array[hsOfficeRelationAdmin(newPartnerRel)], incomingSuperRoles => array[hsOfficeRelationADMIN(newPartnerRel)],
userUuids => array[currentUserUuid()] userUuids => array[currentUserUuid()]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeMembershipAdmin(NEW), hsOfficeMembershipADMIN(NEW),
permissions => array['UPDATE'], permissions => array['UPDATE'],
incomingSuperRoles => array[ incomingSuperRoles => array[
hsOfficeMembershipOwner(NEW), hsOfficeMembershipOWNER(NEW),
hsOfficeRelationAgent(newPartnerRel)] hsOfficeRelationAGENT(newPartnerRel)]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
hsOfficeMembershipReferrer(NEW), hsOfficeMembershipREFERRER(NEW),
permissions => array['SELECT'], permissions => array['SELECT'],
incomingSuperRoles => array[hsOfficeMembershipAdmin(NEW)], incomingSuperRoles => array[hsOfficeMembershipADMIN(NEW)],
outgoingSubRoles => array[hsOfficeRelationTenant(newPartnerRel)] outgoingSubRoles => array[hsOfficeRelationTENANT(newPartnerRel)]
); );
call leaveTriggerForObjectUuid(NEW.uuid); call leaveTriggerForObjectUuid(NEW.uuid);
@ -105,7 +105,7 @@ do language plpgsql $$
LOOP LOOP
call grantPermissionToRole( call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'hs_office_membership'), createPermission(row.uuid, 'INSERT', 'hs_office_membership'),
globalAdmin()); globalADMIN());
END LOOP; END LOOP;
END; END;
$$; $$;
@ -120,7 +120,7 @@ create or replace function hs_office_membership_global_insert_tf()
begin begin
call grantPermissionToRole( call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'hs_office_membership'), createPermission(NEW.uuid, 'INSERT', 'hs_office_membership'),
globalAdmin()); globalADMIN());
return NEW; return NEW;
end; $$; end; $$;

View File

@ -19,7 +19,7 @@ begin
currentTask := 'creating Membership test-data ' || currentTask := 'creating Membership test-data ' ||
'P-' || forPartnerNumber::text || 'P-' || forPartnerNumber::text ||
'M-...' || newMemberNumberSuffix; 'M-...' || newMemberNumberSuffix;
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin'); call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
execute format('set local hsadminng.currentTask to %L', currentTask); execute format('set local hsadminng.currentTask to %L', currentTask);
select partner.* from hs_office_partner partner select partner.* from hs_office_partner partner

View File

@ -59,13 +59,13 @@ class ContextIntegrationTests {
void defineWithoutCurrentUserButWithAssumedRoles() { void defineWithoutCurrentUserButWithAssumedRoles() {
// when // when
final var result = jpaAttempt.transacted(() -> final var result = jpaAttempt.transacted(() ->
context.define(null, "test_package#yyy00.admin") context.define(null, "test_package#yyy00:ADMIN")
); );
// then // then
result.assertExceptionWithRootCauseMessage( result.assertExceptionWithRootCauseMessage(
jakarta.persistence.PersistenceException.class, jakarta.persistence.PersistenceException.class,
"ERROR: [403] undefined has no permission to assume role test_package#yyy00.admin"); "ERROR: [403] undefined has no permission to assume role test_package#yyy00:ADMIN");
} }
@Test @Test
@ -85,7 +85,7 @@ class ContextIntegrationTests {
@Transactional @Transactional
void defineWithCurrentUserAndAssumedRoles() { void defineWithCurrentUserAndAssumedRoles() {
// given // given
context.define("superuser-alex@hostsharing.net", "test_customer#xxx.owner;test_customer#yyy.owner"); context.define("superuser-alex@hostsharing.net", "test_customer#xxx:OWNER;test_customer#yyy:OWNER");
// when // when
final var currentUser = context.getCurrentUser(); final var currentUser = context.getCurrentUser();
@ -93,7 +93,7 @@ class ContextIntegrationTests {
// then // then
assertThat(context.getAssumedRoles()) assertThat(context.getAssumedRoles())
.isEqualTo(Array.of("test_customer#xxx.owner", "test_customer#yyy.owner")); .isEqualTo(Array.of("test_customer#xxx:OWNER", "test_customer#yyy:OWNER"));
assertThat(context.currentSubjectsUuids()).hasSize(2); assertThat(context.currentSubjectsUuids()).hasSize(2);
} }
@ -101,12 +101,12 @@ class ContextIntegrationTests {
public void defineContextWithCurrentUserAndAssumeInaccessibleRole() { public void defineContextWithCurrentUserAndAssumeInaccessibleRole() {
// when // when
final var result = jpaAttempt.transacted(() -> final var result = jpaAttempt.transacted(() ->
context.define("customer-admin@xxx.example.com", "test_package#yyy00.admin") context.define("customer-admin@xxx.example.com", "test_package#yyy00:ADMIN")
); );
// then // then
result.assertExceptionWithRootCauseMessage( result.assertExceptionWithRootCauseMessage(
jakarta.persistence.PersistenceException.class, jakarta.persistence.PersistenceException.class,
"ERROR: [403] user customer-admin@xxx.example.com has no permission to assume role test_package#yyy00.admin"); "ERROR: [403] user customer-admin@xxx.example.com has no permission to assume role test_package#yyy00:ADMIN");
} }
} }

View File

@ -102,21 +102,21 @@ class HsOfficeBankAccountRepositoryIntegrationTest extends ContextBasedTestWithC
final var roles = rawRoleRepo.findAll(); final var roles = rawRoleRepo.findAll();
assertThat(distinctRoleNamesOf(roles)).containsExactlyInAnyOrder(Array.from( assertThat(distinctRoleNamesOf(roles)).containsExactlyInAnyOrder(Array.from(
initialRoleNames, initialRoleNames,
"hs_office_bankaccount#DE25500105176934832579.owner", "hs_office_bankaccount#DE25500105176934832579:OWNER",
"hs_office_bankaccount#DE25500105176934832579.admin", "hs_office_bankaccount#DE25500105176934832579:ADMIN",
"hs_office_bankaccount#DE25500105176934832579.referrer" "hs_office_bankaccount#DE25500105176934832579:REFERRER"
)); ));
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted( assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted(
initialGrantNames, initialGrantNames,
"{ grant perm DELETE on hs_office_bankaccount#DE25500105176934832579 to role hs_office_bankaccount#DE25500105176934832579.owner by system and assume }", "{ grant perm:hs_office_bankaccount#DE25500105176934832579:DELETE to role:hs_office_bankaccount#DE25500105176934832579:OWNER by system and assume }",
"{ grant role hs_office_bankaccount#DE25500105176934832579.owner to role global#global.admin by system and assume }", "{ grant role:hs_office_bankaccount#DE25500105176934832579:OWNER to role:global#global:ADMIN by system and assume }",
"{ grant role hs_office_bankaccount#DE25500105176934832579.owner to user selfregistered-user-drew@hostsharing.org by hs_office_bankaccount#DE25500105176934832579.owner and assume }", "{ grant role:hs_office_bankaccount#DE25500105176934832579:OWNER to user:selfregistered-user-drew@hostsharing.org by hs_office_bankaccount#DE25500105176934832579:OWNER and assume }",
"{ grant role hs_office_bankaccount#DE25500105176934832579.admin to role hs_office_bankaccount#DE25500105176934832579.owner by system and assume }", "{ grant role:hs_office_bankaccount#DE25500105176934832579:ADMIN to role:hs_office_bankaccount#DE25500105176934832579:OWNER by system and assume }",
"{ grant perm UPDATE on hs_office_bankaccount#DE25500105176934832579 to role hs_office_bankaccount#DE25500105176934832579.admin by system and assume }", "{ grant perm:hs_office_bankaccount#DE25500105176934832579:UPDATE to role:hs_office_bankaccount#DE25500105176934832579:ADMIN by system and assume }",
"{ grant perm SELECT on hs_office_bankaccount#DE25500105176934832579 to role hs_office_bankaccount#DE25500105176934832579.referrer by system and assume }", "{ grant perm:hs_office_bankaccount#DE25500105176934832579:SELECT to role:hs_office_bankaccount#DE25500105176934832579:REFERRER by system and assume }",
"{ grant role hs_office_bankaccount#DE25500105176934832579.referrer to role hs_office_bankaccount#DE25500105176934832579.admin by system and assume }", "{ grant role:hs_office_bankaccount#DE25500105176934832579:REFERRER to role:hs_office_bankaccount#DE25500105176934832579:ADMIN by system and assume }",
null null
)); ));
} }

View File

@ -103,20 +103,20 @@ class HsOfficeContactRepositoryIntegrationTest extends ContextBasedTestWithClean
final var roles = rawRoleRepo.findAll(); final var roles = rawRoleRepo.findAll();
assertThat(distinctRoleNamesOf(roles)).containsExactlyInAnyOrder(Array.from( assertThat(distinctRoleNamesOf(roles)).containsExactlyInAnyOrder(Array.from(
initialRoleNames, initialRoleNames,
"hs_office_contact#anothernewcontact.owner", "hs_office_contact#anothernewcontact:OWNER",
"hs_office_contact#anothernewcontact.admin", "hs_office_contact#anothernewcontact:ADMIN",
"hs_office_contact#anothernewcontact.referrer" "hs_office_contact#anothernewcontact:REFERRER"
)); ));
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted( assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted(
initialGrantNames, initialGrantNames,
"{ grant role hs_office_contact#anothernewcontact.owner to role global#global.admin by system and assume }", "{ grant role:hs_office_contact#anothernewcontact:OWNER to role:global#global:ADMIN by system and assume }",
"{ grant perm UPDATE on hs_office_contact#anothernewcontact to role hs_office_contact#anothernewcontact.admin by system and assume }", "{ grant perm:hs_office_contact#anothernewcontact:UPDATE to role:hs_office_contact#anothernewcontact:ADMIN by system and assume }",
"{ grant role hs_office_contact#anothernewcontact.owner to user selfregistered-user-drew@hostsharing.org by hs_office_contact#anothernewcontact.owner and assume }", "{ grant role:hs_office_contact#anothernewcontact:OWNER to user:selfregistered-user-drew@hostsharing.org by hs_office_contact#anothernewcontact:OWNER and assume }",
"{ grant perm DELETE on hs_office_contact#anothernewcontact to role hs_office_contact#anothernewcontact.owner by system and assume }", "{ grant perm:hs_office_contact#anothernewcontact:DELETE to role:hs_office_contact#anothernewcontact:OWNER by system and assume }",
"{ grant role hs_office_contact#anothernewcontact.admin to role hs_office_contact#anothernewcontact.owner by system and assume }", "{ grant role:hs_office_contact#anothernewcontact:ADMIN to role:hs_office_contact#anothernewcontact:OWNER by system and assume }",
"{ grant perm SELECT on hs_office_contact#anothernewcontact to role hs_office_contact#anothernewcontact.referrer by system and assume }", "{ grant perm:hs_office_contact#anothernewcontact:SELECT to role:hs_office_contact#anothernewcontact:REFERRER by system and assume }",
"{ grant role hs_office_contact#anothernewcontact.referrer to role hs_office_contact#anothernewcontact.admin by system and assume }" "{ grant role:hs_office_contact#anothernewcontact:REFERRER to role:hs_office_contact#anothernewcontact:ADMIN by system and assume }"
)); ));
} }

View File

@ -112,8 +112,8 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
.map(s -> s.replace("hs_office_", "")) .map(s -> s.replace("hs_office_", ""))
.containsExactlyInAnyOrder(Array.fromFormatted( .containsExactlyInAnyOrder(Array.fromFormatted(
initialGrantNames, initialGrantNames,
"{ grant perm SELECT on coopassetstransaction#temprefB to role membership#M-1000101.admin by system and assume }", "{ grant perm:coopassetstransaction#temprefB:SELECT to role:membership#M-1000101:ADMIN by system and assume }",
"{ grant perm UPDATE on coopassetstransaction#temprefB to role membership#M-1000101.admin by system and assume }", "{ grant perm:coopassetstransaction#temprefB:UPDATE to role:membership#M-1000101:ADMIN by system and assume }",
null)); null));
} }
@ -194,7 +194,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
@Test @Test
public void partnerPersonAdmin_canViewRelatedCoopAssetsTransactions() { public void partnerPersonAdmin_canViewRelatedCoopAssetsTransactions() {
// given: // given:
context("superuser-alex@hostsharing.net", "hs_office_person#FirstGmbH.admin"); context("superuser-alex@hostsharing.net", "hs_office_person#FirstGmbH:ADMIN");
// when: // when:
final var result = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange( final var result = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(

View File

@ -111,8 +111,8 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
.map(s -> s.replace("hs_office_", "")) .map(s -> s.replace("hs_office_", ""))
.containsExactlyInAnyOrder(Array.fromFormatted( .containsExactlyInAnyOrder(Array.fromFormatted(
initialGrantNames, initialGrantNames,
"{ grant perm SELECT on coopsharestransaction#temprefB to role membership#M-1000101.admin by system and assume }", "{ grant perm:coopsharestransaction#temprefB:SELECT to role:membership#M-1000101.admin by system and assume }",
"{ grant perm UPDATE on coopsharestransaction#temprefB to role membership#M-1000101.admin by system and assume }", "{ grant perm:coopsharestransaction#temprefB:UPDATE to role:membership#M-1000101.admin by system and assume }",
null)); null));
} }
@ -193,7 +193,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
@Test @Test
public void normalUser_canViewOnlyRelatedCoopSharesTransactions() { public void normalUser_canViewOnlyRelatedCoopSharesTransactions() {
// given: // given:
context("superuser-alex@hostsharing.net", "hs_office_membership#M-1000101.admin"); context("superuser-alex@hostsharing.net", "hs_office_membership#M-1000101:ADMIN");
// when: // when:
final var result = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange( final var result = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(

View File

@ -635,7 +635,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
.header("current-user", "superuser-alex@hostsharing.net") .header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", "hs_office_contact#fourthcontact.admin") .header("assumed-roles", "hs_office_contact#fourthcontact:ADMIN")
.contentType(ContentType.JSON) .contentType(ContentType.JSON)
.body(""" .body("""
{ {

View File

@ -172,44 +172,44 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
// then // then
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from( assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
initialRoleNames, initialRoleNames,
"hs_office_relation#FirstGmbH-with-DEBITOR-FourtheG.owner", "hs_office_relation#FirstGmbH-with-DEBITOR-FourtheG:OWNER",
"hs_office_relation#FirstGmbH-with-DEBITOR-FourtheG.admin", "hs_office_relation#FirstGmbH-with-DEBITOR-FourtheG:ADMIN",
"hs_office_relation#FirstGmbH-with-DEBITOR-FourtheG.agent", "hs_office_relation#FirstGmbH-with-DEBITOR-FourtheG:AGENT",
"hs_office_relation#FirstGmbH-with-DEBITOR-FourtheG.tenant")); "hs_office_relation#FirstGmbH-with-DEBITOR-FourtheG:TENANT"));
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())) assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll()))
.map(s -> s.replace("hs_office_", "")) .map(s -> s.replace("hs_office_", ""))
.containsExactlyInAnyOrder(Array.fromFormatted( .containsExactlyInAnyOrder(Array.fromFormatted(
initialGrantNames, initialGrantNames,
"{ grant perm INSERT into sepamandate with relation#FirstGmbH-with-DEBITOR-FourtheG to role relation#FirstGmbH-with-DEBITOR-FourtheG.admin by system and assume }", "{ grant perm:relation#FirstGmbH-with-DEBITOR-FourtheG:INSERT>sepamandate to role:relation#FirstGmbH-with-DEBITOR-FourtheG:ADMIN by system and assume }",
// owner // owner
"{ grant perm DELETE on debitor#D-1000122 to role relation#FirstGmbH-with-DEBITOR-FourtheG.owner by system and assume }", "{ grant perm:debitor#D-1000122:DELETE to role:relation#FirstGmbH-with-DEBITOR-FourtheG:OWNER by system and assume }",
"{ grant perm DELETE on relation#FirstGmbH-with-DEBITOR-FourtheG to role relation#FirstGmbH-with-DEBITOR-FourtheG.owner by system and assume }", "{ grant perm:relation#FirstGmbH-with-DEBITOR-FourtheG:DELETE to role:relation#FirstGmbH-with-DEBITOR-FourtheG:OWNER by system and assume }",
"{ grant role relation#FirstGmbH-with-DEBITOR-FourtheG.owner to role global#global.admin by system and assume }", "{ grant role:relation#FirstGmbH-with-DEBITOR-FourtheG:OWNER to role:global#global:ADMIN by system and assume }",
"{ grant role relation#FirstGmbH-with-DEBITOR-FourtheG.owner to user superuser-alex@hostsharing.net by relation#FirstGmbH-with-DEBITOR-FourtheG.owner and assume }", "{ grant role:relation#FirstGmbH-with-DEBITOR-FourtheG:OWNER to user:superuser-alex@hostsharing.net by relation#FirstGmbH-with-DEBITOR-FourtheG:OWNER and assume }",
// admin // admin
"{ grant perm UPDATE on debitor#D-1000122 to role relation#FirstGmbH-with-DEBITOR-FourtheG.admin by system and assume }", "{ grant perm:debitor#D-1000122:UPDATE to role:relation#FirstGmbH-with-DEBITOR-FourtheG:ADMIN by system and assume }",
"{ grant perm UPDATE on relation#FirstGmbH-with-DEBITOR-FourtheG to role relation#FirstGmbH-with-DEBITOR-FourtheG.admin by system and assume }", "{ grant perm:relation#FirstGmbH-with-DEBITOR-FourtheG:UPDATE to role:relation#FirstGmbH-with-DEBITOR-FourtheG:ADMIN by system and assume }",
"{ grant role relation#FirstGmbH-with-DEBITOR-FourtheG.admin to role relation#FirstGmbH-with-DEBITOR-FourtheG.owner by system and assume }", "{ grant role:relation#FirstGmbH-with-DEBITOR-FourtheG:ADMIN to role:relation#FirstGmbH-with-DEBITOR-FourtheG:OWNER by system and assume }",
"{ grant role relation#FirstGmbH-with-DEBITOR-FourtheG.admin to role person#FirstGmbH.admin by system and assume }", "{ grant role:relation#FirstGmbH-with-DEBITOR-FourtheG:ADMIN to role:person#FirstGmbH:ADMIN by system and assume }",
"{ grant role relation#FirstGmbH-with-DEBITOR-FourtheG.admin to role relation#HostsharingeG-with-PARTNER-FirstGmbH.admin by system and assume }", "{ grant role:relation#FirstGmbH-with-DEBITOR-FourtheG:ADMIN to role:relation#HostsharingeG-with-PARTNER-FirstGmbH:ADMIN by system and assume }",
// agent // agent
"{ grant role relation#FirstGmbH-with-DEBITOR-FourtheG.agent to role person#FourtheG.admin by system and assume }", "{ grant role:relation#FirstGmbH-with-DEBITOR-FourtheG:AGENT to role:person#FourtheG:ADMIN by system and assume }",
"{ grant role relation#FirstGmbH-with-DEBITOR-FourtheG.agent to role relation#FirstGmbH-with-DEBITOR-FourtheG.admin by system and assume }", "{ grant role:relation#FirstGmbH-with-DEBITOR-FourtheG:AGENT to role:relation#FirstGmbH-with-DEBITOR-FourtheG:ADMIN by system and assume }",
"{ grant role relation#FirstGmbH-with-DEBITOR-FourtheG.agent to role relation#HostsharingeG-with-PARTNER-FirstGmbH.agent by system and assume }", "{ grant role:relation#FirstGmbH-with-DEBITOR-FourtheG:AGENT to role:relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT by system and assume }",
// tenant // tenant
"{ grant perm SELECT on debitor#D-1000122 to role relation#FirstGmbH-with-DEBITOR-FourtheG.tenant by system and assume }", "{ grant perm:debitor#D-1000122:SELECT to role:relation#FirstGmbH-with-DEBITOR-FourtheG:TENANT by system and assume }",
"{ grant perm SELECT on relation#FirstGmbH-with-DEBITOR-FourtheG to role relation#FirstGmbH-with-DEBITOR-FourtheG.tenant by system and assume }", "{ grant perm:relation#FirstGmbH-with-DEBITOR-FourtheG:SELECT to role:relation#FirstGmbH-with-DEBITOR-FourtheG:TENANT by system and assume }",
"{ grant role relation#HostsharingeG-with-PARTNER-FirstGmbH.tenant to role relation#FirstGmbH-with-DEBITOR-FourtheG.agent by system and assume }", "{ grant role:relation#HostsharingeG-with-PARTNER-FirstGmbH:TENANT to role:relation#FirstGmbH-with-DEBITOR-FourtheG:AGENT by system and assume }",
"{ grant role contact#fourthcontact.referrer to role relation#FirstGmbH-with-DEBITOR-FourtheG.tenant by system and assume }", "{ grant role:contact#fourthcontact:REFERRER to role:relation#FirstGmbH-with-DEBITOR-FourtheG:TENANT by system and assume }",
"{ grant role person#FirstGmbH.referrer to role relation#FirstGmbH-with-DEBITOR-FourtheG.tenant by system and assume }", "{ grant role:person#FirstGmbH:REFERRER to role:relation#FirstGmbH-with-DEBITOR-FourtheG:TENANT by system and assume }",
"{ grant role person#FourtheG.referrer to role relation#FirstGmbH-with-DEBITOR-FourtheG.tenant by system and assume }", "{ grant role:person#FourtheG:REFERRER to role:relation#FirstGmbH-with-DEBITOR-FourtheG:TENANT by system and assume }",
"{ grant role relation#FirstGmbH-with-DEBITOR-FourtheG.tenant to role contact#fourthcontact.admin by system and assume }", "{ grant role:relation#FirstGmbH-with-DEBITOR-FourtheG:TENANT to role:contact#fourthcontact:ADMIN by system and assume }",
"{ grant role relation#FirstGmbH-with-DEBITOR-FourtheG.tenant to role person#FourtheG.admin by system and assume }", "{ grant role:relation#FirstGmbH-with-DEBITOR-FourtheG:TENANT to role:person#FourtheG:ADMIN by system and assume }",
"{ grant role relation#FirstGmbH-with-DEBITOR-FourtheG.tenant to role relation#FirstGmbH-with-DEBITOR-FourtheG.agent by system and assume }", "{ grant role:relation#FirstGmbH-with-DEBITOR-FourtheG:TENANT to role:relation#FirstGmbH-with-DEBITOR-FourtheG:AGENT by system and assume }",
null)); null));
} }
@ -243,9 +243,9 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
@ParameterizedTest @ParameterizedTest
@Disabled // TODO: reactivate once partner.person + partner.contact are removed @Disabled // TODO: reactivate once partner.person + partner.contact are removed
@ValueSource(strings = { @ValueSource(strings = {
"hs_office_partner#10001:FirstGmbH-firstcontact.admin", "hs_office_partner#10001:FirstGmbH-firstcontact:ADMIN",
"hs_office_person#FirstGmbH.admin", "hs_office_person#FirstGmbH:ADMIN",
"hs_office_contact#firstcontact.admin", "hs_office_contact#firstcontact:ADMIN",
}) })
public void relatedPersonAdmin_canViewRelatedDebitors(final String assumedRole) { public void relatedPersonAdmin_canViewRelatedDebitors(final String assumedRole) {
// given: // given:
@ -317,7 +317,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
givenDebitor, givenDebitor,
"hs_office_relation#FourtheG-with-DEBITOR-FourtheG.admin", true); "hs_office_relation#FourtheG-with-DEBITOR-FourtheG:ADMIN", true);
final var givenNewPartnerPerson = one(personRepo.findPersonByOptionalNameLike("First")); final var givenNewPartnerPerson = one(personRepo.findPersonByOptionalNameLike("First"));
final var givenNewBillingPerson = one(personRepo.findPersonByOptionalNameLike("Firby")); final var givenNewBillingPerson = one(personRepo.findPersonByOptionalNameLike("Firby"));
final var givenNewContact = one(contactRepo.findContactByOptionalLabelLike("sixth contact")); final var givenNewContact = one(contactRepo.findContactByOptionalLabelLike("sixth contact"));
@ -346,31 +346,31 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
result.assertSuccessful(); result.assertSuccessful();
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"global#global.admin", true); "global#global:ADMIN", true);
// ... partner role was reassigned: // ... partner role was reassigned:
assertThatDebitorIsNotVisibleForUserWithRole( assertThatDebitorIsNotVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_relation#FourtheG-with-DEBITOR-FourtheG.admin"); "hs_office_relation#FourtheG-with-DEBITOR-FourtheG:ADMIN");
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_relation#FirstGmbH-with-DEBITOR-FirbySusan.agent", true); "hs_office_relation#FirstGmbH-with-DEBITOR-FirbySusan:AGENT", true);
// ... contact role was reassigned: // ... contact role was reassigned:
assertThatDebitorIsNotVisibleForUserWithRole( assertThatDebitorIsNotVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_contact#fifthcontact.admin"); "hs_office_contact#fifthcontact:ADMIN");
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_contact#sixthcontact.admin", false); "hs_office_contact#sixthcontact:ADMIN", false);
// ... bank-account role was reassigned: // ... bank-account role was reassigned:
assertThatDebitorIsNotVisibleForUserWithRole( assertThatDebitorIsNotVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_bankaccount#DE02200505501015871393.admin"); "hs_office_bankaccount#DE02200505501015871393:ADMIN");
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_bankaccount#DE02120300000000202051.admin", true); "hs_office_bankaccount#DE02120300000000202051:ADMIN", true);
} }
@Test @Test
@ -380,7 +380,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", null, "fig"); final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", null, "fig");
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
givenDebitor, givenDebitor,
"hs_office_relation#FourtheG-with-DEBITOR-FourtheG.admin", true); "hs_office_relation#FourtheG-with-DEBITOR-FourtheG:ADMIN", true);
assertThatDebitorActuallyInDatabase(givenDebitor, true); assertThatDebitorActuallyInDatabase(givenDebitor, true);
final var givenNewBankAccount = one(bankAccountRepo.findByOptionalHolderLike("first")); final var givenNewBankAccount = one(bankAccountRepo.findByOptionalHolderLike("first"));
@ -395,12 +395,12 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
result.assertSuccessful(); result.assertSuccessful();
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"global#global.admin", true); "global#global:ADMIN", true);
// ... bank-account role was assigned: // ... bank-account role was assigned:
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_bankaccount#DE02120300000000202051.admin", true); "hs_office_bankaccount#DE02120300000000202051:ADMIN", true);
} }
@Test @Test
@ -410,7 +410,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth", "fih"); final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth", "fih");
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
givenDebitor, givenDebitor,
"hs_office_relation#HostsharingeG-with-PARTNER-FourtheG.agent", true); "hs_office_relation#HostsharingeG-with-PARTNER-FourtheG:AGENT", true);
assertThatDebitorActuallyInDatabase(givenDebitor, true); assertThatDebitorActuallyInDatabase(givenDebitor, true);
// when // when
@ -424,12 +424,12 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
result.assertSuccessful(); result.assertSuccessful();
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"global#global.admin", true); "global#global:ADMIN", true);
// ... bank-account role was removed from previous bank-account admin: // ... bank-account role was removed from previous bank-account admin:
assertThatDebitorIsNotVisibleForUserWithRole( assertThatDebitorIsNotVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_bankaccount#DE02200505501015871393.admin"); "hs_office_bankaccount#DE02200505501015871393:ADMIN");
} }
@Test @Test
@ -439,12 +439,12 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eighth", "Fourth", "eig"); final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eighth", "Fourth", "eig");
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
givenDebitor, givenDebitor,
"hs_office_relation#HostsharingeG-with-PARTNER-FourtheG.agent", true); "hs_office_relation#HostsharingeG-with-PARTNER-FourtheG:AGENT", true);
assertThatDebitorActuallyInDatabase(givenDebitor, true); assertThatDebitorActuallyInDatabase(givenDebitor, true);
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_relation#HostsharingeG-with-PARTNER-FourtheG.agent"); context("superuser-alex@hostsharing.net", "hs_office_relation#HostsharingeG-with-PARTNER-FourtheG:AGENT");
givenDebitor.setVatId("NEW-VAT-ID"); givenDebitor.setVatId("NEW-VAT-ID");
return toCleanup(debitorRepo.save(givenDebitor)); return toCleanup(debitorRepo.save(givenDebitor));
}); });
@ -462,11 +462,11 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
assertThatDebitorActuallyInDatabase(givenDebitor, true); assertThatDebitorActuallyInDatabase(givenDebitor, true);
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
givenDebitor, givenDebitor,
"hs_office_contact#ninthcontact.admin", false); "hs_office_contact#ninthcontact:ADMIN", false);
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_contact#ninthcontact.admin"); context("superuser-alex@hostsharing.net", "hs_office_contact#ninthcontact:ADMIN");
givenDebitor.setVatId("NEW-VAT-ID"); givenDebitor.setVatId("NEW-VAT-ID");
return toCleanup(debitorRepo.save(givenDebitor)); return toCleanup(debitorRepo.save(givenDebitor));
}); });
@ -545,7 +545,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_relation#FourtheG-with-DEBITOR-FourtheG.admin"); context("superuser-alex@hostsharing.net", "hs_office_relation#FourtheG-with-DEBITOR-FourtheG:ADMIN");
assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent(); assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent();
debitorRepo.deleteByUuid(givenDebitor.getUuid()); debitorRepo.deleteByUuid(givenDebitor.getUuid());

View File

@ -269,7 +269,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
.header("current-user", "superuser-alex@hostsharing.net") .header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", "hs_office_relation#HostsharingeG-with-PARTNER-ThirdOHG.agent") .header("assumed-roles", "hs_office_relation#HostsharingeG-with-PARTNER-ThirdOHG:AGENT")
.port(port) .port(port)
.when() .when()
.get("http://localhost/api/hs/office/memberships/" + givenMembershipUuid) .get("http://localhost/api/hs/office/memberships/" + givenMembershipUuid)
@ -338,7 +338,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
void partnerRelAgent_canPatchValidityOfRelatedMembership() { void partnerRelAgent_canPatchValidityOfRelatedMembership() {
// given // given
final var givenPartnerAgent = "hs_office_relation#HostsharingeG-with-PARTNER-FirstGmbH.agent"; final var givenPartnerAgent = "hs_office_relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT";
context.define("superuser-alex@hostsharing.net", givenPartnerAgent); context.define("superuser-alex@hostsharing.net", givenPartnerAgent);
final var givenMembership = givenSomeTemporaryMembershipBessler("First"); final var givenMembership = givenSomeTemporaryMembershipBessler("First");
@ -401,7 +401,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
.header("current-user", "superuser-alex@hostsharing.net") .header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", "hs_office_relation#HostsharingeG-with-PARTNER-FirstGmbH.agent") .header("assumed-roles", "hs_office_relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT")
.port(port) .port(port)
.when() .when()
.delete("http://localhost/api/hs/office/memberships/" + givenMembership.getUuid()) .delete("http://localhost/api/hs/office/memberships/" + givenMembership.getUuid())

View File

@ -91,7 +91,6 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var initialRoleNames = distinctRoleNamesOf(rawRoleRepo.findAll()); final var initialRoleNames = distinctRoleNamesOf(rawRoleRepo.findAll());
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll()).stream() final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll()).stream()
.map(s -> s.replace("GmbH-firstcontact", ""))
.map(s -> s.replace("hs_office_", "")) .map(s -> s.replace("hs_office_", ""))
.toList(); .toList();
@ -111,31 +110,30 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
final var all = rawRoleRepo.findAll(); final var all = rawRoleRepo.findAll();
assertThat(distinctRoleNamesOf(all)).containsExactlyInAnyOrder(Array.from( assertThat(distinctRoleNamesOf(all)).containsExactlyInAnyOrder(Array.from(
initialRoleNames, initialRoleNames,
"hs_office_membership#M-1000117.admin", "hs_office_membership#M-1000117:ADMIN",
"hs_office_membership#M-1000117.owner", "hs_office_membership#M-1000117:OWNER",
"hs_office_membership#M-1000117.referrer")); "hs_office_membership#M-1000117:REFERRER"));
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())) assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll()))
.map(s -> s.replace("GmbH-firstcontact", ""))
.map(s -> s.replace("hs_office_", "")) .map(s -> s.replace("hs_office_", ""))
.containsExactlyInAnyOrder(Array.fromFormatted( .containsExactlyInAnyOrder(Array.fromFormatted(
initialGrantNames, initialGrantNames,
// owner // owner
"{ grant perm DELETE on membership#M-1000117 to role membership#M-1000117.owner by system and assume }", "{ grant perm:membership#M-1000117:DELETE to role:membership#M-1000117:OWNER by system and assume }",
// admin // admin
"{ grant perm UPDATE on membership#M-1000117 to role membership#M-1000117.admin by system and assume }", "{ grant perm:membership#M-1000117:UPDATE to role:membership#M-1000117:ADMIN by system and assume }",
"{ grant role membership#M-1000117.admin to role membership#M-1000117.owner by system and assume }", "{ grant role:membership#M-1000117:ADMIN to role:membership#M-1000117:OWNER by system and assume }",
"{ grant role membership#M-1000117.owner to role relation#HostsharingeG-with-PARTNER-FirstGmbH.admin by system and assume }", "{ grant role:membership#M-1000117:OWNER to role:relation#HostsharingeG-with-PARTNER-FirstGmbH:ADMIN by system and assume }",
"{ grant role membership#M-1000117.owner to user superuser-alex@hostsharing.net by membership#M-1000117.owner and assume }", "{ grant role:membership#M-1000117:OWNER to user:superuser-alex@hostsharing.net by membership#M-1000117:OWNER and assume }",
// agent // agent
"{ grant role membership#M-1000117.admin to role relation#HostsharingeG-with-PARTNER-FirstGmbH.agent by system and assume }", "{ grant role:membership#M-1000117:ADMIN to role:relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT by system and assume }",
// referrer // referrer
"{ grant perm SELECT on membership#M-1000117 to role membership#M-1000117.referrer by system and assume }", "{ grant perm:membership#M-1000117:SELECT to role:membership#M-1000117:REFERRER by system and assume }",
"{ grant role membership#M-1000117.referrer to role membership#M-1000117.admin by system and assume }", "{ grant role:membership#M-1000117:REFERRER to role:membership#M-1000117:ADMIN by system and assume }",
"{ grant role relation#HostsharingeG-with-PARTNER-FirstGmbH.tenant to role membership#M-1000117.referrer by system and assume }", "{ grant role:relation#HostsharingeG-with-PARTNER-FirstGmbH:TENANT to role:membership#M-1000117:REFERRER by system and assume }",
null)); null));
} }
@ -230,13 +228,13 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership); assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
assertThatMembershipIsVisibleForRole( assertThatMembershipIsVisibleForRole(
givenMembership, givenMembership,
"hs_office_membership#M-1000113.referrer"); "hs_office_membership#M-1000113:REFERRER");
final var newValidityEnd = LocalDate.now(); final var newValidityEnd = LocalDate.now();
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
// TODO: we should test with debitor- and partner-admin as well // TODO: we should test with debitor- and partner-admin as well
context("superuser-alex@hostsharing.net", "hs_office_membership#M-1000113.referrer"); context("superuser-alex@hostsharing.net", "hs_office_membership#M-1000113:REFERRER");
givenMembership.setValidity( givenMembership.setValidity(
Range.closedOpen(givenMembership.getValidity().lower(), newValidityEnd)); Range.closedOpen(givenMembership.getValidity().lower(), newValidityEnd));
return membershipRepo.save(givenMembership); return membershipRepo.save(givenMembership);
@ -294,7 +292,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_relation#HostsharingeG-with-PARTNER-FirstGmbH.agent"); context("superuser-alex@hostsharing.net", "hs_office_relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT");
assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent(); assertThat(membershipRepo.findByUuid(givenMembership.getUuid())).isPresent();
membershipRepo.deleteByUuid(givenMembership.getUuid()); membershipRepo.deleteByUuid(givenMembership.getUuid());

View File

@ -106,7 +106,7 @@ import static org.assertj.core.api.Fail.fail;
@Tag("import") @Tag("import")
@DataJpaTest(properties = { @DataJpaTest(properties = {
"spring.datasource.url=${HSADMINNG_POSTGRES_JDBC_URL:jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers}", "spring.datasource.url=${HSADMINNG_POSTGRES_JDBC_URL:jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers}",
"spring.datasource.username=${HSADMINNG_POSTGRES_ADMIN_USERNAME:admin}", "spring.datasource.username=${HSADMINNG_POSTGRES_ADMIN_USERNAME:ADMIN}",
"spring.datasource.password=${HSADMINNG_POSTGRES_ADMIN_PASSWORD:password}", "spring.datasource.password=${HSADMINNG_POSTGRES_ADMIN_PASSWORD:password}",
"hsadminng.superuser=${HSADMINNG_SUPERUSER:superuser-alex@hostsharing.net}" "hsadminng.superuser=${HSADMINNG_SUPERUSER:superuser-alex@hostsharing.net}"
}) })

View File

@ -132,52 +132,52 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
// then // then
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from( assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
initialRoleNames, initialRoleNames,
"hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler.owner", "hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:OWNER",
"hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler.admin", "hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:ADMIN",
"hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler.agent", "hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:AGENT",
"hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler.tenant")); "hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:TENANT"));
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())) assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll()))
.map(s -> s.replace("ErbenBesslerMelBessler", "EBess")) .map(s -> s.replace("ErbenBesslerMelBessler", "EBess"))
.map(s -> s.replace("fourthcontact", "4th")) .map(s -> s.replace("fourthcontact", "4th"))
.map(s -> s.replace("hs_office_", "")) .map(s -> s.replace("hs_office_", ""))
.containsExactlyInAnyOrder(distinct(fromFormatted( .containsExactlyInAnyOrder(distinct(fromFormatted(
initialGrantNames, initialGrantNames,
"{ grant perm INSERT into sepamandate with relation#HostsharingeG-with-PARTNER-EBess to role relation#HostsharingeG-with-PARTNER-EBess.admin by system and assume }", "{ grant perm:relation#HostsharingeG-with-PARTNER-EBess:INSERT>sepamandate to role:relation#HostsharingeG-with-PARTNER-EBess:ADMIN by system and assume }",
// permissions on partner // permissions on partner
"{ grant perm DELETE on partner#P-20032 to role relation#HostsharingeG-with-PARTNER-EBess.admin by system and assume }", "{ grant perm:partner#P-20032:DELETE to role:relation#HostsharingeG-with-PARTNER-EBess:ADMIN by system and assume }",
"{ grant perm UPDATE on partner#P-20032 to role relation#HostsharingeG-with-PARTNER-EBess.agent by system and assume }", "{ grant perm:partner#P-20032:UPDATE to role:relation#HostsharingeG-with-PARTNER-EBess:AGENT by system and assume }",
"{ grant perm SELECT on partner#P-20032 to role relation#HostsharingeG-with-PARTNER-EBess.tenant by system and assume }", "{ grant perm:partner#P-20032:SELECT to role:relation#HostsharingeG-with-PARTNER-EBess:TENANT by system and assume }",
// permissions on partner-details // permissions on partner-details
"{ grant perm DELETE on partner_details#P-20032-details to role relation#HostsharingeG-with-PARTNER-EBess.admin by system and assume }", "{ grant perm:partner_details#P-20032:DELETE to role:relation#HostsharingeG-with-PARTNER-EBess:ADMIN by system and assume }",
"{ grant perm UPDATE on partner_details#P-20032-details to role relation#HostsharingeG-with-PARTNER-EBess.agent by system and assume }", "{ grant perm:partner_details#P-20032:UPDATE to role:relation#HostsharingeG-with-PARTNER-EBess:AGENT by system and assume }",
"{ grant perm SELECT on partner_details#P-20032-details to role relation#HostsharingeG-with-PARTNER-EBess.agent by system and assume }", "{ grant perm:partner_details#P-20032:SELECT to role:relation#HostsharingeG-with-PARTNER-EBess:AGENT by system and assume }",
// permissions on partner-relation // permissions on partner-relation
"{ grant perm DELETE on relation#HostsharingeG-with-PARTNER-EBess to role relation#HostsharingeG-with-PARTNER-EBess.owner by system and assume }", "{ grant perm:relation#HostsharingeG-with-PARTNER-EBess:DELETE to role:relation#HostsharingeG-with-PARTNER-EBess:OWNER by system and assume }",
"{ grant perm UPDATE on relation#HostsharingeG-with-PARTNER-EBess to role relation#HostsharingeG-with-PARTNER-EBess.admin by system and assume }", "{ grant perm:relation#HostsharingeG-with-PARTNER-EBess:UPDATE to role:relation#HostsharingeG-with-PARTNER-EBess:ADMIN by system and assume }",
"{ grant perm SELECT on relation#HostsharingeG-with-PARTNER-EBess to role relation#HostsharingeG-with-PARTNER-EBess.tenant by system and assume }", "{ grant perm:relation#HostsharingeG-with-PARTNER-EBess:SELECT to role:relation#HostsharingeG-with-PARTNER-EBess:TENANT by system and assume }",
// relation owner // relation owner
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.owner to role global#global.admin by system and assume }", "{ grant role:relation#HostsharingeG-with-PARTNER-EBess:OWNER to role:global#global:ADMIN by system and assume }",
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.owner to user superuser-alex@hostsharing.net by relation#HostsharingeG-with-PARTNER-EBess.owner and assume }", "{ grant role:relation#HostsharingeG-with-PARTNER-EBess:OWNER to user:superuser-alex@hostsharing.net by relation#HostsharingeG-with-PARTNER-EBess:OWNER and assume }",
// relation admin // relation admin
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.admin to role relation#HostsharingeG-with-PARTNER-EBess.owner by system and assume }", "{ grant role:relation#HostsharingeG-with-PARTNER-EBess:ADMIN to role:relation#HostsharingeG-with-PARTNER-EBess:OWNER by system and assume }",
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.admin to role person#HostsharingeG.admin by system and assume }", "{ grant role:relation#HostsharingeG-with-PARTNER-EBess:ADMIN to role:person#HostsharingeG:ADMIN by system and assume }",
// relation agent // relation agent
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.agent to role person#EBess.admin by system and assume }", "{ grant role:relation#HostsharingeG-with-PARTNER-EBess:AGENT to role:person#EBess:ADMIN by system and assume }",
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.agent to role relation#HostsharingeG-with-PARTNER-EBess.admin by system and assume }", "{ grant role:relation#HostsharingeG-with-PARTNER-EBess:AGENT to role:relation#HostsharingeG-with-PARTNER-EBess:ADMIN by system and assume }",
// relation tenant // relation tenant
"{ grant role contact#4th.referrer to role relation#HostsharingeG-with-PARTNER-EBess.tenant by system and assume }", "{ grant role:contact#4th:REFERRER to role:relation#HostsharingeG-with-PARTNER-EBess:TENANT by system and assume }",
"{ grant role person#EBess.referrer to role relation#HostsharingeG-with-PARTNER-EBess.tenant by system and assume }", "{ grant role:person#EBess:REFERRER to role:relation#HostsharingeG-with-PARTNER-EBess:TENANT by system and assume }",
"{ grant role person#HostsharingeG.referrer to role relation#HostsharingeG-with-PARTNER-EBess.tenant by system and assume }", "{ grant role:person#HostsharingeG:REFERRER to role:relation#HostsharingeG-with-PARTNER-EBess:TENANT by system and assume }",
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.tenant to role contact#4th.admin by system and assume }", "{ grant role:relation#HostsharingeG-with-PARTNER-EBess:TENANT to role:contact#4th:ADMIN by system and assume }",
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.tenant to role person#EBess.admin by system and assume }", "{ grant role:relation#HostsharingeG-with-PARTNER-EBess:TENANT to role:person#EBess:ADMIN by system and assume }",
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.tenant to role relation#HostsharingeG-with-PARTNER-EBess.agent by system and assume }", "{ grant role:relation#HostsharingeG-with-PARTNER-EBess:TENANT to role:relation#HostsharingeG-with-PARTNER-EBess:AGENT by system and assume }",
null))); null)));
} }
@ -266,7 +266,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
final var givenPartner = givenSomeTemporaryHostsharingPartner(20036, "Erben Bessler", "fifth contact"); final var givenPartner = givenSomeTemporaryHostsharingPartner(20036, "Erben Bessler", "fifth contact");
assertThatPartnerIsVisibleForUserWithRole( assertThatPartnerIsVisibleForUserWithRole(
givenPartner, givenPartner,
"hs_office_person#ErbenBesslerMelBessler.admin"); "hs_office_person#ErbenBesslerMelBessler:ADMIN");
assertThatPartnerActuallyInDatabase(givenPartner); assertThatPartnerActuallyInDatabase(givenPartner);
// when // when
@ -281,13 +281,13 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
assertThatPartnerIsVisibleForUserWithRole( assertThatPartnerIsVisibleForUserWithRole(
givenPartner, givenPartner,
"global#global.admin"); "global#global:ADMIN");
assertThatPartnerIsVisibleForUserWithRole( assertThatPartnerIsVisibleForUserWithRole(
givenPartner, givenPartner,
"hs_office_person#ThirdOHG.admin"); "hs_office_person#ThirdOHG:ADMIN");
assertThatPartnerIsNotVisibleForUserWithRole( assertThatPartnerIsNotVisibleForUserWithRole(
givenPartner, givenPartner,
"hs_office_person#ErbenBesslerMelBessler.admin"); "hs_office_person#ErbenBesslerMelBessler:ADMIN");
} }
@Test @Test
@ -297,13 +297,13 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
final var givenPartner = givenSomeTemporaryHostsharingPartner(20037, "Erben Bessler", "ninth"); final var givenPartner = givenSomeTemporaryHostsharingPartner(20037, "Erben Bessler", "ninth");
assertThatPartnerIsVisibleForUserWithRole( assertThatPartnerIsVisibleForUserWithRole(
givenPartner, givenPartner,
"hs_office_person#ErbenBesslerMelBessler.admin"); "hs_office_person#ErbenBesslerMelBessler:ADMIN");
assertThatPartnerActuallyInDatabase(givenPartner); assertThatPartnerActuallyInDatabase(givenPartner);
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", context("superuser-alex@hostsharing.net",
"hs_office_person#ErbenBesslerMelBessler.admin"); "hs_office_person#ErbenBesslerMelBessler:ADMIN");
givenPartner.getDetails().setBirthName("new birthname"); givenPartner.getDetails().setBirthName("new birthname");
return partnerRepo.save(givenPartner); return partnerRepo.save(givenPartner);
}); });
@ -319,20 +319,20 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
final var givenPartner = givenSomeTemporaryHostsharingPartner(20037, "Erben Bessler", "ninth"); final var givenPartner = givenSomeTemporaryHostsharingPartner(20037, "Erben Bessler", "ninth");
assertThatPartnerIsVisibleForUserWithRole( assertThatPartnerIsVisibleForUserWithRole(
givenPartner, givenPartner,
"hs_office_person#ErbenBesslerMelBessler.admin"); "hs_office_person#ErbenBesslerMelBessler:ADMIN");
assertThatPartnerActuallyInDatabase(givenPartner); assertThatPartnerActuallyInDatabase(givenPartner);
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", context("superuser-alex@hostsharing.net",
"hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler.tenant"); "hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:TENANT");
givenPartner.getDetails().setBirthName("new birthname"); givenPartner.getDetails().setBirthName("new birthname");
return partnerRepo.save(givenPartner); return partnerRepo.save(givenPartner);
}); });
// then // then
result.assertExceptionWithRootCauseMessage(JpaSystemException.class, result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
"[403] insert into hs_office_partner_details not allowed for current subjects {hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler.tenant}"); "[403] insert into hs_office_partner_details not allowed for current subjects {hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:TENANT}");
} }
private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) { private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) {

View File

@ -102,23 +102,23 @@ class HsOfficePersonRepositoryIntegrationTest extends ContextBasedTestWithCleanu
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder( assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(
Array.from( Array.from(
initialRoleNames, initialRoleNames,
"hs_office_person#anothernewperson.owner", "hs_office_person#anothernewperson:OWNER",
"hs_office_person#anothernewperson.admin", "hs_office_person#anothernewperson:ADMIN",
"hs_office_person#anothernewperson.referrer" "hs_office_person#anothernewperson:REFERRER"
)); ));
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder( assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(
Array.from( Array.fromFormatted(
initialGrantNames, initialGrantNames,
"{ grant perm INSERT into hs_office_relation with hs_office_person#anothernewperson to role hs_office_person#anothernewperson.admin by system and assume }", "{ grant perm:hs_office_person#anothernewperson:INSERT>hs_office_relation to role:hs_office_person#anothernewperson:ADMIN by system and assume }",
"{ grant role hs_office_person#anothernewperson.owner to user selfregistered-user-drew@hostsharing.org by hs_office_person#anothernewperson.owner and assume }", "{ grant role:hs_office_person#anothernewperson:OWNER to user:selfregistered-user-drew@hostsharing.org by hs_office_person#anothernewperson:OWNER and assume }",
"{ grant role hs_office_person#anothernewperson.owner to role global#global.admin by system and assume }", "{ grant role:hs_office_person#anothernewperson:OWNER to role:global#global:ADMIN by system and assume }",
"{ grant perm UPDATE on hs_office_person#anothernewperson to role hs_office_person#anothernewperson.admin by system and assume }", "{ grant perm:hs_office_person#anothernewperson:UPDATE to role:hs_office_person#anothernewperson:ADMIN by system and assume }",
"{ grant perm DELETE on hs_office_person#anothernewperson to role hs_office_person#anothernewperson.owner by system and assume }", "{ grant perm:hs_office_person#anothernewperson:DELETE to role:hs_office_person#anothernewperson:OWNER by system and assume }",
"{ grant role hs_office_person#anothernewperson.admin to role hs_office_person#anothernewperson.owner by system and assume }", "{ grant role:hs_office_person#anothernewperson:ADMIN to role:hs_office_person#anothernewperson:OWNER by system and assume }",
"{ grant perm SELECT on hs_office_person#anothernewperson to role hs_office_person#anothernewperson.referrer by system and assume }", "{ grant perm:hs_office_person#anothernewperson:SELECT to role:hs_office_person#anothernewperson:REFERRER by system and assume }",
"{ grant role hs_office_person#anothernewperson.referrer to role hs_office_person#anothernewperson.admin by system and assume }" "{ grant role:hs_office_person#anothernewperson:REFERRER to role:hs_office_person#anothernewperson:ADMIN by system and assume }"
)); ));
} }

View File

@ -125,35 +125,35 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
// then // then
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from( assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
initialRoleNames, initialRoleNames,
"hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.owner", "hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:OWNER",
"hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.admin", "hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN",
"hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.agent", "hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:AGENT",
"hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant")); "hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:TENANT"));
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted( assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted(
initialGrantNames, initialGrantNames,
// TODO: this grant should only be created for DEBITOR-Relationships, thus the RBAC DSL needs to support conditional grants // TODO: this grant should only be created for DEBITOR-Relationships, thus the RBAC DSL needs to support conditional grants
"{ grant perm INSERT into hs_office_sepamandate with hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert to role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.admin by system and assume }", "{ grant perm:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:INSERT>hs_office_sepamandate to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN by system and assume }",
"{ grant perm DELETE on hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert to role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.owner by system and assume }", "{ grant perm:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:DELETE to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:OWNER by system and assume }",
"{ grant role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.owner to role global#global.admin by system and assume }", "{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:OWNER to role:global#global:ADMIN by system and assume }",
"{ grant role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.owner to user superuser-alex@hostsharing.net by hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.owner and assume }", "{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:OWNER to user:superuser-alex@hostsharing.net by hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:OWNER and assume }",
"{ grant perm UPDATE on hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert to role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.admin by system and assume }", "{ grant perm:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:UPDATE to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN by system and assume }",
"{ grant role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.admin to role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.owner by system and assume }", "{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:OWNER by system and assume }",
"{ grant role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.admin to role hs_office_person#ErbenBesslerMelBessler.admin by system and assume }", "{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN to role:hs_office_person#ErbenBesslerMelBessler:ADMIN by system and assume }",
"{ grant role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.agent to role hs_office_person#BesslerBert.admin by system and assume }", "{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:AGENT to role:hs_office_person#BesslerBert:ADMIN by system and assume }",
"{ grant role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.agent to role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.admin by system and assume }", "{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:AGENT to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN by system and assume }",
"{ grant perm SELECT on hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert to role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant by system and assume }", "{ grant perm:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:SELECT to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:TENANT by system and assume }",
"{ grant role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant to role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.agent by system and assume }", "{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:TENANT to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:AGENT by system and assume }",
"{ grant role hs_office_person#BesslerBert.referrer to role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant by system and assume }", "{ grant role:hs_office_person#BesslerBert:REFERRER to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:TENANT by system and assume }",
"{ grant role hs_office_person#ErbenBesslerMelBessler.referrer to role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant by system and assume }", "{ grant role:hs_office_person#ErbenBesslerMelBessler:REFERRER to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:TENANT by system and assume }",
"{ grant role hs_office_contact#fourthcontact.referrer to role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant by system and assume }", "{ grant role:hs_office_contact#fourthcontact:REFERRER to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:TENANT by system and assume }",
// REPRESENTATIVE holder person -> (represented) anchor person // REPRESENTATIVE holder person -> (represented) anchor person
"{ grant role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant to role hs_office_contact#fourthcontact.admin by system and assume }", "{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:TENANT to role:hs_office_contact#fourthcontact:ADMIN by system and assume }",
"{ grant role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant to role hs_office_person#BesslerBert.admin by system and assume }", "{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:TENANT to role:hs_office_person#BesslerBert:ADMIN by system and assume }",
null) null)
); );
@ -219,7 +219,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
"Bert", "fifth contact"); "Bert", "fifth contact");
assertThatRelationIsVisibleForUserWithRole( assertThatRelationIsVisibleForUserWithRole(
givenRelation, givenRelation,
"hs_office_person#ErbenBesslerMelBessler.admin"); "hs_office_person#ErbenBesslerMelBessler:ADMIN");
assertThatRelationActuallyInDatabase(givenRelation); assertThatRelationActuallyInDatabase(givenRelation);
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var givenContact = contactRepo.findContactByOptionalLabelLike("sixth contact").stream().findFirst().orElseThrow(); final var givenContact = contactRepo.findContactByOptionalLabelLike("sixth contact").stream().findFirst().orElseThrow();
@ -236,14 +236,14 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
assertThat(result.returnedValue().getContact().getLabel()).isEqualTo("sixth contact"); assertThat(result.returnedValue().getContact().getLabel()).isEqualTo("sixth contact");
assertThatRelationIsVisibleForUserWithRole( assertThatRelationIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"global#global.admin"); "global#global:ADMIN");
assertThatRelationIsVisibleForUserWithRole( assertThatRelationIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_contact#sixthcontact.admin"); "hs_office_contact#sixthcontact:ADMIN");
assertThatRelationIsNotVisibleForUserWithRole( assertThatRelationIsNotVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_contact#fifthcontact.admin"); "hs_office_contact#fifthcontact:ADMIN");
relationRepo.deleteByUuid(givenRelation.getUuid()); relationRepo.deleteByUuid(givenRelation.getUuid());
} }
@ -256,12 +256,12 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
"Anita", "eighth"); "Anita", "eighth");
assertThatRelationIsVisibleForUserWithRole( assertThatRelationIsVisibleForUserWithRole(
givenRelation, givenRelation,
"hs_office_person#BesslerAnita.admin"); "hs_office_person#BesslerAnita:ADMIN");
assertThatRelationActuallyInDatabase(givenRelation); assertThatRelationActuallyInDatabase(givenRelation);
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_person#BesslerAnita.admin"); context("superuser-alex@hostsharing.net", "hs_office_person#BesslerAnita:ADMIN");
givenRelation.setContact(null); givenRelation.setContact(null);
return relationRepo.save(givenRelation); return relationRepo.save(givenRelation);
}); });
@ -279,12 +279,12 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
"Anita", "ninth"); "Anita", "ninth");
assertThatRelationIsVisibleForUserWithRole( assertThatRelationIsVisibleForUserWithRole(
givenRelation, givenRelation,
"hs_office_contact#ninthcontact.admin"); "hs_office_contact#ninthcontact:ADMIN");
assertThatRelationActuallyInDatabase(givenRelation); assertThatRelationActuallyInDatabase(givenRelation);
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_contact#ninthcontact.admin"); context("superuser-alex@hostsharing.net", "hs_office_contact#ninthcontact:ADMIN");
givenRelation.setContact(null); // TODO givenRelation.setContact(null); // TODO
return relationRepo.save(givenRelation); return relationRepo.save(givenRelation);
}); });

View File

@ -117,35 +117,35 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTestWithC
final var all = rawRoleRepo.findAll(); final var all = rawRoleRepo.findAll();
assertThat(distinctRoleNamesOf(all)).containsExactlyInAnyOrder(Array.from( assertThat(distinctRoleNamesOf(all)).containsExactlyInAnyOrder(Array.from(
initialRoleNames, initialRoleNames,
"hs_office_sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).admin", "hs_office_sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):ADMIN",
"hs_office_sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).agent", "hs_office_sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):AGENT",
"hs_office_sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).owner", "hs_office_sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):OWNER",
"hs_office_sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).referrer")); "hs_office_sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):REFERRER"));
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())) assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll()))
.map(s -> s.replace("hs_office_", "")) .map(s -> s.replace("hs_office_", ""))
.containsExactlyInAnyOrder(fromFormatted( .containsExactlyInAnyOrder(fromFormatted(
initialGrantNames, initialGrantNames,
// owner // owner
"{ grant perm DELETE on sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01) to role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).owner by system and assume }", "{ grant perm:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):DELETE to role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):OWNER by system and assume }",
"{ grant role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).owner to role global#global.admin by system and assume }", "{ grant role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):OWNER to role:global#global:ADMIN by system and assume }",
"{ grant role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).owner to user superuser-alex@hostsharing.net by sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).owner and assume }", "{ grant role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):OWNER to user:superuser-alex@hostsharing.net by sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):OWNER and assume }",
// admin // admin
"{ grant perm UPDATE on sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01) to role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).admin by system and assume }", "{ grant perm:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):UPDATE to role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):ADMIN by system and assume }",
"{ grant role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).admin to role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).owner by system and assume }", "{ grant role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):ADMIN to role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):OWNER by system and assume }",
// agent // agent
"{ grant role bankaccount#DE02600501010002034304.referrer to role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).agent by system and assume }", "{ grant role:bankaccount#DE02600501010002034304:REFERRER to role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):AGENT by system and assume }",
"{ grant role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).agent to role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).admin by system and assume }", "{ grant role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):AGENT to role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):ADMIN by system and assume }",
"{ grant role relation#FirstGmbH-with-DEBITOR-FirstGmbH.agent to role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).agent by system and assume }", "{ grant role:relation#FirstGmbH-with-DEBITOR-FirstGmbH:AGENT to role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):AGENT by system and assume }",
// referrer // referrer
"{ grant perm SELECT on sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01) to role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).referrer by system and assume }", "{ grant perm:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):SELECT to role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):REFERRER by system and assume }",
"{ grant role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).referrer to role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).agent by system and assume }", "{ grant role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):REFERRER to role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):AGENT by system and assume }",
"{ grant role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).referrer to role bankaccount#DE02600501010002034304.admin by system and assume }", "{ grant role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):REFERRER to role:bankaccount#DE02600501010002034304:ADMIN by system and assume }",
"{ grant role relation#FirstGmbH-with-DEBITOR-FirstGmbH.tenant to role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).referrer by system and assume }", "{ grant role:relation#FirstGmbH-with-DEBITOR-FirstGmbH:TENANT to role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):REFERRER by system and assume }",
"{ grant role sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01).referrer to role relation#FirstGmbH-with-DEBITOR-FirstGmbH.agent by system and assume }", "{ grant role:sepamandate#DE02600501010002034304-[2020-01-01,2023-01-01):REFERRER to role:relation#FirstGmbH-with-DEBITOR-FirstGmbH:AGENT by system and assume }",
null)); null));
} }
@ -233,7 +233,7 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTestWithC
final var givenSepaMandate = givenSomeTemporarySepaMandate("DE02600501010002034304"); final var givenSepaMandate = givenSomeTemporarySepaMandate("DE02600501010002034304");
assertThatSepaMandateIsVisibleForUserWithRole( assertThatSepaMandateIsVisibleForUserWithRole(
givenSepaMandate, givenSepaMandate,
"hs_office_bankaccount#DE02600501010002034304.admin"); "hs_office_bankaccount#DE02600501010002034304:ADMIN");
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
@ -262,13 +262,13 @@ class HsOfficeSepaMandateRepositoryIntegrationTest extends ContextBasedTestWithC
final var givenSepaMandate = givenSomeTemporarySepaMandate("DE02300606010002474689"); final var givenSepaMandate = givenSomeTemporarySepaMandate("DE02300606010002474689");
assertThatSepaMandateIsVisibleForUserWithRole( assertThatSepaMandateIsVisibleForUserWithRole(
givenSepaMandate, givenSepaMandate,
"hs_office_bankaccount#DE02300606010002474689.admin"); "hs_office_bankaccount#DE02300606010002474689:ADMIN");
assertThatSepaMandateActuallyInDatabase(givenSepaMandate); assertThatSepaMandateActuallyInDatabase(givenSepaMandate);
final var newValidityEnd = LocalDate.now(); final var newValidityEnd = LocalDate.now();
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_bankaccount#DE02300606010002474689.admin"); context("superuser-alex@hostsharing.net", "hs_office_bankaccount#DE02300606010002474689:ADMIN");
givenSepaMandate.setValidity(Range.closedOpen( givenSepaMandate.setValidity(Range.closedOpen(
givenSepaMandate.getValidity().lower(), newValidityEnd)); givenSepaMandate.getValidity().lower(), newValidityEnd));

View File

@ -6,7 +6,7 @@ import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantEntity;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository; import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService; import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleEntity; import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRvEntity;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository; import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import net.hostsharing.test.JpaAttempt; import net.hostsharing.test.JpaAttempt;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -255,7 +255,7 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net", null); context.define("superuser-alex@hostsharing.net", null);
return rbacRoleRepo.findAll().stream() return rbacRoleRepo.findAll().stream()
.map(RbacRoleEntity::getRoleName) .map(RbacRoleRvEntity::getRoleName)
.collect(toSet()); .collect(toSet());
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();
} }

View File

@ -5,7 +5,7 @@ import io.restassured.http.ContentType;
import io.restassured.response.ValidatableResponse; import io.restassured.response.ValidatableResponse;
import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.context.ContextBasedTest; import net.hostsharing.hsadminng.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleEntity; import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRvEntity;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository; import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserEntity; import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserEntity;
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserRepository; import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserRepository;
@ -74,37 +74,37 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
.body("", hasItem( .body("", hasItem(
allOf( allOf(
// TODO: should there be a grantedByRole or just a grantedByTrigger? // TODO: should there be a grantedByRole or just a grantedByTrigger?
hasEntry("grantedByRoleIdName", "test_customer#xxx.owner"), hasEntry("grantedByRoleIdName", "test_customer#xxx:OWNER"),
hasEntry("grantedRoleIdName", "test_customer#xxx.admin"), hasEntry("grantedRoleIdName", "test_customer#xxx:ADMIN"),
hasEntry("granteeUserName", "customer-admin@xxx.example.com") hasEntry("granteeUserName", "customer-admin@xxx.example.com")
) )
)) ))
.body("", hasItem( .body("", hasItem(
allOf( allOf(
// TODO: should there be a grantedByRole or just a grantedByTrigger? // TODO: should there be a grantedByRole or just a grantedByTrigger?
hasEntry("grantedByRoleIdName", "test_customer#yyy.owner"), hasEntry("grantedByRoleIdName", "test_customer#yyy:OWNER"),
hasEntry("grantedRoleIdName", "test_customer#yyy.admin"), hasEntry("grantedRoleIdName", "test_customer#yyy:ADMIN"),
hasEntry("granteeUserName", "customer-admin@yyy.example.com") hasEntry("granteeUserName", "customer-admin@yyy.example.com")
) )
)) ))
.body("", hasItem( .body("", hasItem(
allOf( allOf(
hasEntry("grantedByRoleIdName", "global#global.admin"), hasEntry("grantedByRoleIdName", "global#global:ADMIN"),
hasEntry("grantedRoleIdName", "global#global.admin"), hasEntry("grantedRoleIdName", "global#global:ADMIN"),
hasEntry("granteeUserName", "superuser-fran@hostsharing.net") hasEntry("granteeUserName", "superuser-fran@hostsharing.net")
) )
)) ))
.body("", hasItem( .body("", hasItem(
allOf( allOf(
hasEntry("grantedByRoleIdName", "test_customer#xxx.admin"), hasEntry("grantedByRoleIdName", "test_customer#xxx:ADMIN"),
hasEntry("grantedRoleIdName", "test_package#xxx00.admin"), hasEntry("grantedRoleIdName", "test_package#xxx00:ADMIN"),
hasEntry("granteeUserName", "pac-admin-xxx00@xxx.example.com") hasEntry("granteeUserName", "pac-admin-xxx00@xxx.example.com")
) )
)) ))
.body("", hasItem( .body("", hasItem(
allOf( allOf(
hasEntry("grantedByRoleIdName", "test_customer#zzz.admin"), hasEntry("grantedByRoleIdName", "test_customer#zzz:ADMIN"),
hasEntry("grantedRoleIdName", "test_package#zzz02.admin"), hasEntry("grantedRoleIdName", "test_package#zzz02:ADMIN"),
hasEntry("granteeUserName", "pac-admin-zzz02@zzz.example.com") hasEntry("granteeUserName", "pac-admin-zzz02@zzz.example.com")
) )
)) ))
@ -118,7 +118,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
.header("current-user", "superuser-alex@hostsharing.net") .header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_package#yyy00.admin") .header("assumed-roles", "test_package#yyy00:ADMIN")
.port(port) .port(port)
.when() .when()
.get("http://localhost/api/rbac/grants") .get("http://localhost/api/rbac/grants")
@ -127,8 +127,8 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
.contentType("application/json") .contentType("application/json")
.body("", hasItem( .body("", hasItem(
allOf( allOf(
hasEntry("grantedByRoleIdName", "test_customer#yyy.admin"), hasEntry("grantedByRoleIdName", "test_customer#yyy:ADMIN"),
hasEntry("grantedRoleIdName", "test_package#yyy00.admin"), hasEntry("grantedRoleIdName", "test_package#yyy00:ADMIN"),
hasEntry("granteeUserName", "pac-admin-yyy00@yyy.example.com") hasEntry("granteeUserName", "pac-admin-yyy00@yyy.example.com")
) )
)) ))
@ -150,13 +150,13 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
.contentType("application/json") .contentType("application/json")
.body("", hasItem( .body("", hasItem(
allOf( allOf(
hasEntry("grantedByRoleIdName", "test_customer#yyy.admin"), hasEntry("grantedByRoleIdName", "test_customer#yyy:ADMIN"),
hasEntry("grantedRoleIdName", "test_package#yyy00.admin"), hasEntry("grantedRoleIdName", "test_package#yyy00:ADMIN"),
hasEntry("granteeUserName", "pac-admin-yyy00@yyy.example.com") hasEntry("granteeUserName", "pac-admin-yyy00@yyy.example.com")
) )
)) ))
.body("[0].grantedByRoleIdName", is("test_customer#yyy.admin")) .body("[0].grantedByRoleIdName", is("test_customer#yyy:ADMIN"))
.body("[0].grantedRoleIdName", is("test_package#yyy00.admin")) .body("[0].grantedRoleIdName", is("test_package#yyy00:ADMIN"))
.body("[0].granteeUserName", is("pac-admin-yyy00@yyy.example.com")); .body("[0].granteeUserName", is("pac-admin-yyy00@yyy.example.com"));
// @formatter:on // @formatter:on
} }
@ -171,7 +171,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given // given
final var givenCurrentUserAsPackageAdmin = new Subject("customer-admin@xxx.example.com"); final var givenCurrentUserAsPackageAdmin = new Subject("customer-admin@xxx.example.com");
final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com"); final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com");
final var givenGrantedRole = findRbacRoleByName("test_package#xxx00.admin"); final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN");
// when // when
final var grant = givenCurrentUserAsPackageAdmin.getGrantById() final var grant = givenCurrentUserAsPackageAdmin.getGrantById()
@ -180,8 +180,8 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// then // then
grant.assertThat() grant.assertThat()
.statusCode(200) .statusCode(200)
.body("grantedByRoleIdName", is("test_customer#xxx.admin")) .body("grantedByRoleIdName", is("test_customer#xxx:ADMIN"))
.body("grantedRoleIdName", is("test_package#xxx00.admin")) .body("grantedRoleIdName", is("test_package#xxx00:ADMIN"))
.body("granteeUserName", is("pac-admin-xxx00@xxx.example.com")); .body("granteeUserName", is("pac-admin-xxx00@xxx.example.com"));
} }
@ -191,7 +191,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given // given
final var givenCurrentUserAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com"); final var givenCurrentUserAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com");
final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com"); final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com");
final var givenGrantedRole = findRbacRoleByName("test_package#xxx00.admin"); final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN");
// when // when
final var grant = givenCurrentUserAsPackageAdmin.getGrantById() final var grant = givenCurrentUserAsPackageAdmin.getGrantById()
@ -200,8 +200,8 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// then // then
grant.assertThat() grant.assertThat()
.statusCode(200) .statusCode(200)
.body("grantedByRoleIdName", is("test_customer#xxx.admin")) .body("grantedByRoleIdName", is("test_customer#xxx:ADMIN"))
.body("grantedRoleIdName", is("test_package#xxx00.admin")) .body("grantedRoleIdName", is("test_package#xxx00:ADMIN"))
.body("granteeUserName", is("pac-admin-xxx00@xxx.example.com")); .body("granteeUserName", is("pac-admin-xxx00@xxx.example.com"));
} }
@ -211,9 +211,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given // given
final var givenCurrentUserAsPackageAdmin = new Subject( final var givenCurrentUserAsPackageAdmin = new Subject(
"pac-admin-xxx00@xxx.example.com", "pac-admin-xxx00@xxx.example.com",
"test_package#xxx00.admin"); "test_package#xxx00:ADMIN");
final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com"); final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com");
final var givenGrantedRole = findRbacRoleByName("test_package#xxx00.admin"); final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN");
// when // when
final var grant = givenCurrentUserAsPackageAdmin.getGrantById() final var grant = givenCurrentUserAsPackageAdmin.getGrantById()
@ -222,8 +222,8 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// then // then
grant.assertThat() grant.assertThat()
.statusCode(200) .statusCode(200)
.body("grantedByRoleIdName", is("test_customer#xxx.admin")) .body("grantedByRoleIdName", is("test_customer#xxx:ADMIN"))
.body("grantedRoleIdName", is("test_package#xxx00.admin")) .body("grantedRoleIdName", is("test_package#xxx00:ADMIN"))
.body("granteeUserName", is("pac-admin-xxx00@xxx.example.com")); .body("granteeUserName", is("pac-admin-xxx00@xxx.example.com"));
} }
@ -234,9 +234,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given // given
final var givenCurrentUserAsPackageAdmin = new Subject( final var givenCurrentUserAsPackageAdmin = new Subject(
"pac-admin-xxx00@xxx.example.com", "pac-admin-xxx00@xxx.example.com",
"test_package#xxx00.tenant"); "test_package#xxx00:TENANT");
final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com"); final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com");
final var givenGrantedRole = findRbacRoleByName("test_package#xxx00.admin"); final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN");
final var grant = givenCurrentUserAsPackageAdmin.getGrantById() final var grant = givenCurrentUserAsPackageAdmin.getGrantById()
.forGrantedRole(givenGrantedRole).toGranteeUser(givenGranteeUser); .forGrantedRole(givenGrantedRole).toGranteeUser(givenGranteeUser);
@ -255,10 +255,10 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given // given
final var givenNewUser = createRBacUser(); final var givenNewUser = createRBacUser();
final var givenRoleToGrant = "test_package#xxx00.admin"; final var givenRoleToGrant = "test_package#xxx00:ADMIN";
final var givenCurrentUserAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant); final var givenCurrentUserAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant);
final var givenOwnPackageAdminRole = final var givenOwnPackageAdminRole =
findRbacRoleByName(givenCurrentUserAsPackageAdmin.assumedRole); getRbacRoleByName(givenCurrentUserAsPackageAdmin.assumedRole);
// when // when
final var response = givenCurrentUserAsPackageAdmin final var response = givenCurrentUserAsPackageAdmin
@ -268,15 +268,15 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// then // then
response.assertThat() response.assertThat()
.statusCode(201) .statusCode(201)
.body("grantedByRoleIdName", is("test_package#xxx00.admin")) .body("grantedByRoleIdName", is("test_package#xxx00:ADMIN"))
.body("assumed", is(true)) .body("assumed", is(true))
.body("grantedRoleIdName", is("test_package#xxx00.admin")) .body("grantedRoleIdName", is("test_package#xxx00:ADMIN"))
.body("granteeUserName", is(givenNewUser.getName())); .body("granteeUserName", is(givenNewUser.getName()));
assertThat(findAllGrantsOf(givenCurrentUserAsPackageAdmin)) assertThat(findAllGrantsOf(givenCurrentUserAsPackageAdmin))
.extracting(RbacGrantEntity::toDisplay) .extracting(RbacGrantEntity::toDisplay)
.contains("{ grant role " + givenOwnPackageAdminRole.getRoleName() + .contains("{ grant role:" + givenOwnPackageAdminRole.getRoleName() +
" to user " + givenNewUser.getName() + " to user:" + givenNewUser.getName() +
" by role " + givenRoleToGrant + " and assume }"); " by role:" + givenRoleToGrant + " and assume }");
} }
@Test @Test
@ -285,9 +285,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given // given
final var givenNewUser = createRBacUser(); final var givenNewUser = createRBacUser();
final var givenRoleToGrant = "test_package#xxx00.admin"; final var givenRoleToGrant = "test_package#xxx00:ADMIN";
final var givenCurrentUserAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant); final var givenCurrentUserAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant);
final var givenAlienPackageAdminRole = findRbacRoleByName("test_package#yyy00.admin"); final var givenAlienPackageAdminRole = getRbacRoleByName("test_package#yyy00:ADMIN");
// when // when
final var result = givenCurrentUserAsPackageAdmin final var result = givenCurrentUserAsPackageAdmin
@ -298,7 +298,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
result.assertThat() result.assertThat()
.statusCode(403) .statusCode(403)
.body("message", containsString("Access to granted role")) .body("message", containsString("Access to granted role"))
.body("message", containsString("forbidden for test_package#xxx00.admin")); .body("message", containsString("forbidden for test_package#xxx00:ADMIN"));
assertThat(findAllGrantsOf(givenCurrentUserAsPackageAdmin)) assertThat(findAllGrantsOf(givenCurrentUserAsPackageAdmin))
.extracting(RbacGrantEntity::getGranteeUserName) .extracting(RbacGrantEntity::getGranteeUserName)
.doesNotContain(givenNewUser.getName()); .doesNotContain(givenNewUser.getName());
@ -315,9 +315,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
// given // given
final var givenArbitraryUser = createRBacUser(); final var givenArbitraryUser = createRBacUser();
final var givenRoleToGrant = "test_package#xxx00.admin"; final var givenRoleToGrant = "test_package#xxx00:ADMIN";
final var givenCurrentUserAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant); final var givenCurrentUserAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant);
final var givenOwnPackageAdminRole = findRbacRoleByName("test_package#xxx00.admin"); final var givenOwnPackageAdminRole = getRbacRoleByName("test_package#xxx00:ADMIN");
// and given an existing grant // and given an existing grant
assumeCreated(givenCurrentUserAsPackageAdmin assumeCreated(givenCurrentUserAsPackageAdmin
@ -325,7 +325,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
.toUser(givenArbitraryUser)); .toUser(givenArbitraryUser));
assumeGrantExists( assumeGrantExists(
givenCurrentUserAsPackageAdmin, givenCurrentUserAsPackageAdmin,
"{ grant role %s to user %s by role %s and assume }".formatted( "{ grant role:%s to user:%s by role:%s and assume }".formatted(
givenOwnPackageAdminRole.getRoleName(), givenOwnPackageAdminRole.getRoleName(),
givenArbitraryUser.getName(), givenArbitraryUser.getName(),
givenCurrentUserAsPackageAdmin.assumedRole)); givenCurrentUserAsPackageAdmin.assumedRole));
@ -361,11 +361,11 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
this(currentUser, ""); this(currentUser, "");
} }
GrantFixture grantsRole(final RbacRoleEntity givenOwnPackageAdminRole) { GrantFixture grantsRole(final RbacRoleRvEntity givenOwnPackageAdminRole) {
return new GrantFixture(givenOwnPackageAdminRole); return new GrantFixture(givenOwnPackageAdminRole);
} }
RevokeFixture revokesRole(final RbacRoleEntity givenOwnPackageAdminRole) { RevokeFixture revokesRole(final RbacRoleRvEntity givenOwnPackageAdminRole) {
return new RevokeFixture(givenOwnPackageAdminRole); return new RevokeFixture(givenOwnPackageAdminRole);
} }
@ -376,11 +376,11 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
class GrantFixture { class GrantFixture {
private Subject grantingSubject = Subject.this; private Subject grantingSubject = Subject.this;
private final RbacRoleEntity grantedRole; private final RbacRoleRvEntity grantedRole;
private boolean assumed; private boolean assumed;
private RbacUserEntity granteeUser; private RbacUserEntity granteeUser;
public GrantFixture(final RbacRoleEntity roleToGrant) { public GrantFixture(final RbacRoleRvEntity roleToGrant) {
this.grantedRole = roleToGrant; this.grantedRole = roleToGrant;
} }
@ -417,11 +417,11 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
class RevokeFixture { class RevokeFixture {
private Subject currentSubject = Subject.this; private Subject currentSubject = Subject.this;
private final RbacRoleEntity grantedRole; private final RbacRoleRvEntity grantedRole;
private boolean assumed; private boolean assumed;
private RbacUserEntity granteeUser; private RbacUserEntity granteeUser;
public RevokeFixture(final RbacRoleEntity roleToGrant) { public RevokeFixture(final RbacRoleRvEntity roleToGrant) {
this.grantedRole = roleToGrant; this.grantedRole = roleToGrant;
} }
@ -455,9 +455,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
private class GetGrantByIdFixture { private class GetGrantByIdFixture {
private Subject currentSubject = Subject.this; private Subject currentSubject = Subject.this;
private RbacRoleEntity grantedRole; private RbacRoleRvEntity grantedRole;
GetGrantByIdFixture forGrantedRole(final RbacRoleEntity grantedRole) { GetGrantByIdFixture forGrantedRole(final RbacRoleRvEntity grantedRole) {
this.grantedRole = grantedRole; this.grantedRole = grantedRole;
return this; return this;
} }
@ -504,13 +504,13 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", null); context("superuser-alex@hostsharing.net", null);
return rbacUserRepository.findByName(userName); return rbacUserRepository.findByName(userName);
}).returnedValue(); }).assertNotNull().returnedValue();
} }
RbacRoleEntity findRbacRoleByName(final String roleName) { RbacRoleRvEntity getRbacRoleByName(final String roleName) {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", null); context("superuser-alex@hostsharing.net", null);
return rbacRoleRepository.findByRoleName(roleName); return rbacRoleRepository.findByRoleName(roleName);
}).returnedValue(); }).assertNotNull().returnedValue();
} }
} }

View File

@ -34,13 +34,13 @@ class RbacGrantEntityUnitTest {
"GrantEE", UUID.randomUUID(), "GrantEE", UUID.randomUUID(),
true, true,
"ObjectTable", "ObjectId", UUID.randomUUID(), "ObjectTable", "ObjectId", UUID.randomUUID(),
RbacRoleType.admin); // @formatter:on RbacRoleType.ADMIN); // @formatter:on
// when // when
final var display = entity.toDisplay(); final var display = entity.toDisplay();
// then // then
assertThat(display).isEqualTo("{ grant role GrantED to user GrantEE by role GrantER and assume }"); assertThat(display).isEqualTo("{ grant role:GrantED to user:GrantEE by role:GrantER and assume }");
} }
@Test @Test
@ -52,12 +52,12 @@ class RbacGrantEntityUnitTest {
"GrantEE", UUID.randomUUID(), "GrantEE", UUID.randomUUID(),
false, false,
"ObjectTable", "ObjectId", UUID.randomUUID(), "ObjectTable", "ObjectId", UUID.randomUUID(),
RbacRoleType.owner); // @formatter:on RbacRoleType.OWNER); // @formatter:on
// when // when
final var display = entity.toDisplay(); final var display = entity.toDisplay();
// then // then
assertThat(display).isEqualTo("{ grant role GrantED to user GrantEE by role GrantER }"); assertThat(display).isEqualTo("{ grant role:GrantED to user:GrantEE by role:GrantER }");
} }
} }

View File

@ -69,7 +69,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
// then // then
exactlyTheseRbacGrantsAreReturned( exactlyTheseRbacGrantsAreReturned(
result, result,
"{ grant role test_package#xxx00.admin to user pac-admin-xxx00@xxx.example.com by role test_customer#xxx.admin and assume }"); "{ grant role:test_package#xxx00:ADMIN to user:pac-admin-xxx00@xxx.example.com by role:test_customer#xxx:ADMIN and assume }");
} }
@Test @Test
@ -84,17 +84,17 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
// then // then
exactlyTheseRbacGrantsAreReturned( exactlyTheseRbacGrantsAreReturned(
result, result,
"{ grant role test_customer#xxx.admin to user customer-admin@xxx.example.com by role test_customer#xxx.owner and assume }", "{ grant role: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#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#xxx01:ADMIN to user:pac-admin-xxx01@xxx.example.com by role:test_customer#xxx:ADMIN and assume }",
"{ grant role test_package#xxx02.admin to user pac-admin-xxx02@xxx.example.com by role test_customer#xxx.admin and assume }"); "{ grant role:test_package#xxx02:ADMIN to user:pac-admin-xxx02@xxx.example.com by role:test_customer#xxx:ADMIN and assume }");
} }
@Test @Test
@Accepts({ "GRT:L(List)" }) @Accepts({ "GRT:L(List)" })
public void customerAdmin_withAssumedRole_canOnlyViewRbacGrantsVisibleByAssumedRole() { public void customerAdmin_withAssumedRole_canOnlyViewRbacGrantsVisibleByAssumedRole() {
// given: // given:
context("customer-admin@xxx.example.com", "test_package#xxx00.admin"); context("customer-admin@xxx.example.com", "test_package#xxx00:ADMIN");
// when // when
final var result = rbacGrantRepository.findAll(); final var result = rbacGrantRepository.findAll();
@ -102,7 +102,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
// then // then
exactlyTheseRbacGrantsAreReturned( exactlyTheseRbacGrantsAreReturned(
result, result,
"{ grant role test_package#xxx00.admin to user pac-admin-xxx00@xxx.example.com by role test_customer#xxx.admin and assume }"); "{ grant role:test_package#xxx00:ADMIN to user:pac-admin-xxx00@xxx.example.com by role:test_customer#xxx:ADMIN and assume }");
} }
} }
@ -112,9 +112,9 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
@Test @Test
public void customerAdmin_canGrantOwnPackageAdminRole_toArbitraryUser() { public void customerAdmin_canGrantOwnPackageAdminRole_toArbitraryUser() {
// given // given
context("customer-admin@xxx.example.com", "test_customer#xxx.admin"); context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN");
final var givenArbitraryUserUuid = rbacUserRepository.findByName("pac-admin-zzz00@zzz.example.com").getUuid(); final var givenArbitraryUserUuid = rbacUserRepository.findByName("pac-admin-zzz00@zzz.example.com").getUuid();
final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName("test_package#xxx00.admin").getUuid(); final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName("test_package#xxx00:ADMIN").getUuid();
// when // when
final var grant = RbacGrantEntity.builder() final var grant = RbacGrantEntity.builder()
@ -130,7 +130,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
assertThat(rbacGrantRepository.findAll()) assertThat(rbacGrantRepository.findAll())
.extracting(RbacGrantEntity::toDisplay) .extracting(RbacGrantEntity::toDisplay)
.contains( .contains(
"{ grant role test_package#xxx00.admin to user pac-admin-zzz00@zzz.example.com by role test_customer#xxx.admin and assume }"); "{ grant role:test_package#xxx00:ADMIN to user:pac-admin-zzz00@zzz.example.com by role:test_customer#xxx:ADMIN and assume }");
} }
@Test @Test
@ -143,14 +143,14 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
context("customer-admin@xxx.example.com", null); context("customer-admin@xxx.example.com", null);
return new Given( return new Given(
createNewUser(), createNewUser(),
rbacRoleRepository.findByRoleName("test_package#xxx00.owner").getUuid() rbacRoleRepository.findByRoleName("test_package#xxx00:OWNER").getUuid()
); );
}).assumeSuccessful().returnedValue(); }).assumeSuccessful().returnedValue();
// when // when
final var attempt = jpaAttempt.transacted(() -> { final var attempt = jpaAttempt.transacted(() -> {
// now we try to use these uuids as a less privileged user // now we try to use these uuids as a less privileged user
context("pac-admin-xxx00@xxx.example.com", "test_package#xxx00.admin"); context("pac-admin-xxx00@xxx.example.com", "test_package#xxx00:ADMIN");
final var grant = RbacGrantEntity.builder() final var grant = RbacGrantEntity.builder()
.granteeUserUuid(given.arbitraryUser.getUuid()) .granteeUserUuid(given.arbitraryUser.getUuid())
.grantedRoleUuid(given.packageOwnerRoleUuid) .grantedRoleUuid(given.packageOwnerRoleUuid)
@ -162,8 +162,8 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
// then // then
attempt.assertExceptionWithRootCauseMessage( attempt.assertExceptionWithRootCauseMessage(
JpaSystemException.class, JpaSystemException.class,
"ERROR: [403] Access to granted role test_package#xxx00.owner", "ERROR: [403] Access to granted role test_package#xxx00:OWNER",
"forbidden for test_package#xxx00.admin"); "forbidden for test_package#xxx00:ADMIN");
jpaAttempt.transacted(() -> { jpaAttempt.transacted(() -> {
// finally, we use the new user to make sure, no roles were granted // finally, we use the new user to make sure, no roles were granted
context(given.arbitraryUser.getName(), null); context(given.arbitraryUser.getName(), null);
@ -180,16 +180,16 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
public void customerAdmin_canRevokeSelfGrantedPackageAdminRole() { public void customerAdmin_canRevokeSelfGrantedPackageAdminRole() {
// given // given
final var grant = create(grant() final var grant = create(grant()
.byUser("customer-admin@xxx.example.com").withAssumedRole("test_customer#xxx.admin") .byUser("customer-admin@xxx.example.com").withAssumedRole("test_customer#xxx:ADMIN")
.grantingRole("test_package#xxx00.admin").toUser("pac-admin-zzz00@zzz.example.com")); .grantingRole("test_package#xxx00:ADMIN").toUser("pac-admin-zzz00@zzz.example.com"));
// when // when
context("customer-admin@xxx.example.com", "test_customer#xxx.admin"); context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN");
final var revokeAttempt = attempt(em, () -> final var revokeAttempt = attempt(em, () ->
rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId())); rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId()));
// then // then
context("customer-admin@xxx.example.com", "test_customer#xxx.admin"); context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN");
assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull(); assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull();
assertThat(rbacGrantRepository.findAll()) assertThat(rbacGrantRepository.findAll())
.extracting(RbacGrantEntity::getGranteeUserName) .extracting(RbacGrantEntity::getGranteeUserName)
@ -201,17 +201,17 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
// given // given
final var newUser = createNewUserTransacted(); final var newUser = createNewUserTransacted();
final var grant = create(grant() final var grant = create(grant()
.byUser("customer-admin@xxx.example.com").withAssumedRole("test_package#xxx00.admin") .byUser("customer-admin@xxx.example.com").withAssumedRole("test_package#xxx00:ADMIN")
.grantingRole("test_package#xxx00.admin").toUser(newUser.getName())); .grantingRole("test_package#xxx00:ADMIN").toUser(newUser.getName()));
// when // when
context("pac-admin-xxx00@xxx.example.com", "test_package#xxx00.admin"); context("pac-admin-xxx00@xxx.example.com", "test_package#xxx00:ADMIN");
final var revokeAttempt = attempt(em, () -> final var revokeAttempt = attempt(em, () ->
rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId())); rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId()));
// then // then
assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull(); assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull();
context("customer-admin@xxx.example.com", "test_customer#xxx.admin"); context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN");
assertThat(rbacGrantRepository.findAll()) assertThat(rbacGrantRepository.findAll())
.extracting(RbacGrantEntity::getGranteeUserName) .extracting(RbacGrantEntity::getGranteeUserName)
.doesNotContain("pac-admin-zzz00@zzz.example.com"); .doesNotContain("pac-admin-zzz00@zzz.example.com");
@ -221,19 +221,19 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
public void packageAdmin_canNotRevokeOwnPackageAdminRoleGrantedByOwnerRoleOfThatPackage() { public void packageAdmin_canNotRevokeOwnPackageAdminRoleGrantedByOwnerRoleOfThatPackage() {
// given // given
final var grant = create(grant() final var grant = create(grant()
.byUser("customer-admin@xxx.example.com").withAssumedRole("test_package#xxx00.owner") .byUser("customer-admin@xxx.example.com").withAssumedRole("test_package#xxx00:OWNER")
.grantingRole("test_package#xxx00.admin").toUser("pac-admin-zzz00@zzz.example.com")); .grantingRole("test_package#xxx00:ADMIN").toUser("pac-admin-zzz00@zzz.example.com"));
final var grantedByRole = rbacRoleRepository.findByRoleName("test_package#xxx00.owner"); final var grantedByRole = rbacRoleRepository.findByRoleName("test_package#xxx00:OWNER");
// when // when
context("pac-admin-xxx00@xxx.example.com", "test_package#xxx00.admin"); context("pac-admin-xxx00@xxx.example.com", "test_package#xxx00:ADMIN");
final var revokeAttempt = attempt(em, () -> final var revokeAttempt = attempt(em, () ->
rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId())); rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId()));
// then // then
revokeAttempt.assertExceptionWithRootCauseMessage( revokeAttempt.assertExceptionWithRootCauseMessage(
JpaSystemException.class, JpaSystemException.class,
"ERROR: [403] Revoking role created by %s is forbidden for {test_package#xxx00.admin}.".formatted( "ERROR: [403] Revoking role created by %s is forbidden for {test_package#xxx00:ADMIN}.".formatted(
grantedByRole.getUuid() grantedByRole.getUuid()
)); ));
} }
@ -254,7 +254,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
assertThat(grantAttempt.caughtException()).isNull(); assertThat(grantAttempt.caughtException()).isNull();
assertThat(rawRbacGrantRepository.findAll()) assertThat(rawRbacGrantRepository.findAll())
.extracting(RawRbacGrantEntity::toDisplay) .extracting(RawRbacGrantEntity::toDisplay)
.contains("{ grant role %s to user %s by %s and assume }".formatted( .contains("{ grant role:%s to user:%s by %s and assume }".formatted(
with.grantedRole, with.granteeUserName, with.assumedRole with.grantedRole, with.granteeUserName, with.assumedRole
)); ));

View File

@ -54,43 +54,43 @@ class RbacGrantsDiagramServiceIntegrationTest extends ContextBasedTestWithCleanu
@Test @Test
void allGrantsToCurrentUser() { void allGrantsToCurrentUser() {
context("superuser-alex@hostsharing.net", "test_domain#xxx00-aaaa.owner"); context("superuser-alex@hostsharing.net", "test_domain#xxx00-aaaa:OWNER");
final var graph = grantsMermaidService.allGrantsToCurrentUser(EnumSet.of(Include.TEST_ENTITIES)); final var graph = grantsMermaidService.allGrantsToCurrentUser(EnumSet.of(Include.TEST_ENTITIES));
assertThat(graph).isEqualTo(""" assertThat(graph).isEqualTo("""
flowchart TB flowchart TB
role:test_domain#xxx00-aaaa.admin --> role:test_package#xxx00.tenant role: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_domain#xxx00-aaaa:ADMIN
role:test_domain#xxx00-aaaa.owner --> role:test_package#xxx00.tenant role:test_domain#xxx00-aaaa:OWNER --> role:test_package#xxx00:TENANT
role:test_package#xxx00.tenant --> role:test_customer#xxx.tenant role:test_package#xxx00:TENANT --> role:test_customer#xxx:TENANT
""".trim()); """.trim());
} }
@Test @Test
void allGrantsToCurrentUserIncludingPermissions() { void allGrantsToCurrentUserIncludingPermissions() {
context("superuser-alex@hostsharing.net", "test_domain#xxx00-aaaa.owner"); context("superuser-alex@hostsharing.net", "test_domain#xxx00-aaaa:OWNER");
final var graph = grantsMermaidService.allGrantsToCurrentUser(EnumSet.of(Include.TEST_ENTITIES, Include.PERMISSIONS)); final var graph = grantsMermaidService.allGrantsToCurrentUser(EnumSet.of(Include.TEST_ENTITIES, Include.PERMISSIONS));
assertThat(graph).isEqualTo(""" assertThat(graph).isEqualTo("""
flowchart TB flowchart TB
role:test_customer#xxx.tenant --> perm:SELECT:on:test_customer#xxx role:test_customer#xxx:TENANT --> perm:test_customer#xxx:SELECT
role:test_domain#xxx00-aaaa.admin --> perm:SELECT:on:test_domain#xxx00-aaaa 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:ADMIN --> role:test_package#xxx00:TENANT
role:test_domain#xxx00-aaaa.owner --> perm:DELETE:on:test_domain#xxx00-aaaa role:test_domain#xxx00-aaaa:OWNER --> perm:test_domain#xxx00-aaaa:DELETE
role:test_domain#xxx00-aaaa.owner --> perm:UPDATE:on:test_domain#xxx00-aaaa 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_domain#xxx00-aaaa:ADMIN
role:test_domain#xxx00-aaaa.owner --> role:test_package#xxx00.tenant role:test_domain#xxx00-aaaa:OWNER --> role:test_package#xxx00:TENANT
role:test_package#xxx00.tenant --> perm:SELECT:on:test_package#xxx00 role:test_package#xxx00:TENANT --> perm:test_package#xxx00:SELECT
role:test_package#xxx00.tenant --> role:test_customer#xxx.tenant role:test_package#xxx00:TENANT --> role:test_customer#xxx:TENANT
""".trim()); """.trim());
} }
@Test @Test
@Disabled // enable to generate from a real database @Disabled // enable to generate from a real database
void print() throws IOException { void print() throws IOException {
//context("superuser-alex@hostsharing.net", "hs_office_person#FirbySusan.admin"); //context("superuser-alex@hostsharing.net", "hs_office_person#FirbySusan:ADMIN");
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
//final var graph = grantsMermaidService.allGrantsToCurrentUser(EnumSet.of(Include.NON_TEST_ENTITIES, Include.PERMISSIONS)); //final var graph = grantsMermaidService.allGrantsToCurrentUser(EnumSet.of(Include.NON_TEST_ENTITIES, Include.PERMISSIONS));

View File

@ -35,7 +35,7 @@ public class RawRbacRoleEntity {
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
private RbacRoleType roleType; private RbacRoleType roleType;
@Formula("objectTable||'#'||objectIdName||'.'||roleType") @Formula("objectTable||'#'||objectIdName||':'||roleType")
private String roleName; private String roleName;
@NotNull @NotNull

View File

@ -45,14 +45,14 @@ class RbacRoleControllerAcceptanceTest {
.then().assertThat() .then().assertThat()
.statusCode(200) .statusCode(200)
.contentType("application/json") .contentType("application/json")
.body("", hasItem(hasEntry("roleName", "test_customer#xxx.admin"))) .body("", hasItem(hasEntry("roleName", "test_customer#xxx:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_customer#xxx.owner"))) .body("", hasItem(hasEntry("roleName", "test_customer#xxx:OWNER")))
.body("", hasItem(hasEntry("roleName", "test_customer#xxx.tenant"))) .body("", hasItem(hasEntry("roleName", "test_customer#xxx:TENANT")))
// ... // ...
.body("", hasItem(hasEntry("roleName", "global#global.admin"))) .body("", hasItem(hasEntry("roleName", "global#global:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_customer#yyy.admin"))) .body("", hasItem(hasEntry("roleName", "test_customer#yyy:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_package#yyy00.admin"))) .body("", hasItem(hasEntry("roleName", "test_package#yyy00:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaaa.owner"))) .body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER")))
.body( "size()", greaterThanOrEqualTo(73)); // increases with new test data .body( "size()", greaterThanOrEqualTo(73)); // increases with new test data
// @formatter:on // @formatter:on
} }
@ -65,7 +65,7 @@ class RbacRoleControllerAcceptanceTest {
RestAssured RestAssured
.given() .given()
.header("current-user", "superuser-alex@hostsharing.net") .header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_package#yyy00.admin") .header("assumed-roles", "test_package#yyy00:ADMIN")
.port(port) .port(port)
.when() .when()
.get("http://localhost/api/rbac/roles") .get("http://localhost/api/rbac/roles")
@ -75,18 +75,18 @@ class RbacRoleControllerAcceptanceTest {
.statusCode(200) .statusCode(200)
.contentType("application/json") .contentType("application/json")
.body("", hasItem(hasEntry("roleName", "test_customer#yyy.tenant"))) .body("", hasItem(hasEntry("roleName", "test_customer#yyy:TENANT")))
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaaa.owner"))) .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-aaaa:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaab.owner"))) .body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaab:OWNER")))
.body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaab.admin"))) .body("", hasItem(hasEntry("roleName", "test_domain#yyy00-aaab:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_package#yyy00.admin"))) .body("", hasItem(hasEntry("roleName", "test_package#yyy00:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_package#yyy00.tenant"))) .body("", hasItem(hasEntry("roleName", "test_package#yyy00:TENANT")))
.body("", not(hasItem(hasEntry("roleName", "test_customer#xxx.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_domain#xxx00-aaaa:ADMIN"))))
.body("", not(hasItem(hasEntry("roleName", "test_package#xxx00.admin")))) .body("", not(hasItem(hasEntry("roleName", "test_package#xxx00:ADMIN"))))
.body("", not(hasItem(hasEntry("roleName", "test_package#xxx00.tenant")))) .body("", not(hasItem(hasEntry("roleName", "test_package#xxx00:TENANT"))))
; ;
// @formatter:on // @formatter:on
} }
@ -106,15 +106,15 @@ class RbacRoleControllerAcceptanceTest {
.statusCode(200) .statusCode(200)
.contentType("application/json") .contentType("application/json")
.body("", hasItem(hasEntry("roleName", "test_customer#zzz.tenant"))) .body("", hasItem(hasEntry("roleName", "test_customer#zzz:TENANT")))
.body("", hasItem(hasEntry("roleName", "test_domain#zzz00-aaaa.admin"))) .body("", hasItem(hasEntry("roleName", "test_domain#zzz00-aaaa:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_package#zzz00.admin"))) .body("", hasItem(hasEntry("roleName", "test_package#zzz00:ADMIN")))
.body("", hasItem(hasEntry("roleName", "test_package#zzz00.tenant"))) .body("", hasItem(hasEntry("roleName", "test_package#zzz00:TENANT")))
.body("", not(hasItem(hasEntry("roleName", "test_customer#yyy.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_domain#yyy00-aaaa:ADMIN"))))
.body("", not(hasItem(hasEntry("roleName", "test_package#yyy00.admin")))) .body("", not(hasItem(hasEntry("roleName", "test_package#yyy00:ADMIN"))))
.body("", not(hasItem(hasEntry("roleName", "test_package#yyy00.tenant")))); .body("", not(hasItem(hasEntry("roleName", "test_package#yyy00:TENANT"))));
// @formatter:on // @formatter:on
} }
} }

View File

@ -73,9 +73,9 @@ class RbacRoleControllerRestTest {
// then // then
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(3))) .andExpect(jsonPath("$", hasSize(3)))
.andExpect(jsonPath("$[0].roleName", is("global#global.admin"))) .andExpect(jsonPath("$[0].roleName", is("global#global:ADMIN")))
.andExpect(jsonPath("$[1].roleName", is("test_customer#xxx.owner"))) .andExpect(jsonPath("$[1].roleName", is("test_customer#xxx:OWNER")))
.andExpect(jsonPath("$[2].roleName", is("test_customer#xxx.admin"))) .andExpect(jsonPath("$[2].roleName", is("test_customer#xxx:ADMIN")))
.andExpect(jsonPath("$[2].uuid", is(customerXxxAdmin.getUuid().toString()))) .andExpect(jsonPath("$[2].uuid", is(customerXxxAdmin.getUuid().toString())))
.andExpect(jsonPath("$[2].objectUuid", is(customerXxxAdmin.getObjectUuid().toString()))) .andExpect(jsonPath("$[2].objectUuid", is(customerXxxAdmin.getObjectUuid().toString())))
.andExpect(jsonPath("$[2].objectTable", is(customerXxxAdmin.getObjectTable().toString()))) .andExpect(jsonPath("$[2].objectTable", is(customerXxxAdmin.getObjectTable().toString())))

View File

@ -39,19 +39,19 @@ class RbacRoleRepositoryIntegrationTest {
private static final String[] ALL_TEST_DATA_ROLES = Array.of( private static final String[] ALL_TEST_DATA_ROLES = Array.of(
// @formatter:off // @formatter:off
"global#global.admin", "global#global:ADMIN",
"test_customer#xxx.admin", "test_customer#xxx.owner", "test_customer#xxx.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#xxx00:ADMIN", "test_package#xxx00:OWNER", "test_package#xxx00:TENANT",
"test_package#xxx01.admin", "test_package#xxx01.owner", "test_package#xxx01.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_package#xxx02:ADMIN", "test_package#xxx02:OWNER", "test_package#xxx02:TENANT",
"test_customer#yyy.admin", "test_customer#yyy.owner", "test_customer#yyy.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#yyy00:ADMIN", "test_package#yyy00:OWNER", "test_package#yyy00:TENANT",
"test_package#yyy01.admin", "test_package#yyy01.owner", "test_package#yyy01.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_package#yyy02:ADMIN", "test_package#yyy02:OWNER", "test_package#yyy02:TENANT",
"test_customer#zzz.admin", "test_customer#zzz.owner", "test_customer#zzz.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#zzz00:ADMIN", "test_package#zzz00:OWNER", "test_package#zzz00:TENANT",
"test_package#zzz01.admin", "test_package#zzz01.owner", "test_package#zzz01.tenant", "test_package#zzz01:ADMIN", "test_package#zzz01:OWNER", "test_package#zzz01:TENANT",
"test_package#zzz02.admin", "test_package#zzz02.owner", "test_package#zzz02.tenant" "test_package#zzz02:ADMIN", "test_package#zzz02:OWNER", "test_package#zzz02:TENANT"
// @formatter:on // @formatter:on
); );
@ -70,7 +70,7 @@ class RbacRoleRepositoryIntegrationTest {
@Test @Test
public void globalAdmin_withAssumedglobalAdminRole_canViewAllRbacRoles() { public void globalAdmin_withAssumedglobalAdminRole_canViewAllRbacRoles() {
given: given:
context.define("superuser-alex@hostsharing.net", "global#global.admin"); context.define("superuser-alex@hostsharing.net", "global#global:ADMIN");
// when // when
final var result = rbacRoleRepository.findAll(); final var result = rbacRoleRepository.findAll();
@ -91,49 +91,49 @@ class RbacRoleRepositoryIntegrationTest {
allTheseRbacRolesAreReturned( allTheseRbacRolesAreReturned(
result, result,
// @formatter:off // @formatter:off
"test_customer#xxx.admin", "test_customer#xxx:ADMIN",
"test_customer#xxx.tenant", "test_customer#xxx:TENANT",
"test_package#xxx00.admin", "test_package#xxx00:ADMIN",
"test_package#xxx00.owner", "test_package#xxx00:OWNER",
"test_package#xxx00.tenant", "test_package#xxx00:TENANT",
"test_package#xxx01.admin", "test_package#xxx01:ADMIN",
"test_package#xxx01.owner", "test_package#xxx01:OWNER",
"test_package#xxx01.tenant", "test_package#xxx01:TENANT",
// ... // ...
"test_domain#xxx00-aaaa.admin", "test_domain#xxx00-aaaa:ADMIN",
"test_domain#xxx00-aaaa.owner", "test_domain#xxx00-aaaa:OWNER",
// .. // ..
"test_domain#xxx01-aaab.admin", "test_domain#xxx01-aaab:ADMIN",
"test_domain#xxx01-aaab.owner" "test_domain#xxx01-aaab:OWNER"
// @formatter:on // @formatter:on
); );
noneOfTheseRbacRolesIsReturned( noneOfTheseRbacRolesIsReturned(
result, result,
// @formatter:off // @formatter:off
"global#global.admin", "global#global:ADMIN",
"test_customer#xxx.owner", "test_customer#xxx:OWNER",
"test_package#yyy00.admin", "test_package#yyy00:ADMIN",
"test_package#yyy00.owner", "test_package#yyy00:OWNER",
"test_package#yyy00.tenant" "test_package#yyy00:TENANT"
// @formatter:on // @formatter:on
); );
} }
@Test @Test
public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnRbacRole() { public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnRbacRole() {
context.define("customer-admin@xxx.example.com", "test_package#xxx00.admin"); context.define("customer-admin@xxx.example.com", "test_package#xxx00:ADMIN");
final var result = rbacRoleRepository.findAll(); final var result = rbacRoleRepository.findAll();
exactlyTheseRbacRolesAreReturned( exactlyTheseRbacRolesAreReturned(
result, result,
"test_customer#xxx.tenant", "test_customer#xxx:TENANT",
"test_package#xxx00.admin", "test_package#xxx00:ADMIN",
"test_package#xxx00.tenant", "test_package#xxx00:TENANT",
"test_domain#xxx00-aaaa.admin", "test_domain#xxx00-aaaa:ADMIN",
"test_domain#xxx00-aaaa.owner", "test_domain#xxx00-aaaa:OWNER",
"test_domain#xxx00-aaab.admin", "test_domain#xxx00-aaab:ADMIN",
"test_domain#xxx00-aaab.owner"); "test_domain#xxx00-aaab:OWNER");
} }
@Test @Test
@ -157,39 +157,39 @@ class RbacRoleRepositoryIntegrationTest {
void customerAdmin_withoutAssumedRole_canFindItsOwnRolesByName() { void customerAdmin_withoutAssumedRole_canFindItsOwnRolesByName() {
context.define("customer-admin@xxx.example.com"); context.define("customer-admin@xxx.example.com");
final var result = rbacRoleRepository.findByRoleName("test_customer#xxx.admin"); final var result = rbacRoleRepository.findByRoleName("test_customer#xxx:ADMIN");
assertThat(result).isNotNull(); assertThat(result).isNotNull();
assertThat(result.getObjectTable()).isEqualTo("test_customer"); assertThat(result.getObjectTable()).isEqualTo("test_customer");
assertThat(result.getObjectIdName()).isEqualTo("xxx"); assertThat(result.getObjectIdName()).isEqualTo("xxx");
assertThat(result.getRoleType()).isEqualTo(RbacRoleType.admin); assertThat(result.getRoleType()).isEqualTo(RbacRoleType.ADMIN);
} }
@Test @Test
void customerAdmin_withoutAssumedRole_canNotFindAlienRolesByName() { void customerAdmin_withoutAssumedRole_canNotFindAlienRolesByName() {
context.define("customer-admin@xxx.example.com"); context.define("customer-admin@xxx.example.com");
final var result = rbacRoleRepository.findByRoleName("test_customer#bbb.admin"); final var result = rbacRoleRepository.findByRoleName("test_customer#bbb:ADMIN");
assertThat(result).isNull(); assertThat(result).isNull();
} }
} }
void exactlyTheseRbacRolesAreReturned(final List<RbacRoleEntity> actualResult, final String... expectedRoleNames) { void exactlyTheseRbacRolesAreReturned(final List<RbacRoleRvEntity> actualResult, final String... expectedRoleNames) {
assertThat(actualResult) assertThat(actualResult)
.extracting(RbacRoleEntity::getRoleName) .extracting(RbacRoleRvEntity::getRoleName)
.containsExactlyInAnyOrder(expectedRoleNames); .containsExactlyInAnyOrder(expectedRoleNames);
} }
void allTheseRbacRolesAreReturned(final List<RbacRoleEntity> actualResult, final String... expectedRoleNames) { void allTheseRbacRolesAreReturned(final List<RbacRoleRvEntity> actualResult, final String... expectedRoleNames) {
assertThat(actualResult) assertThat(actualResult)
.extracting(RbacRoleEntity::getRoleName) .extracting(RbacRoleRvEntity::getRoleName)
.contains(expectedRoleNames); .contains(expectedRoleNames);
} }
void noneOfTheseRbacRolesIsReturned(final List<RbacRoleEntity> actualResult, final String... unexpectedRoleNames) { void noneOfTheseRbacRolesIsReturned(final List<RbacRoleRvEntity> actualResult, final String... unexpectedRoleNames) {
assertThat(actualResult) assertThat(actualResult)
.extracting(RbacRoleEntity::getRoleName) .extracting(RbacRoleRvEntity::getRoleName)
.doesNotContain(unexpectedRoleNames); .doesNotContain(unexpectedRoleNames);
} }

View File

@ -4,11 +4,11 @@ import static java.util.UUID.randomUUID;
public class TestRbacRole { public class TestRbacRole {
public static final RbacRoleEntity hostmasterRole = rbacRole("global", "global", RbacRoleType.admin); public static final RbacRoleRvEntity hostmasterRole = rbacRole("global", "global", RbacRoleType.ADMIN);
static final RbacRoleEntity customerXxxOwner = rbacRole("test_customer", "xxx", RbacRoleType.owner); static final RbacRoleRvEntity customerXxxOwner = rbacRole("test_customer", "xxx", RbacRoleType.OWNER);
static final RbacRoleEntity customerXxxAdmin = rbacRole("test_customer", "xxx", RbacRoleType.admin); static final RbacRoleRvEntity customerXxxAdmin = rbacRole("test_customer", "xxx", RbacRoleType.ADMIN);
static public RbacRoleEntity rbacRole(final String objectTable, final String objectIdName, final RbacRoleType roleType) { static public RbacRoleRvEntity rbacRole(final String objectTable, final String objectIdName, final RbacRoleType roleType) {
return new RbacRoleEntity(randomUUID(), randomUUID(), objectTable, objectIdName, roleType, objectTable+'#'+objectIdName+'.'+roleType); return new RbacRoleRvEntity(randomUUID(), randomUUID(), objectTable, objectIdName, roleType, objectTable+'#'+objectIdName+':'+roleType);
} }
} }

View File

@ -104,7 +104,7 @@ class RbacUserControllerAcceptanceTest {
RestAssured RestAssured
.given() .given()
.header("current-user", "superuser-alex@hostsharing.net") .header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#yyy.admin") .header("assumed-roles", "test_customer#yyy:ADMIN")
.port(port) .port(port)
.when() .when()
.get("http://localhost/api/rbac/users/" + givenUser.getUuid()) .get("http://localhost/api/rbac/users/" + givenUser.getUuid())
@ -210,7 +210,7 @@ class RbacUserControllerAcceptanceTest {
RestAssured RestAssured
.given() .given()
.header("current-user", "superuser-alex@hostsharing.net") .header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#yyy.admin") .header("assumed-roles", "test_customer#yyy:ADMIN")
.port(port) .port(port)
.when() .when()
.get("http://localhost/api/rbac/users") .get("http://localhost/api/rbac/users")
@ -287,12 +287,12 @@ class RbacUserControllerAcceptanceTest {
.contentType("application/json") .contentType("application/json")
.body("", hasItem( .body("", hasItem(
allOf( allOf(
hasEntry("roleName", "test_customer#yyy.tenant"), hasEntry("roleName", "test_customer#yyy:TENANT"),
hasEntry("op", "SELECT")) hasEntry("op", "SELECT"))
)) ))
.body("", hasItem( .body("", hasItem(
allOf( allOf(
hasEntry("roleName", "test_domain#yyy00-aaaa.owner"), hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER"),
hasEntry("op", "DELETE")) hasEntry("op", "DELETE"))
)) ))
// actual content tested in integration test, so this is enough for here: // actual content tested in integration test, so this is enough for here:
@ -309,7 +309,7 @@ class RbacUserControllerAcceptanceTest {
RestAssured RestAssured
.given() .given()
.header("current-user", "superuser-alex@hostsharing.net") .header("current-user", "superuser-alex@hostsharing.net")
.header("assumed-roles", "test_customer#yyy.admin") .header("assumed-roles", "test_customer#yyy:ADMIN")
.port(port) .port(port)
.when() .when()
.get("http://localhost/api/rbac/users/" + givenUser.getUuid() + "/permissions") .get("http://localhost/api/rbac/users/" + givenUser.getUuid() + "/permissions")
@ -318,12 +318,12 @@ class RbacUserControllerAcceptanceTest {
.contentType("application/json") .contentType("application/json")
.body("", hasItem( .body("", hasItem(
allOf( allOf(
hasEntry("roleName", "test_customer#yyy.tenant"), hasEntry("roleName", "test_customer#yyy:TENANT"),
hasEntry("op", "SELECT")) hasEntry("op", "SELECT"))
)) ))
.body("", hasItem( .body("", hasItem(
allOf( allOf(
hasEntry("roleName", "test_domain#yyy00-aaaa.owner"), hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER"),
hasEntry("op", "DELETE")) hasEntry("op", "DELETE"))
)) ))
// actual content tested in integration test, so this is enough for here: // actual content tested in integration test, so this is enough for here:
@ -348,12 +348,12 @@ class RbacUserControllerAcceptanceTest {
.contentType("application/json") .contentType("application/json")
.body("", hasItem( .body("", hasItem(
allOf( allOf(
hasEntry("roleName", "test_customer#yyy.tenant"), hasEntry("roleName", "test_customer#yyy:TENANT"),
hasEntry("op", "SELECT")) hasEntry("op", "SELECT"))
)) ))
.body("", hasItem( .body("", hasItem(
allOf( allOf(
hasEntry("roleName", "test_domain#yyy00-aaaa.owner"), hasEntry("roleName", "test_domain#yyy00-aaaa:OWNER"),
hasEntry("op", "DELETE")) hasEntry("op", "DELETE"))
)) ))
// actual content tested in integration test, so this is enough for here: // actual content tested in integration test, so this is enough for here:

View File

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

View File

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

View File

@ -21,9 +21,9 @@ class TestCustomerEntityUnitTest {
subgraph customer:roles[ ] subgraph customer:roles[ ]
style customer:roles fill:#dd4901,stroke:white style customer:roles fill:#dd4901,stroke:white
role:customer:owner[[customer:owner]] role:customer:OWNER[[customer:OWNER]]
role:customer:admin[[customer:admin]] role:customer:ADMIN[[customer:ADMIN]]
role:customer:tenant[[customer:tenant]] role:customer:TENANT[[customer:TENANT]]
end end
subgraph customer:permissions[ ] subgraph customer:permissions[ ]
@ -37,18 +37,18 @@ class TestCustomerEntityUnitTest {
end end
%% granting roles to users %% granting roles to users
user:creator ==>|XX| role:customer:owner user:creator ==>|XX| role:customer:OWNER
%% granting roles to roles %% granting roles to roles
role:global:admin ==>|XX| role:customer:owner role:global:ADMIN ==>|XX| role:customer:OWNER
role:customer:owner ==> role:customer:admin role:customer:OWNER ==> role:customer:ADMIN
role:customer:admin ==> role:customer:tenant role:customer:ADMIN ==> role:customer:TENANT
%% granting permissions to roles %% granting permissions to roles
role:global:admin ==> perm:customer:INSERT role:global:ADMIN ==> perm:customer:INSERT
role:customer:owner ==> perm:customer:DELETE role:customer:OWNER ==> perm:customer:DELETE
role:customer:admin ==> perm:customer:UPDATE role:customer:ADMIN ==> perm:customer:UPDATE
role:customer:tenant ==> perm:customer:SELECT role:customer:TENANT ==> perm:customer:SELECT
"""); """);
} }
} }

View File

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

View File

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

View File

@ -21,9 +21,9 @@ class TestPackageEntityUnitTest {
subgraph package:roles[ ] subgraph package:roles[ ]
style package:roles fill:#dd4901,stroke:white style package:roles fill:#dd4901,stroke:white
role:package:owner[[package:owner]] role:package:OWNER[[package:OWNER]]
role:package:admin[[package:admin]] role:package:ADMIN[[package:ADMIN]]
role:package:tenant[[package:tenant]] role:package:TENANT[[package:TENANT]]
end end
subgraph package:permissions[ ] subgraph package:permissions[ ]
@ -43,26 +43,26 @@ class TestPackageEntityUnitTest {
subgraph customer:roles[ ] subgraph customer:roles[ ]
style customer:roles fill:#99bcdb,stroke:white style customer:roles fill:#99bcdb,stroke:white
role:customer:owner[[customer:owner]] role:customer:OWNER[[customer:OWNER]]
role:customer:admin[[customer:admin]] role:customer:ADMIN[[customer:ADMIN]]
role:customer:tenant[[customer:tenant]] role:customer:TENANT[[customer:TENANT]]
end end
end end
%% granting roles to roles %% granting roles to roles
role:global:admin -.->|XX| role:customer:owner role:global:ADMIN -.->|XX| role:customer:OWNER
role:customer:owner -.-> role:customer:admin role:customer:OWNER -.-> role:customer:ADMIN
role:customer:admin -.-> role:customer:tenant role:customer:ADMIN -.-> role:customer:TENANT
role:customer:admin ==> role:package:owner role:customer:ADMIN ==> role:package:OWNER
role:package:owner ==> role:package:admin role:package:OWNER ==> role:package:ADMIN
role:package:admin ==> role:package:tenant role:package:ADMIN ==> role:package:TENANT
role:package:tenant ==> role:customer:tenant role:package:TENANT ==> role:customer:TENANT
%% granting permissions to roles %% granting permissions to roles
role:customer:admin ==> perm:package:INSERT role:customer:ADMIN ==> perm:package:INSERT
role:package:owner ==> perm:package:DELETE role:package:OWNER ==> perm:package:DELETE
role:package:owner ==> perm:package:UPDATE role:package:OWNER ==> perm:package:UPDATE
role:package:tenant ==> perm:package:SELECT role:package:TENANT ==> perm:package:SELECT
"""); """);
} }
} }

View File

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

View File

@ -154,6 +154,11 @@ public class JpaAttempt {
return this; return this;
} }
public JpaResult<T> assertNotNull() {
assertThat(returnedValue()).isNotNull();
return this;
}
private String firstRootCauseMessageLineOf(final RuntimeException exception) { private String firstRootCauseMessageLineOf(final RuntimeException exception) {
final var rootCause = NestedExceptionUtils.getRootCause(exception); final var rootCause = NestedExceptionUtils.getRootCause(exception);
return Optional.ofNullable(rootCause) return Optional.ofNullable(rootCause)