allow-multiple-insert-permission-grants #49
@ -179,7 +179,9 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject {
|
|||||||
.createSubRole(TENANT, (with) -> {
|
.createSubRole(TENANT, (with) -> {
|
||||||
with.outgoingSubRole("debitorRel", TENANT);
|
with.outgoingSubRole("debitorRel", TENANT);
|
||||||
with.permission(SELECT);
|
with.permission(SELECT);
|
||||||
});
|
})
|
||||||
|
|
||||||
|
.limitDiagramTo("bookingItem", "debitorRel", "global");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
|
@ -37,6 +37,7 @@ import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOU
|
|||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inCaseOf;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inCaseOf;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inOtherCases;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingCase;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingCase;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||||
@ -156,9 +157,10 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject {
|
|||||||
dependsOnColumn("parentAssetUuid"),
|
dependsOnColumn("parentAssetUuid"),
|
||||||
directlyFetchedByDependsOnColumn(),
|
directlyFetchedByDependsOnColumn(),
|
||||||
NULLABLE)
|
NULLABLE)
|
||||||
// TODO.rbac: implement multiple INSERT-rules, e.g. for Asset.bookingItem + Asset.parentAsset
|
.toRole("parentServer", ADMIN).grantPermission(INSERT)
|
||||||
//.toRole("parentServer", AGENT).grantPermission(INSERT)
|
.toRole("bookingItem", AGENT).grantPermission(INSERT)
|
||||||
)
|
),
|
||||||
|
inOtherCases(then -> {})
|
||||||
)
|
)
|
||||||
|
|
||||||
.createRole(OWNER, (with) -> {
|
.createRole(OWNER, (with) -> {
|
||||||
@ -171,7 +173,9 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject {
|
|||||||
.createSubRole(TENANT, (with) -> {
|
.createSubRole(TENANT, (with) -> {
|
||||||
with.outgoingSubRole("bookingItem", TENANT);
|
with.outgoingSubRole("bookingItem", TENANT);
|
||||||
with.permission(SELECT);
|
with.permission(SELECT);
|
||||||
});
|
})
|
||||||
|
|
||||||
|
.limitDiagramTo("asset", "bookingItem", "bookingItem.debitorRel", "parentServer", "global");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
|
@ -19,7 +19,6 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.*;
|
|||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inCaseOf;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inCaseOf;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inOtherCases;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inOtherCases;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingCase;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
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.*;
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.BinaryOperator;
|
import java.util.function.BinaryOperator;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.joining;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.PostgresTriggerReference.NEW;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.PostgresTriggerReference.NEW;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.GUEST;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
||||||
import static org.apache.commons.lang3.StringUtils.capitalize;
|
import static org.apache.commons.lang3.StringUtils.capitalize;
|
||||||
import static org.apache.commons.lang3.StringUtils.uncapitalize;
|
import static org.apache.commons.lang3.StringUtils.uncapitalize;
|
||||||
@ -22,194 +26,121 @@ public class InsertTriggerGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void generateTo(final StringWriter plPgSql) {
|
void generateTo(final StringWriter plPgSql) {
|
||||||
generateLiquibaseChangesetHeader(plPgSql);
|
if (isInsertPermissionGrantedToGlobalGuest()) {
|
||||||
generateGrantInsertRoleToExistingObjects(plPgSql);
|
// any user is allowed to insert new rows => no insert check needed
|
||||||
generateInsertPermissionGrantTrigger(plPgSql);
|
return;
|
||||||
generateInsertCheckTrigger(plPgSql);
|
}
|
||||||
plPgSql.writeLn("--//");
|
|
||||||
|
generateInsertGrants(plPgSql);
|
||||||
|
generateInsertPermissionChecks(plPgSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateLiquibaseChangesetHeader(final StringWriter plPgSql) {
|
private void generateInsertGrants(final StringWriter plPgSql) {
|
||||||
|
if (isInsertPermissionIsNotGrantedAtAll()) {
|
||||||
|
generateInsertPermissionTriggerAlwaysDisallow(plPgSql);
|
||||||
|
} else {
|
||||||
|
generateInsertPermissionGrants(plPgSql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateInsertPermissionGrants(final StringWriter plPgSql) {
|
||||||
plPgSql.writeLn("""
|
plPgSql.writeLn("""
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset ${liquibaseTagPrefix}-rbac-INSERT:1 endDelimiter:--//
|
--changeset ${liquibaseTagPrefix}-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
""",
|
""",
|
||||||
with("liquibaseTagPrefix", liquibaseTagPrefix));
|
with("liquibaseTagPrefix", liquibaseTagPrefix));
|
||||||
}
|
|
||||||
|
|
||||||
private void generateGrantInsertRoleToExistingObjects(final StringWriter plPgSql) {
|
getInsertGrants().forEach( g -> {
|
||||||
getOptionalInsertSuperRole().ifPresent( superRoleDef -> {
|
|
||||||
plPgSql.writeLn("""
|
plPgSql.writeLn("""
|
||||||
/*
|
-- granting INSERT permission to ${rawSubTable} ----------------------------
|
||||||
Creates INSERT INTO ${rawSubTableName} permissions for the related ${rawSuperTableName} rows.
|
""",
|
||||||
*/
|
with("rawSubTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()));
|
||||||
do language plpgsql $$
|
|
||||||
declare
|
|
||||||
row ${rawSuperTableName};
|
|
||||||
begin
|
|
||||||
call defineContext('create INSERT INTO ${rawSubTableName} permissions for the related ${rawSuperTableName} rows');
|
|
||||||
|
|
||||||
FOR row IN SELECT * FROM ${rawSuperTableName}${typeCondition}
|
if (isGrantToADifferentTable(g)) {
|
||||||
LOOP
|
plPgSql.writeLn(
|
||||||
call grantPermissionToRole(
|
"""
|
||||||
createPermission(row.uuid, 'INSERT', '${rawSubTableName}'),
|
/*
|
||||||
${rawSuperRoleDescriptor});
|
Grants INSERT INTO ${rawSubTable} permissions to specified role of pre-existing ${rawSuperTable} rows.
|
||||||
END LOOP;
|
*/
|
||||||
END;
|
do language plpgsql $$
|
||||||
$$;
|
declare
|
||||||
""",
|
row ${rawSuperTable};
|
||||||
with("rawSubTableName", rbacDef.getRootEntityAlias().getRawTableName()),
|
begin
|
||||||
with("rawSuperTableName", superRoleDef.getEntityAlias().getRawTableName()),
|
call defineContext('create INSERT INTO ${rawSubTable} permissions for pre-exising ${rawSuperTable} rows');
|
||||||
with("rawSuperRoleDescriptor", toRoleDescriptor(superRoleDef, "row")),
|
|
||||||
with("typeCondition", superRoleDef.getEntityAlias().isCaseDependent()
|
FOR row IN SELECT * FROM ${rawSuperTable}
|
||||||
? "\n\t\t\tWHERE type = '${case}'".replace("${case}", superRoleDef.getEntityAlias().usingCase().value)
|
${whenCondition}
|
||||||
: "")
|
LOOP
|
||||||
);
|
call grantPermissionToRole(
|
||||||
});
|
createPermission(row.uuid, 'INSERT', '${rawSubTable}'),
|
||||||
}
|
${superRoleRef});
|
||||||
|
END LOOP;
|
||||||
|
end;
|
||||||
|
$$;
|
||||||
|
""",
|
||||||
|
with("whenCondition", g.getSuperRoleDef().getEntityAlias().isCaseDependent()
|
||||||
|
// TODO.impl: 'type' needs to be dynamically generated
|
||||||
|
? "WHERE type = '${value}'"
|
||||||
|
.replace("${value}", g.getSuperRoleDef().getEntityAlias().usingCase().value)
|
||||||
|
: "-- unconditional for all rows in that table"),
|
||||||
|
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
|
||||||
|
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()),
|
||||||
|
with("superRoleRef", toRoleDescriptor(g.getSuperRoleDef(), "row")));
|
||||||
|
} else {
|
||||||
|
plPgSql.writeLn("""
|
||||||
|
-- Granting INSERT INTO hs_hosting_asset permissions to specified role of pre-existing hs_hosting_asset rows slipped,
|
||||||
|
-- because there cannot yet be any pre-existing rows in the same table yet.
|
||||||
|
""",
|
||||||
|
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
|
||||||
|
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()));
|
||||||
|
}
|
||||||
|
|
||||||
private void generateInsertPermissionGrantTrigger(final StringWriter plPgSql) {
|
|
||||||
getOptionalInsertSuperRole().ifPresent( superRoleDef -> {
|
|
||||||
plPgSql.writeLn("""
|
plPgSql.writeLn("""
|
||||||
/**
|
/**
|
||||||
Adds ${rawSubTableName} INSERT permission to specified role of new ${rawSuperTableName} rows.
|
Grants ${rawSubTable} INSERT permission to specified role of new ${rawSuperTable} rows.
|
||||||
*/
|
*/
|
||||||
create or replace function ${rawSubTableName}_${rawSuperTableName}_insert_tf()
|
create or replace function new_${rawSubTable}_grants_insert_to_${rawSuperTable}_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
${typeConditionIf}call grantPermissionToRole(
|
${ifConditionThen}
|
||||||
createPermission(NEW.uuid, 'INSERT', '${rawSubTableName}'),
|
call grantPermissionToRole(
|
||||||
${rawSuperRoleDescriptor});${typeConditionEndIf}
|
createPermission(NEW.uuid, 'INSERT', '${rawSubTable}'),
|
||||||
|
${superRoleRef});
|
||||||
|
${ifConditionEnd}
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_${rawSubTableName}_${rawSuperTableName}_insert_tg
|
create trigger z_new_${rawSubTable}_grants_insert_to_${rawSuperTable}_tg
|
||||||
after insert on ${rawSuperTableName}
|
after insert on ${rawSuperTable}
|
||||||
for each row
|
for each row
|
||||||
execute procedure ${rawSubTableName}_${rawSuperTableName}_insert_tf();
|
execute procedure new_${rawSubTable}_grants_insert_to_${rawSuperTable}_tf();
|
||||||
""",
|
""",
|
||||||
with("rawSubTableName", rbacDef.getRootEntityAlias().getRawTableName()),
|
with("ifConditionThen", g.getSuperRoleDef().getEntityAlias().isCaseDependent()
|
||||||
with("rawSuperTableName", superRoleDef.getEntityAlias().getRawTableName()),
|
// TODO.impl: .type needs to be dynamically generated
|
||||||
with("rawSuperRoleDescriptor", toRoleDescriptor(superRoleDef, NEW.name())),
|
? "if NEW.type = '" + g.getSuperRoleDef().getEntityAlias().usingCase().value + "' then"
|
||||||
with("typeConditionIf",
|
: "-- unconditional for all rows in that table"),
|
||||||
superRoleDef.getEntityAlias().isCaseDependent()
|
with("ifConditionEnd", g.getSuperRoleDef().getEntityAlias().isCaseDependent()
|
||||||
? "if NEW.type = '${case}' then\n\t\t".replace("${case}", superRoleDef.getEntityAlias().usingCase().value)
|
? "end if;"
|
||||||
: ""),
|
: "-- end."),
|
||||||
with("typeConditionEndIf", superRoleDef.getEntityAlias().isCaseDependent()
|
with("superRoleRef", toRoleDescriptor(g.getSuperRoleDef(), NEW.name())),
|
||||||
? "\n\tend if;"
|
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
|
||||||
: "")
|
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()));
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateInsertCheckTrigger(final StringWriter plPgSql) {
|
private void generateInsertPermissionTriggerAlwaysDisallow(final StringWriter plPgSql) {
|
||||||
getOptionalInsertGrant().ifPresentOrElse(g -> {
|
|
||||||
if (g.getSuperRoleDef().getEntityAlias().isGlobal()) {
|
|
||||||
switch (g.getSuperRoleDef().getRole()) {
|
|
||||||
case ADMIN -> {
|
|
||||||
generateInsertPermissionTriggerAllowOnlyGlobalAdmin(plPgSql);
|
|
||||||
}
|
|
||||||
case GUEST -> {
|
|
||||||
// no permission check trigger generated, as anybody can insert rows into this table
|
|
||||||
}
|
|
||||||
default -> {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"invalid global role for INSERT permission: " + g.getSuperRoleDef().getRole());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (g.getSuperRoleDef().getEntityAlias().isFetchedByDirectForeignKey()) {
|
|
||||||
generateInsertPermissionTriggerAllowByRoleOfDirectForeignKey(plPgSql, g);
|
|
||||||
} else {
|
|
||||||
generateInsertPermissionTriggerAllowByRoleOfIndirectForeignKey(plPgSql, g);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() -> {
|
|
||||||
System.err.println("WARNING: no explicit INSERT grant for " + rbacDef.getRootEntityAlias().simpleName() + " => implicitly grant INSERT to global:ADMIN");
|
|
||||||
generateInsertPermissionTriggerAllowOnlyGlobalAdmin(plPgSql);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateInsertPermissionTriggerAllowByRoleOfDirectForeignKey(final StringWriter plPgSql, final RbacView.RbacGrantDefinition g) {
|
|
||||||
plPgSql.writeLn("""
|
plPgSql.writeLn("""
|
||||||
/**
|
-- ============================================================================
|
||||||
Checks if the user or assumed roles are allowed to insert a row to ${rawSubTable},
|
--changeset ${liquibaseTagPrefix}-rbac-ALWAYS-DISALLOW-INSERT:1 endDelimiter:--//
|
||||||
where the check is performed by a direct role.
|
-- ----------------------------------------------------------------------------
|
||||||
|
""",
|
||||||
|
with("liquibaseTagPrefix", liquibaseTagPrefix));
|
||||||
|
|
||||||
A direct role is a role depending on a foreign key directly available in the NEW row.
|
|
||||||
*/
|
|
||||||
create or replace function ${rawSubTable}_insert_permission_missing_tf()
|
|
||||||
returns trigger
|
|
||||||
language plpgsql as $$
|
|
||||||
begin
|
|
||||||
raise exception '[403] insert into ${rawSubTable} not allowed for current subjects % (%)',
|
|
||||||
currentSubjects(), currentSubjectsUuids();
|
|
||||||
end; $$;
|
|
||||||
|
|
||||||
create trigger ${rawSubTable}_insert_permission_check_tg
|
|
||||||
before insert on ${rawSubTable}
|
|
||||||
for each row
|
|
||||||
when ( not hasInsertPermission(NEW.${referenceColumn}, 'INSERT', '${rawSubTable}') )
|
|
||||||
execute procedure ${rawSubTable}_insert_permission_missing_tf();
|
|
||||||
""",
|
|
||||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()),
|
|
||||||
with("referenceColumn", g.getSuperRoleDef().getEntityAlias().dependsOnColumName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateInsertPermissionTriggerAllowByRoleOfIndirectForeignKey(
|
|
||||||
final StringWriter plPgSql,
|
|
||||||
final RbacView.RbacGrantDefinition g) {
|
|
||||||
plPgSql.writeLn("""
|
|
||||||
/**
|
|
||||||
Checks if the user or assumed roles are allowed to insert a row to ${rawSubTable},
|
|
||||||
where the check is performed by an indirect role.
|
|
||||||
|
|
||||||
An indirect role is a role which depends on an object uuid which is not a direct foreign key
|
|
||||||
of the source entity, but needs to be fetched via joined tables.
|
|
||||||
*/
|
|
||||||
create or replace function ${rawSubTable}_insert_permission_check_tf()
|
|
||||||
returns trigger
|
|
||||||
language plpgsql as $$
|
|
||||||
|
|
||||||
declare
|
|
||||||
superRoleObjectUuid uuid;
|
|
||||||
|
|
||||||
begin
|
|
||||||
""",
|
|
||||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
|
||||||
plPgSql.chopEmptyLines();
|
|
||||||
plPgSql.indented(2, () -> {
|
|
||||||
plPgSql.writeLn(
|
|
||||||
"superRoleObjectUuid := (" + g.getSuperRoleDef().getEntityAlias().fetchSql().sql + ");\n" +
|
|
||||||
"assert superRoleObjectUuid is not null, 'superRoleObjectUuid must not be null';",
|
|
||||||
with("columns", g.getSuperRoleDef().getEntityAlias().aliasName() + ".uuid"),
|
|
||||||
with("ref", NEW.name()));
|
|
||||||
});
|
|
||||||
plPgSql.writeLn();
|
|
||||||
plPgSql.writeLn("""
|
|
||||||
if ( not hasInsertPermission(superRoleObjectUuid, 'INSERT', '${rawSubTable}') ) then
|
|
||||||
raise exception
|
|
||||||
'[403] insert into ${rawSubTable} not allowed for current subjects % (%)',
|
|
||||||
currentSubjects(), currentSubjectsUuids();
|
|
||||||
end if;
|
|
||||||
return NEW;
|
|
||||||
end; $$;
|
|
||||||
|
|
||||||
create trigger ${rawSubTable}_insert_permission_check_tg
|
|
||||||
before insert on ${rawSubTable}
|
|
||||||
for each row
|
|
||||||
execute procedure ${rawSubTable}_insert_permission_check_tf();
|
|
||||||
|
|
||||||
""",
|
|
||||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateInsertPermissionTriggerAllowOnlyGlobalAdmin(final StringWriter plPgSql) {
|
|
||||||
plPgSql.writeLn("""
|
plPgSql.writeLn("""
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to ${rawSubTable},
|
Checks if the user or assumed roles are allowed to insert a row to ${rawSubTable},
|
||||||
@ -219,17 +150,129 @@ public class InsertTriggerGenerator {
|
|||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
raise exception '[403] insert into ${rawSubTable} not allowed for current subjects % (%)',
|
raise exception '[403] insert into ${rawSubTable} not allowed regardless of current subject, no insert permissions grated at all';
|
||||||
currentSubjects(), currentSubjectsUuids();
|
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger ${rawSubTable}_insert_permission_check_tg
|
create trigger ${rawSubTable}_insert_permission_check_tg
|
||||||
before insert on ${rawSubTable}
|
before insert on ${rawSubTable}
|
||||||
for each row
|
for each row
|
||||||
when ( not isGlobalAdmin() )
|
|
||||||
execute procedure ${rawSubTable}_insert_permission_missing_tf();
|
execute procedure ${rawSubTable}_insert_permission_missing_tf();
|
||||||
""",
|
""",
|
||||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||||
|
|
||||||
|
plPgSql.writeLn("--//");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateInsertPermissionChecks(final StringWriter plPgSql) {
|
||||||
|
generateInsertPermissionsCheckHeader(plPgSql);
|
||||||
|
|
||||||
|
plPgSql.indented(1, () -> {
|
||||||
|
getInsertGrants().forEach(g -> {
|
||||||
|
generateInsertPermissionChecksForSingleGrant(plPgSql, g);
|
||||||
|
});
|
||||||
|
plPgSql.chopTail(" or\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
generateInsertPermissionsChecksFooter(plPgSql);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateInsertPermissionsCheckHeader(final StringWriter plPgSql) {
|
||||||
|
plPgSql.writeLn("""
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset ${rawSubTable}-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks if the user respectively the assumed roles are allowed to insert a row to ${rawSubTable}.
|
||||||
|
*/
|
||||||
|
create or replace function ${rawSubTable}_insert_permission_check_tf()
|
||||||
|
returns trigger
|
||||||
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
superObjectUuid uuid;
|
||||||
|
begin
|
||||||
|
""",
|
||||||
|
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||||
|
plPgSql.chopEmptyLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateInsertPermissionChecksForSingleGrant(final StringWriter plPgSql, final RbacView.RbacGrantDefinition g) {
|
||||||
|
final RbacView.EntityAlias superRoleEntityAlias = g.getSuperRoleDef().getEntityAlias();
|
||||||
|
|
||||||
|
final var caseCondition = g.isConditional()
|
||||||
|
? ("NEW.type in (" + toStringList(g.getForCases()) + ") and ")
|
||||||
|
: "";
|
||||||
|
|
||||||
|
if (g.getSuperRoleDef().isGlobal(GUEST)) {
|
||||||
|
plPgSql.writeLn(
|
||||||
|
"""
|
||||||
|
-- check INSERT INSERT permission for global anyone
|
||||||
|
if ${caseCondition}true then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
""",
|
||||||
|
with("caseCondition", caseCondition));
|
||||||
|
} else if (g.getSuperRoleDef().isGlobal(ADMIN)) {
|
||||||
|
plPgSql.writeLn(
|
||||||
|
"""
|
||||||
|
-- check INSERT INSERT if global ADMIN
|
||||||
|
if ${caseCondition}isGlobalAdmin() then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
""",
|
||||||
|
with("caseCondition", caseCondition));
|
||||||
|
} else if (g.getSuperRoleDef().getEntityAlias().isFetchedByDirectForeignKey()) {
|
||||||
|
plPgSql.writeLn(
|
||||||
|
"""
|
||||||
|
-- check INSERT permission via direct foreign key: NEW.${refColumn}
|
||||||
|
if ${caseCondition}hasInsertPermission(NEW.${refColumn}, '${rawSubTable}') then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
""",
|
||||||
|
with("caseCondition", caseCondition),
|
||||||
|
with("refColumn", superRoleEntityAlias.dependsOnColumName()),
|
||||||
|
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||||
|
} else {
|
||||||
|
plPgSql.writeLn(
|
||||||
|
"""
|
||||||
|
-- check INSERT permission via indirect foreign key: NEW.${refColumn}
|
||||||
|
superObjectUuid := (${fetchSql});
|
||||||
|
assert superObjectUuid is not null, 'object uuid fetched depending on ${rawSubTable}.${refColumn} must not be null, also check fetchSql in RBAC DSL';
|
||||||
|
if ${caseCondition}hasInsertPermission(superObjectUuid, '${rawSubTable}') then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
""",
|
||||||
|
with("caseCondition", caseCondition),
|
||||||
|
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()),
|
||||||
|
with("refColumn", superRoleEntityAlias.dependsOnColumName()),
|
||||||
|
with("fetchSql", g.getSuperRoleDef().getEntityAlias().fetchSql().sql),
|
||||||
|
with("columns", g.getSuperRoleDef().getEntityAlias().aliasName() + ".uuid"),
|
||||||
|
with("ref", NEW.name()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateInsertPermissionsChecksFooter(final StringWriter plPgSql) {
|
||||||
|
plPgSql.writeLn();
|
||||||
|
plPgSql.writeLn("""
|
||||||
|
raise exception '[403] insert into ${rawSubTable} not allowed for current subjects % (%)',
|
||||||
|
currentSubjects(), currentSubjectsUuids();
|
||||||
|
end; $$;
|
||||||
|
|
||||||
|
create trigger ${rawSubTable}_insert_permission_check_tg
|
||||||
|
before insert on ${rawSubTable}
|
||||||
|
for each row
|
||||||
|
execute procedure ${rawSubTable}_insert_permission_check_tf();
|
||||||
|
--//
|
||||||
|
""",
|
||||||
|
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toStringList(final Set<RbacView.CaseDef> cases) {
|
||||||
|
return cases.stream().map(c -> "'" + c.value + "'").collect(joining(", "));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isGrantToADifferentTable(final RbacView.RbacGrantDefinition g) {
|
||||||
|
return !rbacDef.getRootEntityAlias().getRawTableName().equals(g.getSuperRoleDef().getEntityAlias().getRawTableName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream<RbacView.RbacGrantDefinition> getInsertGrants() {
|
private Stream<RbacView.RbacGrantDefinition> getInsertGrants() {
|
||||||
@ -238,6 +281,15 @@ public class InsertTriggerGenerator {
|
|||||||
.filter(g -> g.getPermDef().toCreate && g.getPermDef().getPermission() == INSERT);
|
.filter(g -> g.getPermDef().toCreate && g.getPermDef().getPermission() == INSERT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isInsertPermissionIsNotGrantedAtAll() {
|
||||||
|
return getInsertGrants().findAny().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isInsertPermissionGrantedToGlobalGuest() {
|
||||||
|
return getInsertGrants().anyMatch(g ->
|
||||||
|
g.getSuperRoleDef().getEntityAlias().isGlobal() && g.getSuperRoleDef().getRole() == GUEST);
|
||||||
|
}
|
||||||
|
|
||||||
private Optional<RbacView.RbacGrantDefinition> getOptionalInsertGrant() {
|
private Optional<RbacView.RbacGrantDefinition> getOptionalInsertGrant() {
|
||||||
return getInsertGrants()
|
return getInsertGrants()
|
||||||
.reduce(singleton());
|
.reduce(singleton());
|
||||||
@ -252,7 +304,8 @@ public class InsertTriggerGenerator {
|
|||||||
private static <T> BinaryOperator<T> singleton() {
|
private static <T> BinaryOperator<T> singleton() {
|
||||||
return (x, y) -> {
|
return (x, y) -> {
|
||||||
if ( !x.equals(y) ) {
|
if ( !x.equals(y) ) {
|
||||||
throw new IllegalStateException("only a single INSERT permission grant allowed");
|
return x;
|
||||||
|
// throw new IllegalStateException("only a single INSERT permission grant allowed");
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
};
|
};
|
||||||
|
@ -32,10 +32,10 @@ public class RbacIdentityViewGenerator {
|
|||||||
$idName$);
|
$idName$);
|
||||||
""";
|
""";
|
||||||
case SQL_QUERY -> """
|
case SQL_QUERY -> """
|
||||||
call generateRbacIdentityViewFromQuery('${rawTableName}',
|
call generateRbacIdentityViewFromQuery('${rawTableName}',
|
||||||
$idName$
|
$idName$
|
||||||
${identityViewSqlPart}
|
${identityViewSqlPart}
|
||||||
$idName$);
|
$idName$);
|
||||||
""";
|
""";
|
||||||
default -> throw new IllegalStateException("illegal SQL part given");
|
default -> throw new IllegalStateException("illegal SQL part given");
|
||||||
},
|
},
|
||||||
@ -43,5 +43,6 @@ public class RbacIdentityViewGenerator {
|
|||||||
with("rawTableName", rawTableName));
|
with("rawTableName", rawTableName));
|
||||||
|
|
||||||
plPgSql.writeLn("--//");
|
plPgSql.writeLn("--//");
|
||||||
|
plPgSql.writeLn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import static java.util.Optional.ofNullable;
|
|||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.ROLE_TO_ROLE;
|
||||||
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.SQL.Part.AUTO_FETCH;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.Part.AUTO_FETCH;
|
||||||
import static org.apache.commons.collections4.SetUtils.hashSet;
|
import static org.apache.commons.collections4.SetUtils.hashSet;
|
||||||
@ -62,6 +63,7 @@ public class RbacView {
|
|||||||
private SQL orderBySqlExpression;
|
private SQL orderBySqlExpression;
|
||||||
private EntityAlias rootEntityAliasProxy;
|
private EntityAlias rootEntityAliasProxy;
|
||||||
private RbacRoleDefinition previousRoleDef;
|
private RbacRoleDefinition previousRoleDef;
|
||||||
|
private Set<String> limitDiagramToAliasNames;
|
||||||
private final Map<String, CaseDef> cases = new LinkedHashMap<>() {
|
private final Map<String, CaseDef> cases = new LinkedHashMap<>() {
|
||||||
@Override
|
@Override
|
||||||
public CaseDef put(final String key, final CaseDef value) {
|
public CaseDef put(final String key, final CaseDef value) {
|
||||||
@ -396,8 +398,7 @@ public class RbacView {
|
|||||||
new RbacRoleDefinition(findEntityAlias(mapper.map(roleDef.entityAlias.aliasName)), roleDef.role);
|
new RbacRoleDefinition(findEntityAlias(mapper.map(roleDef.entityAlias.aliasName)), roleDef.role);
|
||||||
});
|
});
|
||||||
copyOf(importedRbacView.getGrantDefs()).forEach(grantDef -> {
|
copyOf(importedRbacView.getGrantDefs()).forEach(grantDef -> {
|
||||||
if ( grantDef.grantType() == RbacGrantDefinition.GrantType.ROLE_TO_ROLE &&
|
if ( grantDef.grantType() == ROLE_TO_ROLE && grantDef.matchesCase(forCase) ) {
|
||||||
(grantDef.forCases == null || grantDef.matchesCase(forCase)) ) {
|
|
||||||
final var importedGrantDef = findOrCreateGrantDef(
|
final var importedGrantDef = findOrCreateGrantDef(
|
||||||
findRbacRole(
|
findRbacRole(
|
||||||
mapper.map(grantDef.getSubRoleDef().entityAlias.aliasName),
|
mapper.map(grantDef.getSubRoleDef().entityAlias.aliasName),
|
||||||
@ -499,6 +500,29 @@ public class RbacView {
|
|||||||
new RbacViewPostgresGenerator(this).generateToChangeLog(Path.of(OUTPUT_BASEDIR, baseFileName + ".sql"));
|
new RbacViewPostgresGenerator(this).generateToChangeLog(Path.of(OUTPUT_BASEDIR, baseFileName + ".sql"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RbacView limitDiagramTo(final String... aliasNames) {
|
||||||
|
this.limitDiagramToAliasNames = Set.of(aliasNames);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean renderInDiagram(final EntityAlias ea) {
|
||||||
|
return limitDiagramToAliasNames == null || limitDiagramToAliasNames.contains(ea.aliasName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean renderInDiagram(final RbacGrantDefinition g) {
|
||||||
|
if ( limitDiagramToAliasNames == null ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return switch (g.grantType()) {
|
||||||
|
case ROLE_TO_USER ->
|
||||||
|
renderInDiagram(g.getSubRoleDef().getEntityAlias());
|
||||||
|
case ROLE_TO_ROLE ->
|
||||||
|
renderInDiagram(g.getSuperRoleDef().getEntityAlias()) && renderInDiagram(g.getSubRoleDef().getEntityAlias());
|
||||||
|
case PERM_TO_ROLE ->
|
||||||
|
renderInDiagram(g.getSuperRoleDef().getEntityAlias()) && renderInDiagram(g.getPermDef().getEntityAlias());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public class RbacGrantBuilder {
|
public class RbacGrantBuilder {
|
||||||
|
|
||||||
private final RbacRoleDefinition superRoleDef;
|
private final RbacRoleDefinition superRoleDef;
|
||||||
@ -535,7 +559,7 @@ public class RbacView {
|
|||||||
private final RbacPermissionDefinition permDef;
|
private final RbacPermissionDefinition permDef;
|
||||||
private boolean assumed = true;
|
private boolean assumed = true;
|
||||||
private boolean toCreate = false;
|
private boolean toCreate = false;
|
||||||
private Set<CaseDef> forCases = new HashSet<>();
|
private Set<CaseDef> forCases = new LinkedHashSet<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
@ -560,11 +584,13 @@ public class RbacView {
|
|||||||
register(this);
|
register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RbacGrantDefinition(final RbacPermissionDefinition permDef, final RbacRoleDefinition roleDef) {
|
public RbacGrantDefinition(final RbacPermissionDefinition permDef, final RbacRoleDefinition roleDef,
|
||||||
|
final CaseDef forCase) {
|
||||||
this.userDef = null;
|
this.userDef = null;
|
||||||
this.subRoleDef = null;
|
this.subRoleDef = null;
|
||||||
this.superRoleDef = roleDef;
|
this.superRoleDef = roleDef;
|
||||||
this.permDef = permDef;
|
this.permDef = permDef;
|
||||||
|
this.forCases = forCase != null ? hashSet(forCase) : null;
|
||||||
register(this);
|
register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,7 +610,7 @@ public class RbacView {
|
|||||||
GrantType grantType() {
|
GrantType grantType() {
|
||||||
return permDef != null ? PERM_TO_ROLE
|
return permDef != null ? PERM_TO_ROLE
|
||||||
: userDef != null ? GrantType.ROLE_TO_USER
|
: userDef != null ? GrantType.ROLE_TO_USER
|
||||||
: GrantType.ROLE_TO_ROLE;
|
: ROLE_TO_ROLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isAssumed() {
|
boolean isAssumed() {
|
||||||
@ -602,9 +628,10 @@ public class RbacView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean matchesCase(final ColumnValue requestedCase) {
|
boolean matchesCase(final ColumnValue requestedCase) {
|
||||||
final var noCasesDefined = forCases.isEmpty();
|
final var noCasesDefined = forCases == null;
|
||||||
final var generateForAllCases = requestedCase == null;
|
final var generateForAllCases = requestedCase == null;
|
||||||
final boolean isGrantedForRequestedCase = forCases.stream().anyMatch(c -> c.isCase(requestedCase));
|
final boolean isGrantedForRequestedCase = forCases == null || forCases.stream().anyMatch(c -> c.isCase(requestedCase))
|
||||||
|
|| forCases.stream().anyMatch(CaseDef::isDefaultCase) && !allCases.stream().anyMatch(c -> c.isCase(requestedCase));
|
||||||
return noCasesDefined || generateForAllCases || isGrantedForRequestedCase;
|
return noCasesDefined || generateForAllCases || isGrantedForRequestedCase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,7 +703,8 @@ public class RbacView {
|
|||||||
final String tableName;
|
final String tableName;
|
||||||
final boolean toCreate;
|
final boolean toCreate;
|
||||||
|
|
||||||
private RbacPermissionDefinition(final EntityAlias entityAlias, final Permission permission, final String tableName, final boolean toCreate) {
|
private RbacPermissionDefinition(final EntityAlias entityAlias, final Permission permission, final String tableName,
|
||||||
|
final boolean toCreate) {
|
||||||
this.entityAlias = entityAlias;
|
this.entityAlias = entityAlias;
|
||||||
this.permission = permission;
|
this.permission = permission;
|
||||||
this.tableName = tableName;
|
this.tableName = tableName;
|
||||||
@ -788,6 +816,10 @@ public class RbacView {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "role:" + entityAlias.aliasName + role;
|
return "role:" + entityAlias.aliasName + role;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isGlobal(final Role role) {
|
||||||
|
return entityAlias.isGlobal() && this.role == role;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public RbacUserReference findUserRef(final RbacUserReference.UserRole userRole) {
|
public RbacUserReference findUserRef(final RbacUserReference.UserRole userRole) {
|
||||||
@ -842,19 +874,6 @@ public class RbacView {
|
|||||||
.orElseGet(() -> new RbacPermissionDefinition(entityAlias, perm, tableName, true)); // TODO: true => toCreate
|
.orElseGet(() -> new RbacPermissionDefinition(entityAlias, perm, tableName, true)); // TODO: true => toCreate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RbacPermissionDefinition findRbacPerm(final EntityAlias entityAlias, final Permission perm) {
|
|
||||||
return findRbacPerm(entityAlias, perm, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RbacPermissionDefinition findRbacPerm(final String entityAliasName, final Permission perm, String tableName) {
|
|
||||||
return findRbacPerm(findEntityAlias(entityAliasName), perm, tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RbacPermissionDefinition findRbacPerm(final String entityAliasName, final Permission perm) {
|
|
||||||
return findRbacPerm(findEntityAlias(entityAliasName), perm);
|
|
||||||
}
|
|
||||||
|
|
||||||
private RbacGrantDefinition findOrCreateGrantDef(final RbacRoleDefinition roleDefinition, final RbacUserReference user) {
|
private RbacGrantDefinition findOrCreateGrantDef(final RbacRoleDefinition roleDefinition, final RbacUserReference user) {
|
||||||
return grantDefs.stream()
|
return grantDefs.stream()
|
||||||
.filter(g -> g.subRoleDef == roleDefinition && g.userDef == user)
|
.filter(g -> g.subRoleDef == roleDefinition && g.userDef == user)
|
||||||
@ -866,7 +885,8 @@ public class RbacView {
|
|||||||
return grantDefs.stream()
|
return grantDefs.stream()
|
||||||
.filter(g -> g.permDef == permDef && g.superRoleDef == roleDef)
|
.filter(g -> g.permDef == permDef && g.superRoleDef == roleDef)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseGet(() -> new RbacGrantDefinition(permDef, roleDef));
|
.map(g -> g.forCase(processingCase))
|
||||||
|
.orElseGet(() -> new RbacGrantDefinition(permDef, roleDef, processingCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
private RbacGrantDefinition findOrCreateGrantDef(
|
private RbacGrantDefinition findOrCreateGrantDef(
|
||||||
|
@ -5,7 +5,12 @@ import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static java.util.Comparator.comparing;
|
||||||
import static java.util.stream.Collectors.joining;
|
import static java.util.stream.Collectors.joining;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.*;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.*;
|
||||||
|
|
||||||
@ -15,17 +20,28 @@ public class RbacViewMermaidFlowchartGenerator {
|
|||||||
public static final String HOSTSHARING_LIGHT_ORANGE = "#feb28c";
|
public static final String HOSTSHARING_LIGHT_ORANGE = "#feb28c";
|
||||||
public static final String HOSTSHARING_DARK_BLUE = "#274d6e";
|
public static final String HOSTSHARING_DARK_BLUE = "#274d6e";
|
||||||
public static final String HOSTSHARING_LIGHT_BLUE = "#99bcdb";
|
public static final String HOSTSHARING_LIGHT_BLUE = "#99bcdb";
|
||||||
|
|
||||||
// TODO.rbac: implement level limit for all renderable items and remove items which not part of a grant
|
|
||||||
private static final long MAX_LEVEL_TO_RENDER = 3;
|
|
||||||
private final RbacView rbacDef;
|
private final RbacView rbacDef;
|
||||||
|
|
||||||
|
private final List<RbacView.EntityAlias> usedEntityAliases;
|
||||||
|
|
||||||
private final CaseDef forCase;
|
private final CaseDef forCase;
|
||||||
private final StringWriter flowchart = new StringWriter();
|
private final StringWriter flowchart = new StringWriter();
|
||||||
|
|
||||||
public RbacViewMermaidFlowchartGenerator(final RbacView rbacDef, final CaseDef forCase) {
|
public RbacViewMermaidFlowchartGenerator(final RbacView rbacDef, final CaseDef forCase) {
|
||||||
this.rbacDef = rbacDef;
|
this.rbacDef = rbacDef;
|
||||||
this.forCase = forCase;
|
this.forCase = forCase;
|
||||||
|
|
||||||
|
usedEntityAliases = rbacDef.getGrantDefs().stream()
|
||||||
|
.flatMap(g -> Stream.of(
|
||||||
|
g.getSuperRoleDef() != null ? g.getSuperRoleDef().getEntityAlias() : null,
|
||||||
|
g.getSubRoleDef() != null ? g.getSubRoleDef().getEntityAlias() : null,
|
||||||
|
g.getPermDef() != null ? g.getPermDef().getEntityAlias() : null))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.sorted(comparing(RbacView.EntityAlias::aliasName))
|
||||||
|
.distinct()
|
||||||
|
.filter(rbacDef::renderInDiagram)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
flowchart.writeLn("""
|
flowchart.writeLn("""
|
||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
@ -38,13 +54,18 @@ public class RbacViewMermaidFlowchartGenerator {
|
|||||||
this(rbacDef, null);
|
this(rbacDef, null);
|
||||||
}
|
}
|
||||||
private void renderEntitySubgraphs() {
|
private void renderEntitySubgraphs() {
|
||||||
rbacDef.getEntityAliases().values().stream()
|
usedEntityAliases.stream()
|
||||||
.filter(entityAlias -> !rbacDef.isEntityAliasProxy(entityAlias))
|
.filter(entityAlias -> !rbacDef.isEntityAliasProxy(entityAlias))
|
||||||
.filter(entityAlias -> !entityAlias.isPlaceholder())
|
.filter(entityAlias -> !entityAlias.isPlaceholder())
|
||||||
|
.filter(rbacDef::renderInDiagram)
|
||||||
.forEach(this::renderEntitySubgraph);
|
.forEach(this::renderEntitySubgraph);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderEntitySubgraph(final RbacView.EntityAlias entity) {
|
private void renderEntitySubgraph(final RbacView.EntityAlias entity) {
|
||||||
|
if (!rbacDef.renderInDiagram(entity)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final var color = rbacDef.isRootEntityAlias(entity) ? HOSTSHARING_DARK_ORANGE
|
final var color = rbacDef.isRootEntityAlias(entity) ? HOSTSHARING_DARK_ORANGE
|
||||||
: entity.isSubEntity() ? HOSTSHARING_LIGHT_ORANGE
|
: entity.isSubEntity() ? HOSTSHARING_LIGHT_ORANGE
|
||||||
: HOSTSHARING_LIGHT_BLUE;
|
: HOSTSHARING_LIGHT_BLUE;
|
||||||
@ -58,8 +79,7 @@ public class RbacViewMermaidFlowchartGenerator {
|
|||||||
.replace("%{strokeColor}", HOSTSHARING_DARK_BLUE ));
|
.replace("%{strokeColor}", HOSTSHARING_DARK_BLUE ));
|
||||||
|
|
||||||
flowchart.indented( () -> {
|
flowchart.indented( () -> {
|
||||||
rbacDef.getEntityAliases().values().stream()
|
usedEntityAliases.stream()
|
||||||
.filter(e -> e.level() <= MAX_LEVEL_TO_RENDER)
|
|
||||||
.filter(e -> e.aliasName().startsWith(entity.aliasName() + ":"))
|
.filter(e -> e.aliasName().startsWith(entity.aliasName() + ":"))
|
||||||
.forEach(this::renderEntitySubgraph);
|
.forEach(this::renderEntitySubgraph);
|
||||||
|
|
||||||
@ -110,9 +130,9 @@ public class RbacViewMermaidFlowchartGenerator {
|
|||||||
|
|
||||||
private void renderGrants(final RbacView.RbacGrantDefinition.GrantType grantType, final String comment) {
|
private void renderGrants(final RbacView.RbacGrantDefinition.GrantType grantType, final String comment) {
|
||||||
final var grantsOfRequestedType = rbacDef.getGrantDefs().stream()
|
final var grantsOfRequestedType = rbacDef.getGrantDefs().stream()
|
||||||
.filter(g -> g.level() <= MAX_LEVEL_TO_RENDER)
|
|
||||||
.filter(g -> g.grantType() == grantType)
|
.filter(g -> g.grantType() == grantType)
|
||||||
.filter(this::isToBeRenderedInThisGraph)
|
.filter(rbacDef::renderInDiagram)
|
||||||
|
.filter(this::isToBeRenderedForThisCase)
|
||||||
.toList();
|
.toList();
|
||||||
if ( !grantsOfRequestedType.isEmpty()) {
|
if ( !grantsOfRequestedType.isEmpty()) {
|
||||||
flowchart.ensureSingleEmptyLine();
|
flowchart.ensureSingleEmptyLine();
|
||||||
@ -121,8 +141,8 @@ public class RbacViewMermaidFlowchartGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isToBeRenderedInThisGraph(final RbacView.RbacGrantDefinition g) {
|
private boolean isToBeRenderedForThisCase(final RbacView.RbacGrantDefinition g) {
|
||||||
if ( g.grantType() != ROLE_TO_ROLE )
|
if ( g.grantType() == ROLE_TO_USER )
|
||||||
return true;
|
return true;
|
||||||
if ( forCase == null && !g.isConditional() )
|
if ( forCase == null && !g.isConditional() )
|
||||||
return true;
|
return true;
|
||||||
|
@ -2,8 +2,6 @@ package net.hostsharing.hsadminng.rbac.rbacdef;
|
|||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import static java.util.Arrays.stream;
|
import static java.util.Arrays.stream;
|
||||||
import static java.util.stream.Collectors.joining;
|
import static java.util.stream.Collectors.joining;
|
||||||
|
|
||||||
@ -111,9 +109,11 @@ public class StringWriter {
|
|||||||
String apply(final String textToAppend) {
|
String apply(final String textToAppend) {
|
||||||
text = textToAppend;
|
text = textToAppend;
|
||||||
stream(varDefs).forEach(varDef -> {
|
stream(varDefs).forEach(varDef -> {
|
||||||
final var pattern = Pattern.compile("\\$\\{" + varDef.name() + "}", Pattern.CASE_INSENSITIVE);
|
// TODO.impl: I actually want a case-independent search+replace but ...
|
||||||
final var matcher = pattern.matcher(text);
|
// for which the substitution String can contain sequences of "${...}" to be replaced by further varDefs.
|
||||||
text = matcher.replaceAll(varDef.value());
|
text = text.replace("${" + varDef.name() + "}", varDef.value());
|
||||||
|
text = text.replace("${" + varDef.name().toUpperCase() + "}", varDef.value());
|
||||||
|
text = text.replace("${" + varDef.name().toLowerCase() + "}", varDef.value());
|
||||||
});
|
});
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
--liquibase formatted sql
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- RAISE-FUNCTIONS
|
||||||
|
--changeset RAISE-FUNCTIONS:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
Like RAISE EXCEPTION ... just as an expression instead of a statement.
|
||||||
|
*/
|
||||||
|
create or replace function raiseException(msg text)
|
||||||
|
returns varchar
|
||||||
|
language plpgsql as $$
|
||||||
|
begin
|
||||||
|
raise exception using message = msg;
|
||||||
|
end; $$;
|
||||||
|
--//
|
@ -569,14 +569,14 @@ select exists(
|
|||||||
);
|
);
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
create or replace function hasInsertPermission(objectUuid uuid, forOp RbacOp, tableName text )
|
create or replace function hasInsertPermission(objectUuid uuid, tableName text )
|
||||||
returns BOOL
|
returns BOOL
|
||||||
stable -- leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
permissionUuid uuid;
|
permissionUuid uuid;
|
||||||
begin
|
begin
|
||||||
permissionUuid = findPermissionId(objectUuid, forOp, tableName);
|
permissionUuid = findPermissionId(objectUuid, 'INSERT'::RbacOp, tableName);
|
||||||
return permissionUuid is not null;
|
return permissionUuid is not null;
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
@ -77,66 +77,82 @@ execute procedure insertTriggerForTestCustomer_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset test-customer-rbac-INSERT:1 endDelimiter:--//
|
--changeset test-customer-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- granting INSERT permission to global ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates INSERT INTO test_customer permissions for the related global rows.
|
Grants INSERT INTO test_customer permissions to specified role of pre-existing global rows.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
row global;
|
row global;
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO test_customer permissions for the related global rows');
|
call defineContext('create INSERT INTO test_customer permissions for pre-exising global rows');
|
||||||
|
|
||||||
FOR row IN SELECT * FROM global
|
FOR row IN SELECT * FROM global
|
||||||
|
-- unconditional for all rows in that table
|
||||||
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;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds test_customer INSERT permission to specified role of new global rows.
|
Grants test_customer INSERT permission to specified role of new global rows.
|
||||||
*/
|
*/
|
||||||
create or replace function test_customer_global_insert_tf()
|
create or replace function new_test_customer_grants_insert_to_global_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
-- unconditional for all rows in that table
|
||||||
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'test_customer'),
|
createPermission(NEW.uuid, 'INSERT', 'test_customer'),
|
||||||
globalADMIN());
|
globalADMIN());
|
||||||
|
-- end.
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_test_customer_global_insert_tg
|
create trigger z_new_test_customer_grants_insert_to_global_tg
|
||||||
after insert on global
|
after insert on global
|
||||||
for each row
|
for each row
|
||||||
execute procedure test_customer_global_insert_tf();
|
execute procedure new_test_customer_grants_insert_to_global_tf();
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset test_customer-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to test_customer,
|
Checks if the user respectively the assumed roles are allowed to insert a row to test_customer.
|
||||||
where only global-admin has that permission.
|
|
||||||
*/
|
*/
|
||||||
create or replace function test_customer_insert_permission_missing_tf()
|
create or replace function test_customer_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
superObjectUuid uuid;
|
||||||
begin
|
begin
|
||||||
|
-- check INSERT INSERT if global ADMIN
|
||||||
|
if isGlobalAdmin() then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
|
||||||
raise exception '[403] insert into test_customer not allowed for current subjects % (%)',
|
raise exception '[403] insert into test_customer not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger test_customer_insert_permission_check_tg
|
create trigger test_customer_insert_permission_check_tg
|
||||||
before insert on test_customer
|
before insert on test_customer
|
||||||
for each row
|
for each row
|
||||||
when ( not isGlobalAdmin() )
|
execute procedure test_customer_insert_permission_check_tf();
|
||||||
execute procedure test_customer_insert_permission_missing_tf();
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset test-customer-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset test-customer-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
@ -147,6 +163,7 @@ call generateRbacIdentityViewFromProjection('test_customer',
|
|||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset test-customer-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset test-customer-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -6,6 +6,19 @@ This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manua
|
|||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
|
subgraph customer["`**customer**`"]
|
||||||
|
direction TB
|
||||||
|
style customer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph customer:roles[ ]
|
||||||
|
style customer:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:customer:OWNER[[customer:OWNER]]
|
||||||
|
role:customer:ADMIN[[customer:ADMIN]]
|
||||||
|
role:customer:TENANT[[customer:TENANT]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
subgraph package["`**package**`"]
|
subgraph package["`**package**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style package fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
style package fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
@ -28,19 +41,6 @@ subgraph package["`**package**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph customer["`**customer**`"]
|
|
||||||
direction TB
|
|
||||||
style customer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph customer:roles[ ]
|
|
||||||
style customer:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:customer:OWNER[[customer:OWNER]]
|
|
||||||
role:customer:ADMIN[[customer:ADMIN]]
|
|
||||||
role:customer:TENANT[[customer:TENANT]]
|
|
||||||
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
|
||||||
|
@ -142,68 +142,82 @@ execute procedure updateTriggerForTestPackage_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset test-package-rbac-INSERT:1 endDelimiter:--//
|
--changeset test-package-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- granting INSERT permission to test_customer ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates INSERT INTO test_package permissions for the related test_customer rows.
|
Grants INSERT INTO test_package permissions to specified role of pre-existing test_customer rows.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
row test_customer;
|
row test_customer;
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO test_package permissions for the related test_customer rows');
|
call defineContext('create INSERT INTO test_package permissions for pre-exising test_customer rows');
|
||||||
|
|
||||||
FOR row IN SELECT * FROM test_customer
|
FOR row IN SELECT * FROM test_customer
|
||||||
|
-- unconditional for all rows in that table
|
||||||
LOOP
|
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;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds test_package INSERT permission to specified role of new test_customer rows.
|
Grants test_package INSERT permission to specified role of new test_customer rows.
|
||||||
*/
|
*/
|
||||||
create or replace function test_package_test_customer_insert_tf()
|
create or replace function new_test_package_grants_insert_to_test_customer_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
-- unconditional for all rows in that table
|
||||||
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'test_package'),
|
createPermission(NEW.uuid, 'INSERT', 'test_package'),
|
||||||
testCustomerADMIN(NEW));
|
testCustomerADMIN(NEW));
|
||||||
|
-- end.
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_test_package_test_customer_insert_tg
|
create trigger z_new_test_package_grants_insert_to_test_customer_tg
|
||||||
after insert on test_customer
|
after insert on test_customer
|
||||||
for each row
|
for each row
|
||||||
execute procedure test_package_test_customer_insert_tf();
|
execute procedure new_test_package_grants_insert_to_test_customer_tf();
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset test_package-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to test_package,
|
Checks if the user respectively the assumed roles are allowed to insert a row to test_package.
|
||||||
where the check is performed by a direct role.
|
|
||||||
|
|
||||||
A direct role is a role depending on a foreign key directly available in the NEW row.
|
|
||||||
*/
|
*/
|
||||||
create or replace function test_package_insert_permission_missing_tf()
|
create or replace function test_package_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
superObjectUuid uuid;
|
||||||
begin
|
begin
|
||||||
|
-- check INSERT permission via direct foreign key: NEW.customerUuid
|
||||||
|
if hasInsertPermission(NEW.customerUuid, 'test_package') then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
|
||||||
raise exception '[403] insert into test_package not allowed for current subjects % (%)',
|
raise exception '[403] insert into test_package not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger test_package_insert_permission_check_tg
|
create trigger test_package_insert_permission_check_tg
|
||||||
before insert on test_package
|
before insert on test_package
|
||||||
for each row
|
for each row
|
||||||
when ( not hasInsertPermission(NEW.customerUuid, 'INSERT', 'test_package') )
|
execute procedure test_package_insert_permission_check_tf();
|
||||||
execute procedure test_package_insert_permission_missing_tf();
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset test-package-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset test-package-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
@ -214,6 +228,7 @@ call generateRbacIdentityViewFromProjection('test_package',
|
|||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset test-package-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset test-package-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -6,32 +6,6 @@ This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manua
|
|||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
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["`**package**`"]
|
|
||||||
direction TB
|
|
||||||
style package fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph package:roles[ ]
|
|
||||||
style package:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:package:OWNER[[package:OWNER]]
|
|
||||||
role:package:ADMIN[[package:ADMIN]]
|
|
||||||
role:package:TENANT[[package:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph domain["`**domain**`"]
|
subgraph domain["`**domain**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style domain fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
style domain fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
@ -53,6 +27,32 @@ subgraph domain["`**domain**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
subgraph package["`**package**`"]
|
||||||
|
direction TB
|
||||||
|
style package fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph package:roles[ ]
|
||||||
|
style package:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:package:OWNER[[package:OWNER]]
|
||||||
|
role:package:ADMIN[[package:ADMIN]]
|
||||||
|
role:package:TENANT[[package:TENANT]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
%% 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
|
||||||
|
@ -141,68 +141,82 @@ execute procedure updateTriggerForTestDomain_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset test-domain-rbac-INSERT:1 endDelimiter:--//
|
--changeset test-domain-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- granting INSERT permission to test_package ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates INSERT INTO test_domain permissions for the related test_package rows.
|
Grants INSERT INTO test_domain permissions to specified role of pre-existing test_package rows.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
row test_package;
|
row test_package;
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO test_domain permissions for the related test_package rows');
|
call defineContext('create INSERT INTO test_domain permissions for pre-exising test_package rows');
|
||||||
|
|
||||||
FOR row IN SELECT * FROM test_package
|
FOR row IN SELECT * FROM test_package
|
||||||
|
-- unconditional for all rows in that table
|
||||||
LOOP
|
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;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds test_domain INSERT permission to specified role of new test_package rows.
|
Grants test_domain INSERT permission to specified role of new test_package rows.
|
||||||
*/
|
*/
|
||||||
create or replace function test_domain_test_package_insert_tf()
|
create or replace function new_test_domain_grants_insert_to_test_package_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
-- unconditional for all rows in that table
|
||||||
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'test_domain'),
|
createPermission(NEW.uuid, 'INSERT', 'test_domain'),
|
||||||
testPackageADMIN(NEW));
|
testPackageADMIN(NEW));
|
||||||
|
-- end.
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_test_domain_test_package_insert_tg
|
create trigger z_new_test_domain_grants_insert_to_test_package_tg
|
||||||
after insert on test_package
|
after insert on test_package
|
||||||
for each row
|
for each row
|
||||||
execute procedure test_domain_test_package_insert_tf();
|
execute procedure new_test_domain_grants_insert_to_test_package_tf();
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset test_domain-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to test_domain,
|
Checks if the user respectively the assumed roles are allowed to insert a row to test_domain.
|
||||||
where the check is performed by a direct role.
|
|
||||||
|
|
||||||
A direct role is a role depending on a foreign key directly available in the NEW row.
|
|
||||||
*/
|
*/
|
||||||
create or replace function test_domain_insert_permission_missing_tf()
|
create or replace function test_domain_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
superObjectUuid uuid;
|
||||||
begin
|
begin
|
||||||
|
-- check INSERT permission via direct foreign key: NEW.packageUuid
|
||||||
|
if hasInsertPermission(NEW.packageUuid, 'test_domain') then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
|
||||||
raise exception '[403] insert into test_domain not allowed for current subjects % (%)',
|
raise exception '[403] insert into test_domain not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger test_domain_insert_permission_check_tg
|
create trigger test_domain_insert_permission_check_tg
|
||||||
before insert on test_domain
|
before insert on test_domain
|
||||||
for each row
|
for each row
|
||||||
when ( not hasInsertPermission(NEW.packageUuid, 'INSERT', 'test_domain') )
|
execute procedure test_domain_insert_permission_check_tf();
|
||||||
execute procedure test_domain_insert_permission_missing_tf();
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset test-domain-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset test-domain-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
@ -213,6 +227,7 @@ call generateRbacIdentityViewFromProjection('test_domain',
|
|||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset test-domain-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset test-domain-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -76,49 +76,6 @@ execute procedure insertTriggerForHsOfficeContact_tf();
|
|||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
|
||||||
--changeset hs-office-contact-rbac-INSERT:1 endDelimiter:--//
|
|
||||||
-- ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/*
|
|
||||||
Creates INSERT INTO hs_office_contact permissions for the related global rows.
|
|
||||||
*/
|
|
||||||
do language plpgsql $$
|
|
||||||
declare
|
|
||||||
row global;
|
|
||||||
begin
|
|
||||||
call defineContext('create INSERT INTO hs_office_contact permissions for the related global rows');
|
|
||||||
|
|
||||||
FOR row IN SELECT * FROM global
|
|
||||||
LOOP
|
|
||||||
call grantPermissionToRole(
|
|
||||||
createPermission(row.uuid, 'INSERT', 'hs_office_contact'),
|
|
||||||
globalGUEST());
|
|
||||||
END LOOP;
|
|
||||||
END;
|
|
||||||
$$;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Adds hs_office_contact INSERT permission to specified role of new global rows.
|
|
||||||
*/
|
|
||||||
create or replace function hs_office_contact_global_insert_tf()
|
|
||||||
returns trigger
|
|
||||||
language plpgsql
|
|
||||||
strict as $$
|
|
||||||
begin
|
|
||||||
call grantPermissionToRole(
|
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_contact'),
|
|
||||||
globalGUEST());
|
|
||||||
return NEW;
|
|
||||||
end; $$;
|
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
|
||||||
create trigger z_hs_office_contact_global_insert_tg
|
|
||||||
after insert on global
|
|
||||||
for each row
|
|
||||||
execute procedure hs_office_contact_global_insert_tf();
|
|
||||||
--//
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-contact-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-contact-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
@ -129,6 +86,7 @@ call generateRbacIdentityViewFromProjection('hs_office_contact',
|
|||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-contact-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-contact-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -76,49 +76,6 @@ execute procedure insertTriggerForHsOfficePerson_tf();
|
|||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
|
||||||
--changeset hs-office-person-rbac-INSERT:1 endDelimiter:--//
|
|
||||||
-- ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/*
|
|
||||||
Creates INSERT INTO hs_office_person permissions for the related global rows.
|
|
||||||
*/
|
|
||||||
do language plpgsql $$
|
|
||||||
declare
|
|
||||||
row global;
|
|
||||||
begin
|
|
||||||
call defineContext('create INSERT INTO hs_office_person permissions for the related global rows');
|
|
||||||
|
|
||||||
FOR row IN SELECT * FROM global
|
|
||||||
LOOP
|
|
||||||
call grantPermissionToRole(
|
|
||||||
createPermission(row.uuid, 'INSERT', 'hs_office_person'),
|
|
||||||
globalGUEST());
|
|
||||||
END LOOP;
|
|
||||||
END;
|
|
||||||
$$;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Adds hs_office_person INSERT permission to specified role of new global rows.
|
|
||||||
*/
|
|
||||||
create or replace function hs_office_person_global_insert_tf()
|
|
||||||
returns trigger
|
|
||||||
language plpgsql
|
|
||||||
strict as $$
|
|
||||||
begin
|
|
||||||
call grantPermissionToRole(
|
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_person'),
|
|
||||||
globalGUEST());
|
|
||||||
return NEW;
|
|
||||||
end; $$;
|
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
|
||||||
create trigger z_hs_office_person_global_insert_tg
|
|
||||||
after insert on global
|
|
||||||
for each row
|
|
||||||
execute procedure hs_office_person_global_insert_tf();
|
|
||||||
--//
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-person-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-person-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
@ -129,6 +86,7 @@ call generateRbacIdentityViewFromProjection('hs_office_person',
|
|||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-person-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-person-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -6,19 +6,6 @@ This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manua
|
|||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
subgraph holderPerson["`**holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph holderPerson:roles[ ]
|
|
||||||
style holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:holderPerson:OWNER[[holderPerson:OWNER]]
|
|
||||||
role:holderPerson:ADMIN[[holderPerson:ADMIN]]
|
|
||||||
role:holderPerson:REFERRER[[holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph anchorPerson["`**anchorPerson**`"]
|
subgraph anchorPerson["`**anchorPerson**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
@ -45,6 +32,19 @@ subgraph contact["`**contact**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
subgraph holderPerson["`**holderPerson**`"]
|
||||||
|
direction TB
|
||||||
|
style holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph holderPerson:roles[ ]
|
||||||
|
style holderPerson:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:holderPerson:OWNER[[holderPerson:OWNER]]
|
||||||
|
role:holderPerson:ADMIN[[holderPerson:ADMIN]]
|
||||||
|
role:holderPerson:REFERRER[[holderPerson:REFERRER]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
subgraph relation["`**relation**`"]
|
subgraph relation["`**relation**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style relation fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
style relation fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
|
@ -6,19 +6,6 @@ This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manua
|
|||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
subgraph holderPerson["`**holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph holderPerson:roles[ ]
|
|
||||||
style holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:holderPerson:OWNER[[holderPerson:OWNER]]
|
|
||||||
role:holderPerson:ADMIN[[holderPerson:ADMIN]]
|
|
||||||
role:holderPerson:REFERRER[[holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph anchorPerson["`**anchorPerson**`"]
|
subgraph anchorPerson["`**anchorPerson**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
@ -45,6 +32,19 @@ subgraph contact["`**contact**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
subgraph holderPerson["`**holderPerson**`"]
|
||||||
|
direction TB
|
||||||
|
style holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph holderPerson:roles[ ]
|
||||||
|
style holderPerson:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:holderPerson:OWNER[[holderPerson:OWNER]]
|
||||||
|
role:holderPerson:ADMIN[[holderPerson:ADMIN]]
|
||||||
|
role:holderPerson:REFERRER[[holderPerson:REFERRER]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
subgraph relation["`**relation**`"]
|
subgraph relation["`**relation**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style relation fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
style relation fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
|
@ -151,68 +151,82 @@ execute procedure updateTriggerForHsOfficeRelation_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-relation-rbac-INSERT:1 endDelimiter:--//
|
--changeset hs-office-relation-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- granting INSERT permission to hs_office_person ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates INSERT INTO hs_office_relation permissions for the related hs_office_person rows.
|
Grants INSERT INTO hs_office_relation permissions to specified role of pre-existing hs_office_person rows.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
row hs_office_person;
|
row hs_office_person;
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO hs_office_relation permissions for the related hs_office_person rows');
|
call defineContext('create INSERT INTO hs_office_relation permissions for pre-exising hs_office_person rows');
|
||||||
|
|
||||||
FOR row IN SELECT * FROM hs_office_person
|
FOR row IN SELECT * FROM hs_office_person
|
||||||
|
-- unconditional for all rows in that table
|
||||||
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;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds hs_office_relation INSERT permission to specified role of new hs_office_person rows.
|
Grants hs_office_relation INSERT permission to specified role of new hs_office_person rows.
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_relation_hs_office_person_insert_tf()
|
create or replace function new_hs_office_relation_grants_insert_to_hs_office_person_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
-- unconditional for all rows in that table
|
||||||
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_relation'),
|
createPermission(NEW.uuid, 'INSERT', 'hs_office_relation'),
|
||||||
hsOfficePersonADMIN(NEW));
|
hsOfficePersonADMIN(NEW));
|
||||||
|
-- end.
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_hs_office_relation_hs_office_person_insert_tg
|
create trigger z_new_hs_office_relation_grants_insert_to_hs_office_person_tg
|
||||||
after insert on hs_office_person
|
after insert on hs_office_person
|
||||||
for each row
|
for each row
|
||||||
execute procedure hs_office_relation_hs_office_person_insert_tf();
|
execute procedure new_hs_office_relation_grants_insert_to_hs_office_person_tf();
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs_office_relation-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_relation,
|
Checks if the user respectively the assumed roles are allowed to insert a row to hs_office_relation.
|
||||||
where the check is performed by a direct role.
|
|
||||||
|
|
||||||
A direct role is a role depending on a foreign key directly available in the NEW row.
|
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_relation_insert_permission_missing_tf()
|
create or replace function hs_office_relation_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
superObjectUuid uuid;
|
||||||
begin
|
begin
|
||||||
|
-- check INSERT permission via direct foreign key: NEW.anchorUuid
|
||||||
|
if hasInsertPermission(NEW.anchorUuid, 'hs_office_relation') then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
|
||||||
raise exception '[403] insert into hs_office_relation not allowed for current subjects % (%)',
|
raise exception '[403] insert into hs_office_relation not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger hs_office_relation_insert_permission_check_tg
|
create trigger hs_office_relation_insert_permission_check_tg
|
||||||
before insert on hs_office_relation
|
before insert on hs_office_relation
|
||||||
for each row
|
for each row
|
||||||
when ( not hasInsertPermission(NEW.anchorUuid, 'INSERT', 'hs_office_relation') )
|
execute procedure hs_office_relation_insert_permission_check_tf();
|
||||||
execute procedure hs_office_relation_insert_permission_missing_tf();
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-relation-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-relation-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
@ -225,6 +239,7 @@ call generateRbacIdentityViewFromProjection('hs_office_relation',
|
|||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-relation-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-relation-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -6,19 +6,6 @@ This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manua
|
|||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
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 partner["`**partner**`"]
|
subgraph partner["`**partner**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style partner fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
style partner fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
@ -73,6 +60,19 @@ subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
|
|||||||
end
|
end
|
||||||
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.holderPerson["`**partnerRel.holderPerson**`"]
|
subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
@ -154,66 +154,82 @@ execute procedure updateTriggerForHsOfficePartner_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-partner-rbac-INSERT:1 endDelimiter:--//
|
--changeset hs-office-partner-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- granting INSERT permission to global ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates INSERT INTO hs_office_partner permissions for the related global rows.
|
Grants INSERT INTO hs_office_partner permissions to specified role of pre-existing global rows.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
row global;
|
row global;
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO hs_office_partner permissions for the related global rows');
|
call defineContext('create INSERT INTO hs_office_partner permissions for pre-exising global rows');
|
||||||
|
|
||||||
FOR row IN SELECT * FROM global
|
FOR row IN SELECT * FROM global
|
||||||
|
-- unconditional for all rows in that table
|
||||||
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;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds hs_office_partner INSERT permission to specified role of new global rows.
|
Grants hs_office_partner INSERT permission to specified role of new global rows.
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_partner_global_insert_tf()
|
create or replace function new_hs_office_partner_grants_insert_to_global_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
-- unconditional for all rows in that table
|
||||||
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_partner'),
|
createPermission(NEW.uuid, 'INSERT', 'hs_office_partner'),
|
||||||
globalADMIN());
|
globalADMIN());
|
||||||
|
-- end.
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_hs_office_partner_global_insert_tg
|
create trigger z_new_hs_office_partner_grants_insert_to_global_tg
|
||||||
after insert on global
|
after insert on global
|
||||||
for each row
|
for each row
|
||||||
execute procedure hs_office_partner_global_insert_tf();
|
execute procedure new_hs_office_partner_grants_insert_to_global_tf();
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs_office_partner-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_partner,
|
Checks if the user respectively the assumed roles are allowed to insert a row to hs_office_partner.
|
||||||
where only global-admin has that permission.
|
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_partner_insert_permission_missing_tf()
|
create or replace function hs_office_partner_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
superObjectUuid uuid;
|
||||||
begin
|
begin
|
||||||
|
-- check INSERT INSERT if global ADMIN
|
||||||
|
if isGlobalAdmin() then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
|
||||||
raise exception '[403] insert into hs_office_partner not allowed for current subjects % (%)',
|
raise exception '[403] insert into hs_office_partner not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger hs_office_partner_insert_permission_check_tg
|
create trigger hs_office_partner_insert_permission_check_tg
|
||||||
before insert on hs_office_partner
|
before insert on hs_office_partner
|
||||||
for each row
|
for each row
|
||||||
when ( not isGlobalAdmin() )
|
execute procedure hs_office_partner_insert_permission_check_tf();
|
||||||
execute procedure hs_office_partner_insert_permission_missing_tf();
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-partner-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-partner-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
@ -224,6 +240,7 @@ call generateRbacIdentityViewFromProjection('hs_office_partner',
|
|||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-partner-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-partner-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -58,79 +58,96 @@ execute procedure insertTriggerForHsOfficePartnerDetails_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-partner-details-rbac-INSERT:1 endDelimiter:--//
|
--changeset hs-office-partner-details-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- granting INSERT permission to global ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates INSERT INTO hs_office_partner_details permissions for the related global rows.
|
Grants INSERT INTO hs_office_partner_details permissions to specified role of pre-existing global rows.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
row global;
|
row global;
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO hs_office_partner_details permissions for the related global rows');
|
call defineContext('create INSERT INTO hs_office_partner_details permissions for pre-exising global rows');
|
||||||
|
|
||||||
FOR row IN SELECT * FROM global
|
FOR row IN SELECT * FROM global
|
||||||
|
-- unconditional for all rows in that table
|
||||||
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;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds hs_office_partner_details INSERT permission to specified role of new global rows.
|
Grants hs_office_partner_details INSERT permission to specified role of new global rows.
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_partner_details_global_insert_tf()
|
create or replace function new_hs_office_partner_details_grants_insert_to_global_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
-- unconditional for all rows in that table
|
||||||
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_partner_details'),
|
createPermission(NEW.uuid, 'INSERT', 'hs_office_partner_details'),
|
||||||
globalADMIN());
|
globalADMIN());
|
||||||
|
-- end.
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_hs_office_partner_details_global_insert_tg
|
create trigger z_new_hs_office_partner_details_grants_insert_to_global_tg
|
||||||
after insert on global
|
after insert on global
|
||||||
for each row
|
for each row
|
||||||
execute procedure hs_office_partner_details_global_insert_tf();
|
execute procedure new_hs_office_partner_details_grants_insert_to_global_tf();
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs_office_partner_details-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_partner_details,
|
Checks if the user respectively the assumed roles are allowed to insert a row to hs_office_partner_details.
|
||||||
where only global-admin has that permission.
|
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_partner_details_insert_permission_missing_tf()
|
create or replace function hs_office_partner_details_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
superObjectUuid uuid;
|
||||||
begin
|
begin
|
||||||
|
-- check INSERT INSERT if global ADMIN
|
||||||
|
if isGlobalAdmin() then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
|
||||||
raise exception '[403] insert into hs_office_partner_details not allowed for current subjects % (%)',
|
raise exception '[403] insert into hs_office_partner_details not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger hs_office_partner_details_insert_permission_check_tg
|
create trigger hs_office_partner_details_insert_permission_check_tg
|
||||||
before insert on hs_office_partner_details
|
before insert on hs_office_partner_details
|
||||||
for each row
|
for each row
|
||||||
when ( not isGlobalAdmin() )
|
execute procedure hs_office_partner_details_insert_permission_check_tf();
|
||||||
execute procedure hs_office_partner_details_insert_permission_missing_tf();
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-partner-details-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-partner-details-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
call generateRbacIdentityViewFromQuery('hs_office_partner_details',
|
call generateRbacIdentityViewFromQuery('hs_office_partner_details',
|
||||||
$idName$
|
$idName$
|
||||||
SELECT partnerDetails.uuid as uuid, partner_iv.idName 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
|
||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-partner-details-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-partner-details-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -76,49 +76,6 @@ execute procedure insertTriggerForHsOfficeBankAccount_tf();
|
|||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
|
||||||
--changeset hs-office-bankaccount-rbac-INSERT:1 endDelimiter:--//
|
|
||||||
-- ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/*
|
|
||||||
Creates INSERT INTO hs_office_bankaccount permissions for the related global rows.
|
|
||||||
*/
|
|
||||||
do language plpgsql $$
|
|
||||||
declare
|
|
||||||
row global;
|
|
||||||
begin
|
|
||||||
call defineContext('create INSERT INTO hs_office_bankaccount permissions for the related global rows');
|
|
||||||
|
|
||||||
FOR row IN SELECT * FROM global
|
|
||||||
LOOP
|
|
||||||
call grantPermissionToRole(
|
|
||||||
createPermission(row.uuid, 'INSERT', 'hs_office_bankaccount'),
|
|
||||||
globalGUEST());
|
|
||||||
END LOOP;
|
|
||||||
END;
|
|
||||||
$$;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Adds hs_office_bankaccount INSERT permission to specified role of new global rows.
|
|
||||||
*/
|
|
||||||
create or replace function hs_office_bankaccount_global_insert_tf()
|
|
||||||
returns trigger
|
|
||||||
language plpgsql
|
|
||||||
strict as $$
|
|
||||||
begin
|
|
||||||
call grantPermissionToRole(
|
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_bankaccount'),
|
|
||||||
globalGUEST());
|
|
||||||
return NEW;
|
|
||||||
end; $$;
|
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
|
||||||
create trigger z_hs_office_bankaccount_global_insert_tg
|
|
||||||
after insert on global
|
|
||||||
for each row
|
|
||||||
execute procedure hs_office_bankaccount_global_insert_tf();
|
|
||||||
--//
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-bankaccount-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-bankaccount-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
@ -129,6 +86,7 @@ call generateRbacIdentityViewFromProjection('hs_office_bankaccount',
|
|||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-bankaccount-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-bankaccount-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -6,45 +6,6 @@ This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manua
|
|||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
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 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 debitor["`**debitor**`"]
|
subgraph debitor["`**debitor**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style debitor fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
style debitor fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
@ -73,30 +34,16 @@ subgraph debitor["`**debitor**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph partnerRel["`**partnerRel**`"]
|
subgraph debitorRel.anchorPerson["`**debitorRel.anchorPerson**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
subgraph partnerRel:roles[ ]
|
subgraph debitorRel.anchorPerson:roles[ ]
|
||||||
style partnerRel:roles fill:#99bcdb,stroke:white
|
style debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
role:partnerRel:OWNER[[partnerRel:OWNER]]
|
role:debitorRel.anchorPerson:OWNER[[debitorRel.anchorPerson:OWNER]]
|
||||||
role:partnerRel:ADMIN[[partnerRel:ADMIN]]
|
role:debitorRel.anchorPerson:ADMIN[[debitorRel.anchorPerson:ADMIN]]
|
||||||
role:partnerRel:AGENT[[partnerRel:AGENT]]
|
role:debitorRel.anchorPerson:REFERRER[[debitorRel.anchorPerson:REFERRER]]
|
||||||
role:partnerRel:TENANT[[partnerRel:TENANT]]
|
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -113,6 +60,33 @@ subgraph debitorRel.contact["`**debitorRel.contact**`"]
|
|||||||
end
|
end
|
||||||
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 partnerRel["`**partnerRel**`"]
|
||||||
|
direction TB
|
||||||
|
style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph partnerRel:roles[ ]
|
||||||
|
style partnerRel:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:partnerRel:OWNER[[partnerRel:OWNER]]
|
||||||
|
role:partnerRel:ADMIN[[partnerRel:ADMIN]]
|
||||||
|
role:partnerRel:AGENT[[partnerRel:AGENT]]
|
||||||
|
role:partnerRel:TENANT[[partnerRel:TENANT]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
|
subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
@ -126,6 +100,32 @@ subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
|
|||||||
end
|
end
|
||||||
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.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 refundBankAccount["`**refundBankAccount**`"]
|
subgraph refundBankAccount["`**refundBankAccount**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style refundBankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style refundBankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
@ -149,6 +149,16 @@ 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:debitorRel:OWNER -.-> role:debitorRel:ADMIN
|
||||||
|
role:debitorRel:ADMIN -.-> role:debitorRel:AGENT
|
||||||
|
role:debitorRel:AGENT -.-> role:debitorRel:TENANT
|
||||||
|
role:debitorRel.contact:ADMIN -.-> role:debitorRel:TENANT
|
||||||
|
role:debitorRel:TENANT -.-> role:debitorRel.anchorPerson:REFERRER
|
||||||
|
role:debitorRel:TENANT -.-> role:debitorRel.holderPerson:REFERRER
|
||||||
|
role:debitorRel:TENANT -.-> role:debitorRel.contact:REFERRER
|
||||||
|
role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel:OWNER
|
||||||
|
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:AGENT
|
||||||
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
|
||||||
|
@ -127,73 +127,89 @@ execute procedure updateTriggerForHsOfficeDebitor_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-debitor-rbac-INSERT:1 endDelimiter:--//
|
--changeset hs-office-debitor-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- granting INSERT permission to global ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates INSERT INTO hs_office_debitor permissions for the related global rows.
|
Grants INSERT INTO hs_office_debitor permissions to specified role of pre-existing global rows.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
row global;
|
row global;
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO hs_office_debitor permissions for the related global rows');
|
call defineContext('create INSERT INTO hs_office_debitor permissions for pre-exising global rows');
|
||||||
|
|
||||||
FOR row IN SELECT * FROM global
|
FOR row IN SELECT * FROM global
|
||||||
|
-- unconditional for all rows in that table
|
||||||
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;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds hs_office_debitor INSERT permission to specified role of new global rows.
|
Grants hs_office_debitor INSERT permission to specified role of new global rows.
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_debitor_global_insert_tf()
|
create or replace function new_hs_office_debitor_grants_insert_to_global_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
-- unconditional for all rows in that table
|
||||||
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_debitor'),
|
createPermission(NEW.uuid, 'INSERT', 'hs_office_debitor'),
|
||||||
globalADMIN());
|
globalADMIN());
|
||||||
|
-- end.
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_hs_office_debitor_global_insert_tg
|
create trigger z_new_hs_office_debitor_grants_insert_to_global_tg
|
||||||
after insert on global
|
after insert on global
|
||||||
for each row
|
for each row
|
||||||
execute procedure hs_office_debitor_global_insert_tf();
|
execute procedure new_hs_office_debitor_grants_insert_to_global_tf();
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs_office_debitor-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_debitor,
|
Checks if the user respectively the assumed roles are allowed to insert a row to hs_office_debitor.
|
||||||
where only global-admin has that permission.
|
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_debitor_insert_permission_missing_tf()
|
create or replace function hs_office_debitor_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
superObjectUuid uuid;
|
||||||
begin
|
begin
|
||||||
|
-- check INSERT INSERT if global ADMIN
|
||||||
|
if isGlobalAdmin() then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
|
||||||
raise exception '[403] insert into hs_office_debitor not allowed for current subjects % (%)',
|
raise exception '[403] insert into hs_office_debitor not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger hs_office_debitor_insert_permission_check_tg
|
create trigger hs_office_debitor_insert_permission_check_tg
|
||||||
before insert on hs_office_debitor
|
before insert on hs_office_debitor
|
||||||
for each row
|
for each row
|
||||||
when ( not isGlobalAdmin() )
|
execute procedure hs_office_debitor_insert_permission_check_tf();
|
||||||
execute procedure hs_office_debitor_insert_permission_missing_tf();
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-debitor-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-debitor-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
call generateRbacIdentityViewFromQuery('hs_office_debitor',
|
call generateRbacIdentityViewFromQuery('hs_office_debitor',
|
||||||
$idName$
|
$idName$
|
||||||
SELECT debitor.uuid AS uuid,
|
SELECT debitor.uuid AS uuid,
|
||||||
'D-' || (SELECT partner.partnerNumber
|
'D-' || (SELECT partner.partnerNumber
|
||||||
FROM hs_office_partner partner
|
FROM hs_office_partner partner
|
||||||
JOIN hs_office_relation partnerRel
|
JOIN hs_office_relation partnerRel
|
||||||
@ -203,9 +219,10 @@ create trigger hs_office_debitor_insert_permission_check_tg
|
|||||||
WHERE debitorRel.uuid = debitor.debitorRelUuid)
|
WHERE debitorRel.uuid = debitor.debitorRelUuid)
|
||||||
|| debitorNumberSuffix as idName
|
|| debitorNumberSuffix as idName
|
||||||
FROM hs_office_debitor AS debitor
|
FROM hs_office_debitor AS debitor
|
||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-debitor-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-debitor-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -19,16 +19,17 @@ subgraph bankAccount["`**bankAccount**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph debitorRel.contact["`**debitorRel.contact**`"]
|
subgraph debitorRel["`**debitorRel**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
subgraph debitorRel.contact:roles[ ]
|
subgraph debitorRel:roles[ ]
|
||||||
style debitorRel.contact:roles fill:#99bcdb,stroke:white
|
style debitorRel:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
role:debitorRel.contact:OWNER[[debitorRel.contact:OWNER]]
|
role:debitorRel:OWNER[[debitorRel:OWNER]]
|
||||||
role:debitorRel.contact:ADMIN[[debitorRel.contact:ADMIN]]
|
role:debitorRel:ADMIN[[debitorRel:ADMIN]]
|
||||||
role:debitorRel.contact:REFERRER[[debitorRel.contact:REFERRER]]
|
role:debitorRel:AGENT[[debitorRel:AGENT]]
|
||||||
|
role:debitorRel:TENANT[[debitorRel:TENANT]]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -45,6 +46,19 @@ subgraph debitorRel.anchorPerson["`**debitorRel.anchorPerson**`"]
|
|||||||
end
|
end
|
||||||
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.holderPerson["`**debitorRel.holderPerson**`"]
|
subgraph debitorRel.holderPerson["`**debitorRel.holderPerson**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
@ -81,20 +95,6 @@ subgraph sepaMandate["`**sepaMandate**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph debitorRel["`**debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph debitorRel:roles[ ]
|
|
||||||
style debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:debitorRel:OWNER[[debitorRel:OWNER]]
|
|
||||||
role:debitorRel:ADMIN[[debitorRel:ADMIN]]
|
|
||||||
role:debitorRel:AGENT[[debitorRel:AGENT]]
|
|
||||||
role:debitorRel:TENANT[[debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
%% granting roles to users
|
%% granting roles to users
|
||||||
user:creator ==> role:sepaMandate:OWNER
|
user:creator ==> role:sepaMandate:OWNER
|
||||||
|
|
||||||
@ -108,6 +108,16 @@ 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:debitorRel:OWNER -.-> role:debitorRel:ADMIN
|
||||||
|
role:debitorRel:ADMIN -.-> role:debitorRel:AGENT
|
||||||
|
role:debitorRel:AGENT -.-> role:debitorRel:TENANT
|
||||||
|
role:debitorRel.contact:ADMIN -.-> role:debitorRel:TENANT
|
||||||
|
role:debitorRel:TENANT -.-> role:debitorRel.anchorPerson:REFERRER
|
||||||
|
role:debitorRel:TENANT -.-> role:debitorRel.holderPerson:REFERRER
|
||||||
|
role:debitorRel:TENANT -.-> role:debitorRel.contact:REFERRER
|
||||||
|
role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel:OWNER
|
||||||
|
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:AGENT
|
||||||
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
|
||||||
|
@ -102,78 +102,79 @@ execute procedure insertTriggerForHsOfficeSepaMandate_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-sepamandate-rbac-INSERT:1 endDelimiter:--//
|
--changeset hs-office-sepamandate-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- granting INSERT permission to hs_office_relation ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates INSERT INTO hs_office_sepamandate permissions for the related hs_office_relation rows.
|
Grants INSERT INTO hs_office_sepamandate permissions to specified role of pre-existing hs_office_relation rows.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
row hs_office_relation;
|
row hs_office_relation;
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO hs_office_sepamandate permissions for the related hs_office_relation rows');
|
call defineContext('create INSERT INTO hs_office_sepamandate permissions for pre-exising hs_office_relation rows');
|
||||||
|
|
||||||
FOR row IN SELECT * FROM hs_office_relation
|
FOR row IN SELECT * FROM hs_office_relation
|
||||||
WHERE type = 'DEBITOR'
|
WHERE type = 'DEBITOR'
|
||||||
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;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds hs_office_sepamandate INSERT permission to specified role of new hs_office_relation rows.
|
Grants hs_office_sepamandate INSERT permission to specified role of new hs_office_relation rows.
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_sepamandate_hs_office_relation_insert_tf()
|
create or replace function new_hs_office_sepamandate_grants_insert_to_hs_office_relation_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
if NEW.type = 'DEBITOR' then
|
if NEW.type = 'DEBITOR' then
|
||||||
call grantPermissionToRole(
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_sepamandate'),
|
createPermission(NEW.uuid, 'INSERT', 'hs_office_sepamandate'),
|
||||||
hsOfficeRelationADMIN(NEW));
|
hsOfficeRelationADMIN(NEW));
|
||||||
end if;
|
end if;
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_hs_office_sepamandate_hs_office_relation_insert_tg
|
create trigger z_new_hs_office_sepamandate_grants_insert_to_hs_office_relation_tg
|
||||||
after insert on hs_office_relation
|
after insert on hs_office_relation
|
||||||
for each row
|
for each row
|
||||||
execute procedure hs_office_sepamandate_hs_office_relation_insert_tf();
|
execute procedure new_hs_office_sepamandate_grants_insert_to_hs_office_relation_tf();
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs_office_sepamandate-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_sepamandate,
|
Checks if the user respectively the assumed roles are allowed to insert a row to hs_office_sepamandate.
|
||||||
where the check is performed by an indirect role.
|
|
||||||
|
|
||||||
An indirect role is a role which depends on an object uuid which is not a direct foreign key
|
|
||||||
of the source entity, but needs to be fetched via joined tables.
|
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_sepamandate_insert_permission_check_tf()
|
create or replace function hs_office_sepamandate_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
|
||||||
declare
|
declare
|
||||||
superRoleObjectUuid uuid;
|
superObjectUuid uuid;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
superRoleObjectUuid := (SELECT debitorRel.uuid
|
-- check INSERT permission via indirect foreign key: NEW.debitorUuid
|
||||||
FROM hs_office_relation debitorRel
|
superObjectUuid := (SELECT debitorRel.uuid
|
||||||
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
FROM hs_office_relation debitorRel
|
||||||
WHERE debitor.uuid = NEW.debitorUuid
|
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||||
);
|
WHERE debitor.uuid = NEW.debitorUuid
|
||||||
assert superRoleObjectUuid is not null, 'superRoleObjectUuid must not be null';
|
);
|
||||||
|
assert superObjectUuid is not null, 'object uuid fetched depending on hs_office_sepamandate.debitorUuid must not be null, also check fetchSql in RBAC DSL';
|
||||||
if ( not hasInsertPermission(superRoleObjectUuid, 'INSERT', 'hs_office_sepamandate') ) then
|
if hasInsertPermission(superObjectUuid, 'hs_office_sepamandate') then
|
||||||
raise exception
|
return NEW;
|
||||||
'[403] insert into hs_office_sepamandate not allowed for current subjects % (%)',
|
|
||||||
currentSubjects(), currentSubjectsUuids();
|
|
||||||
end if;
|
end if;
|
||||||
return NEW;
|
|
||||||
|
raise exception '[403] insert into hs_office_sepamandate not allowed for current subjects % (%)',
|
||||||
|
currentSubjects(), currentSubjectsUuids();
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger hs_office_sepamandate_insert_permission_check_tg
|
create trigger hs_office_sepamandate_insert_permission_check_tg
|
||||||
@ -182,18 +183,20 @@ create trigger hs_office_sepamandate_insert_permission_check_tg
|
|||||||
execute procedure hs_office_sepamandate_insert_permission_check_tf();
|
execute procedure hs_office_sepamandate_insert_permission_check_tf();
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-sepamandate-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-sepamandate-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
call generateRbacIdentityViewFromQuery('hs_office_sepamandate',
|
call generateRbacIdentityViewFromQuery('hs_office_sepamandate',
|
||||||
$idName$
|
$idName$
|
||||||
select sm.uuid as uuid, ba.iban || '-' || sm.validity as idName
|
select sm.uuid as uuid, ba.iban || '-' || sm.validity as idName
|
||||||
from hs_office_sepamandate sm
|
from hs_office_sepamandate sm
|
||||||
join hs_office_bankaccount ba on ba.uuid = sm.bankAccountUuid
|
join hs_office_bankaccount ba on ba.uuid = sm.bankAccountUuid
|
||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-sepamandate-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-sepamandate-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -6,33 +6,6 @@ This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manua
|
|||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
subgraph partnerRel["`**partnerRel**`"]
|
|
||||||
direction TB
|
|
||||||
style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph partnerRel:roles[ ]
|
|
||||||
style partnerRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:partnerRel:OWNER[[partnerRel:OWNER]]
|
|
||||||
role:partnerRel:ADMIN[[partnerRel:ADMIN]]
|
|
||||||
role:partnerRel:AGENT[[partnerRel:AGENT]]
|
|
||||||
role:partnerRel:TENANT[[partnerRel:TENANT]]
|
|
||||||
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 membership["`**membership**`"]
|
subgraph membership["`**membership**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style membership fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
style membership fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
@ -55,6 +28,20 @@ subgraph membership["`**membership**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
subgraph partnerRel["`**partnerRel**`"]
|
||||||
|
direction TB
|
||||||
|
style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph partnerRel:roles[ ]
|
||||||
|
style partnerRel:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:partnerRel:OWNER[[partnerRel:OWNER]]
|
||||||
|
role:partnerRel:ADMIN[[partnerRel:ADMIN]]
|
||||||
|
role:partnerRel:AGENT[[partnerRel:AGENT]]
|
||||||
|
role:partnerRel:TENANT[[partnerRel:TENANT]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
|
subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
@ -68,6 +55,19 @@ subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
|
|||||||
end
|
end
|
||||||
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.holderPerson["`**partnerRel.holderPerson**`"]
|
subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
@ -89,79 +89,96 @@ execute procedure insertTriggerForHsOfficeMembership_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-membership-rbac-INSERT:1 endDelimiter:--//
|
--changeset hs-office-membership-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- granting INSERT permission to global ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates INSERT INTO hs_office_membership permissions for the related global rows.
|
Grants INSERT INTO hs_office_membership permissions to specified role of pre-existing global rows.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
row global;
|
row global;
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO hs_office_membership permissions for the related global rows');
|
call defineContext('create INSERT INTO hs_office_membership permissions for pre-exising global rows');
|
||||||
|
|
||||||
FOR row IN SELECT * FROM global
|
FOR row IN SELECT * FROM global
|
||||||
|
-- unconditional for all rows in that table
|
||||||
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;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds hs_office_membership INSERT permission to specified role of new global rows.
|
Grants hs_office_membership INSERT permission to specified role of new global rows.
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_membership_global_insert_tf()
|
create or replace function new_hs_office_membership_grants_insert_to_global_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
-- unconditional for all rows in that table
|
||||||
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_membership'),
|
createPermission(NEW.uuid, 'INSERT', 'hs_office_membership'),
|
||||||
globalADMIN());
|
globalADMIN());
|
||||||
|
-- end.
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_hs_office_membership_global_insert_tg
|
create trigger z_new_hs_office_membership_grants_insert_to_global_tg
|
||||||
after insert on global
|
after insert on global
|
||||||
for each row
|
for each row
|
||||||
execute procedure hs_office_membership_global_insert_tf();
|
execute procedure new_hs_office_membership_grants_insert_to_global_tf();
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs_office_membership-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_membership,
|
Checks if the user respectively the assumed roles are allowed to insert a row to hs_office_membership.
|
||||||
where only global-admin has that permission.
|
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_membership_insert_permission_missing_tf()
|
create or replace function hs_office_membership_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
superObjectUuid uuid;
|
||||||
begin
|
begin
|
||||||
|
-- check INSERT INSERT if global ADMIN
|
||||||
|
if isGlobalAdmin() then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
|
||||||
raise exception '[403] insert into hs_office_membership not allowed for current subjects % (%)',
|
raise exception '[403] insert into hs_office_membership not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger hs_office_membership_insert_permission_check_tg
|
create trigger hs_office_membership_insert_permission_check_tg
|
||||||
before insert on hs_office_membership
|
before insert on hs_office_membership
|
||||||
for each row
|
for each row
|
||||||
when ( not isGlobalAdmin() )
|
execute procedure hs_office_membership_insert_permission_check_tf();
|
||||||
execute procedure hs_office_membership_insert_permission_missing_tf();
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-membership-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-membership-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
call generateRbacIdentityViewFromQuery('hs_office_membership',
|
call generateRbacIdentityViewFromQuery('hs_office_membership',
|
||||||
$idName$
|
$idName$
|
||||||
SELECT m.uuid AS uuid,
|
SELECT m.uuid AS uuid,
|
||||||
'M-' || p.partnerNumber || m.memberNumberSuffix as idName
|
'M-' || p.partnerNumber || m.memberNumberSuffix as idName
|
||||||
FROM hs_office_membership AS m
|
FROM hs_office_membership AS m
|
||||||
JOIN hs_office_partner AS p ON p.uuid = m.partnerUuid
|
JOIN hs_office_partner AS p ON p.uuid = m.partnerUuid
|
||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-membership-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-membership-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -6,32 +6,6 @@ This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manua
|
|||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
subgraph membership.partnerRel.holderPerson["`**membership.partnerRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style membership.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph membership.partnerRel.holderPerson:roles[ ]
|
|
||||||
style membership.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:membership.partnerRel.holderPerson:OWNER[[membership.partnerRel.holderPerson:OWNER]]
|
|
||||||
role:membership.partnerRel.holderPerson:ADMIN[[membership.partnerRel.holderPerson:ADMIN]]
|
|
||||||
role:membership.partnerRel.holderPerson:REFERRER[[membership.partnerRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph membership.partnerRel.anchorPerson["`**membership.partnerRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style membership.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph membership.partnerRel.anchorPerson:roles[ ]
|
|
||||||
style membership.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:membership.partnerRel.anchorPerson:OWNER[[membership.partnerRel.anchorPerson:OWNER]]
|
|
||||||
role:membership.partnerRel.anchorPerson:ADMIN[[membership.partnerRel.anchorPerson:ADMIN]]
|
|
||||||
role:membership.partnerRel.anchorPerson:REFERRER[[membership.partnerRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph coopSharesTransaction["`**coopSharesTransaction**`"]
|
subgraph coopSharesTransaction["`**coopSharesTransaction**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style coopSharesTransaction fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
style coopSharesTransaction fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
@ -72,6 +46,19 @@ subgraph membership.partnerRel["`**membership.partnerRel**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
subgraph membership.partnerRel.anchorPerson["`**membership.partnerRel.anchorPerson**`"]
|
||||||
|
direction TB
|
||||||
|
style membership.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph membership.partnerRel.anchorPerson:roles[ ]
|
||||||
|
style membership.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:membership.partnerRel.anchorPerson:OWNER[[membership.partnerRel.anchorPerson:OWNER]]
|
||||||
|
role:membership.partnerRel.anchorPerson:ADMIN[[membership.partnerRel.anchorPerson:ADMIN]]
|
||||||
|
role:membership.partnerRel.anchorPerson:REFERRER[[membership.partnerRel.anchorPerson:REFERRER]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
subgraph membership.partnerRel.contact["`**membership.partnerRel.contact**`"]
|
subgraph membership.partnerRel.contact["`**membership.partnerRel.contact**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style membership.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style membership.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
@ -85,6 +72,19 @@ subgraph membership.partnerRel.contact["`**membership.partnerRel.contact**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
subgraph membership.partnerRel.holderPerson["`**membership.partnerRel.holderPerson**`"]
|
||||||
|
direction TB
|
||||||
|
style membership.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph membership.partnerRel.holderPerson:roles[ ]
|
||||||
|
style membership.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:membership.partnerRel.holderPerson:OWNER[[membership.partnerRel.holderPerson:OWNER]]
|
||||||
|
role:membership.partnerRel.holderPerson:ADMIN[[membership.partnerRel.holderPerson:ADMIN]]
|
||||||
|
role:membership.partnerRel.holderPerson:REFERRER[[membership.partnerRel.holderPerson:REFERRER]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
%% granting roles to roles
|
%% granting roles to roles
|
||||||
role:global:ADMIN -.-> role:membership.partnerRel.anchorPerson:OWNER
|
role:global:ADMIN -.-> role:membership.partnerRel.anchorPerson:OWNER
|
||||||
role:membership.partnerRel.anchorPerson:OWNER -.-> role:membership.partnerRel.anchorPerson:ADMIN
|
role:membership.partnerRel.anchorPerson:OWNER -.-> role:membership.partnerRel.anchorPerson:ADMIN
|
||||||
|
@ -65,68 +65,82 @@ execute procedure insertTriggerForHsOfficeCoopSharesTransaction_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-coopsharestransaction-rbac-INSERT:1 endDelimiter:--//
|
--changeset hs-office-coopsharestransaction-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- granting INSERT permission to hs_office_membership ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates INSERT INTO hs_office_coopsharestransaction permissions for the related hs_office_membership rows.
|
Grants INSERT INTO hs_office_coopsharestransaction permissions to specified role of pre-existing hs_office_membership rows.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
row hs_office_membership;
|
row hs_office_membership;
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO hs_office_coopsharestransaction permissions for the related hs_office_membership rows');
|
call defineContext('create INSERT INTO hs_office_coopsharestransaction permissions for pre-exising hs_office_membership rows');
|
||||||
|
|
||||||
FOR row IN SELECT * FROM hs_office_membership
|
FOR row IN SELECT * FROM hs_office_membership
|
||||||
|
-- unconditional for all rows in that table
|
||||||
LOOP
|
LOOP
|
||||||
call grantPermissionToRole(
|
call grantPermissionToRole(
|
||||||
createPermission(row.uuid, 'INSERT', 'hs_office_coopsharestransaction'),
|
createPermission(row.uuid, 'INSERT', 'hs_office_coopsharestransaction'),
|
||||||
hsOfficeMembershipADMIN(row));
|
hsOfficeMembershipADMIN(row));
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds hs_office_coopsharestransaction INSERT permission to specified role of new hs_office_membership rows.
|
Grants hs_office_coopsharestransaction INSERT permission to specified role of new hs_office_membership rows.
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_coopsharestransaction_hs_office_membership_insert_tf()
|
create or replace function new_hs_office_coopsharestransaction_grants_insert_to_hs_office_membership_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
-- unconditional for all rows in that table
|
||||||
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_coopsharestransaction'),
|
createPermission(NEW.uuid, 'INSERT', 'hs_office_coopsharestransaction'),
|
||||||
hsOfficeMembershipADMIN(NEW));
|
hsOfficeMembershipADMIN(NEW));
|
||||||
|
-- end.
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_hs_office_coopsharestransaction_hs_office_membership_insert_tg
|
create trigger z_new_hs_office_coopsharestransaction_grants_insert_to_hs_office_membership_tg
|
||||||
after insert on hs_office_membership
|
after insert on hs_office_membership
|
||||||
for each row
|
for each row
|
||||||
execute procedure hs_office_coopsharestransaction_hs_office_membership_insert_tf();
|
execute procedure new_hs_office_coopsharestransaction_grants_insert_to_hs_office_membership_tf();
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs_office_coopsharestransaction-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_coopsharestransaction,
|
Checks if the user respectively the assumed roles are allowed to insert a row to hs_office_coopsharestransaction.
|
||||||
where the check is performed by a direct role.
|
|
||||||
|
|
||||||
A direct role is a role depending on a foreign key directly available in the NEW row.
|
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_coopsharestransaction_insert_permission_missing_tf()
|
create or replace function hs_office_coopsharestransaction_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
superObjectUuid uuid;
|
||||||
begin
|
begin
|
||||||
|
-- check INSERT permission via direct foreign key: NEW.membershipUuid
|
||||||
|
if hasInsertPermission(NEW.membershipUuid, 'hs_office_coopsharestransaction') then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
|
||||||
raise exception '[403] insert into hs_office_coopsharestransaction not allowed for current subjects % (%)',
|
raise exception '[403] insert into hs_office_coopsharestransaction not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger hs_office_coopsharestransaction_insert_permission_check_tg
|
create trigger hs_office_coopsharestransaction_insert_permission_check_tg
|
||||||
before insert on hs_office_coopsharestransaction
|
before insert on hs_office_coopsharestransaction
|
||||||
for each row
|
for each row
|
||||||
when ( not hasInsertPermission(NEW.membershipUuid, 'INSERT', 'hs_office_coopsharestransaction') )
|
execute procedure hs_office_coopsharestransaction_insert_permission_check_tf();
|
||||||
execute procedure hs_office_coopsharestransaction_insert_permission_missing_tf();
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-coopsharestransaction-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-coopsharestransaction-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
@ -137,6 +151,7 @@ call generateRbacIdentityViewFromProjection('hs_office_coopsharestransaction',
|
|||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-coopsharestransaction-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-coopsharestransaction-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -6,32 +6,6 @@ This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manua
|
|||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
subgraph membership.partnerRel.holderPerson["`**membership.partnerRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style membership.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph membership.partnerRel.holderPerson:roles[ ]
|
|
||||||
style membership.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:membership.partnerRel.holderPerson:OWNER[[membership.partnerRel.holderPerson:OWNER]]
|
|
||||||
role:membership.partnerRel.holderPerson:ADMIN[[membership.partnerRel.holderPerson:ADMIN]]
|
|
||||||
role:membership.partnerRel.holderPerson:REFERRER[[membership.partnerRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph membership.partnerRel.anchorPerson["`**membership.partnerRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style membership.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph membership.partnerRel.anchorPerson:roles[ ]
|
|
||||||
style membership.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:membership.partnerRel.anchorPerson:OWNER[[membership.partnerRel.anchorPerson:OWNER]]
|
|
||||||
role:membership.partnerRel.anchorPerson:ADMIN[[membership.partnerRel.anchorPerson:ADMIN]]
|
|
||||||
role:membership.partnerRel.anchorPerson:REFERRER[[membership.partnerRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph coopAssetsTransaction["`**coopAssetsTransaction**`"]
|
subgraph coopAssetsTransaction["`**coopAssetsTransaction**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style coopAssetsTransaction fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
style coopAssetsTransaction fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
@ -72,6 +46,19 @@ subgraph membership.partnerRel["`**membership.partnerRel**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
subgraph membership.partnerRel.anchorPerson["`**membership.partnerRel.anchorPerson**`"]
|
||||||
|
direction TB
|
||||||
|
style membership.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph membership.partnerRel.anchorPerson:roles[ ]
|
||||||
|
style membership.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:membership.partnerRel.anchorPerson:OWNER[[membership.partnerRel.anchorPerson:OWNER]]
|
||||||
|
role:membership.partnerRel.anchorPerson:ADMIN[[membership.partnerRel.anchorPerson:ADMIN]]
|
||||||
|
role:membership.partnerRel.anchorPerson:REFERRER[[membership.partnerRel.anchorPerson:REFERRER]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
subgraph membership.partnerRel.contact["`**membership.partnerRel.contact**`"]
|
subgraph membership.partnerRel.contact["`**membership.partnerRel.contact**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style membership.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style membership.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
@ -85,6 +72,19 @@ subgraph membership.partnerRel.contact["`**membership.partnerRel.contact**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
subgraph membership.partnerRel.holderPerson["`**membership.partnerRel.holderPerson**`"]
|
||||||
|
direction TB
|
||||||
|
style membership.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph membership.partnerRel.holderPerson:roles[ ]
|
||||||
|
style membership.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:membership.partnerRel.holderPerson:OWNER[[membership.partnerRel.holderPerson:OWNER]]
|
||||||
|
role:membership.partnerRel.holderPerson:ADMIN[[membership.partnerRel.holderPerson:ADMIN]]
|
||||||
|
role:membership.partnerRel.holderPerson:REFERRER[[membership.partnerRel.holderPerson:REFERRER]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
%% granting roles to roles
|
%% granting roles to roles
|
||||||
role:global:ADMIN -.-> role:membership.partnerRel.anchorPerson:OWNER
|
role:global:ADMIN -.-> role:membership.partnerRel.anchorPerson:OWNER
|
||||||
role:membership.partnerRel.anchorPerson:OWNER -.-> role:membership.partnerRel.anchorPerson:ADMIN
|
role:membership.partnerRel.anchorPerson:OWNER -.-> role:membership.partnerRel.anchorPerson:ADMIN
|
||||||
|
@ -65,68 +65,82 @@ execute procedure insertTriggerForHsOfficeCoopAssetsTransaction_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-coopassetstransaction-rbac-INSERT:1 endDelimiter:--//
|
--changeset hs-office-coopassetstransaction-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- granting INSERT permission to hs_office_membership ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates INSERT INTO hs_office_coopassetstransaction permissions for the related hs_office_membership rows.
|
Grants INSERT INTO hs_office_coopassetstransaction permissions to specified role of pre-existing hs_office_membership rows.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
row hs_office_membership;
|
row hs_office_membership;
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO hs_office_coopassetstransaction permissions for the related hs_office_membership rows');
|
call defineContext('create INSERT INTO hs_office_coopassetstransaction permissions for pre-exising hs_office_membership rows');
|
||||||
|
|
||||||
FOR row IN SELECT * FROM hs_office_membership
|
FOR row IN SELECT * FROM hs_office_membership
|
||||||
|
-- unconditional for all rows in that table
|
||||||
LOOP
|
LOOP
|
||||||
call grantPermissionToRole(
|
call grantPermissionToRole(
|
||||||
createPermission(row.uuid, 'INSERT', 'hs_office_coopassetstransaction'),
|
createPermission(row.uuid, 'INSERT', 'hs_office_coopassetstransaction'),
|
||||||
hsOfficeMembershipADMIN(row));
|
hsOfficeMembershipADMIN(row));
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds hs_office_coopassetstransaction INSERT permission to specified role of new hs_office_membership rows.
|
Grants hs_office_coopassetstransaction INSERT permission to specified role of new hs_office_membership rows.
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_coopassetstransaction_hs_office_membership_insert_tf()
|
create or replace function new_hs_office_coopassetstransaction_grants_insert_to_hs_office_membership_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
-- unconditional for all rows in that table
|
||||||
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_coopassetstransaction'),
|
createPermission(NEW.uuid, 'INSERT', 'hs_office_coopassetstransaction'),
|
||||||
hsOfficeMembershipADMIN(NEW));
|
hsOfficeMembershipADMIN(NEW));
|
||||||
|
-- end.
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_hs_office_coopassetstransaction_hs_office_membership_insert_tg
|
create trigger z_new_hs_office_coopassetstransaction_grants_insert_to_hs_office_membership_tg
|
||||||
after insert on hs_office_membership
|
after insert on hs_office_membership
|
||||||
for each row
|
for each row
|
||||||
execute procedure hs_office_coopassetstransaction_hs_office_membership_insert_tf();
|
execute procedure new_hs_office_coopassetstransaction_grants_insert_to_hs_office_membership_tf();
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs_office_coopassetstransaction-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_coopassetstransaction,
|
Checks if the user respectively the assumed roles are allowed to insert a row to hs_office_coopassetstransaction.
|
||||||
where the check is performed by a direct role.
|
|
||||||
|
|
||||||
A direct role is a role depending on a foreign key directly available in the NEW row.
|
|
||||||
*/
|
*/
|
||||||
create or replace function hs_office_coopassetstransaction_insert_permission_missing_tf()
|
create or replace function hs_office_coopassetstransaction_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
superObjectUuid uuid;
|
||||||
begin
|
begin
|
||||||
|
-- check INSERT permission via direct foreign key: NEW.membershipUuid
|
||||||
|
if hasInsertPermission(NEW.membershipUuid, 'hs_office_coopassetstransaction') then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
|
||||||
raise exception '[403] insert into hs_office_coopassetstransaction not allowed for current subjects % (%)',
|
raise exception '[403] insert into hs_office_coopassetstransaction not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger hs_office_coopassetstransaction_insert_permission_check_tg
|
create trigger hs_office_coopassetstransaction_insert_permission_check_tg
|
||||||
before insert on hs_office_coopassetstransaction
|
before insert on hs_office_coopassetstransaction
|
||||||
for each row
|
for each row
|
||||||
when ( not hasInsertPermission(NEW.membershipUuid, 'INSERT', 'hs_office_coopassetstransaction') )
|
execute procedure hs_office_coopassetstransaction_insert_permission_check_tf();
|
||||||
execute procedure hs_office_coopassetstransaction_insert_permission_missing_tf();
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-coopassetstransaction-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-coopassetstransaction-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
@ -137,6 +151,7 @@ call generateRbacIdentityViewFromProjection('hs_office_coopassetstransaction',
|
|||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-coopassetstransaction-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-coopassetstransaction-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -6,86 +6,6 @@ This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manua
|
|||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
subgraph debitor.debitorRel.anchorPerson["`**debitor.debitorRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style debitor.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph debitor.debitorRel.anchorPerson:roles[ ]
|
|
||||||
style debitor.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:debitor.debitorRel.anchorPerson:OWNER[[debitor.debitorRel.anchorPerson:OWNER]]
|
|
||||||
role:debitor.debitorRel.anchorPerson:ADMIN[[debitor.debitorRel.anchorPerson:ADMIN]]
|
|
||||||
role:debitor.debitorRel.anchorPerson:REFERRER[[debitor.debitorRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph debitor.debitorRel.holderPerson["`**debitor.debitorRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style debitor.debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph debitor.debitorRel.holderPerson:roles[ ]
|
|
||||||
style debitor.debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:debitor.debitorRel.holderPerson:OWNER[[debitor.debitorRel.holderPerson:OWNER]]
|
|
||||||
role:debitor.debitorRel.holderPerson:ADMIN[[debitor.debitorRel.holderPerson:ADMIN]]
|
|
||||||
role:debitor.debitorRel.holderPerson:REFERRER[[debitor.debitorRel.holderPerson: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 debitor.debitorRel["`**debitor.debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style debitor.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph debitor.debitorRel:roles[ ]
|
|
||||||
style debitor.debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:debitor.debitorRel:OWNER[[debitor.debitorRel:OWNER]]
|
|
||||||
role:debitor.debitorRel:ADMIN[[debitor.debitorRel:ADMIN]]
|
|
||||||
role:debitor.debitorRel:AGENT[[debitor.debitorRel:AGENT]]
|
|
||||||
role:debitor.debitorRel:TENANT[[debitor.debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph debitor.partnerRel["`**debitor.partnerRel**`"]
|
|
||||||
direction TB
|
|
||||||
style debitor.partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph debitor.partnerRel:roles[ ]
|
|
||||||
style debitor.partnerRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:debitor.partnerRel:OWNER[[debitor.partnerRel:OWNER]]
|
|
||||||
role:debitor.partnerRel:ADMIN[[debitor.partnerRel:ADMIN]]
|
|
||||||
role:debitor.partnerRel:AGENT[[debitor.partnerRel:AGENT]]
|
|
||||||
role:debitor.partnerRel:TENANT[[debitor.partnerRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem["`**bookingItem**`"]
|
subgraph bookingItem["`**bookingItem**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style bookingItem fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
style bookingItem fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
@ -109,89 +29,6 @@ subgraph bookingItem["`**bookingItem**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph debitor.partnerRel.contact["`**debitor.partnerRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style debitor.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph debitor.partnerRel.contact:roles[ ]
|
|
||||||
style debitor.partnerRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:debitor.partnerRel.contact:OWNER[[debitor.partnerRel.contact:OWNER]]
|
|
||||||
role:debitor.partnerRel.contact:ADMIN[[debitor.partnerRel.contact:ADMIN]]
|
|
||||||
role:debitor.partnerRel.contact:REFERRER[[debitor.partnerRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph debitor.partnerRel.holderPerson["`**debitor.partnerRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style debitor.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph debitor.partnerRel.holderPerson:roles[ ]
|
|
||||||
style debitor.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:debitor.partnerRel.holderPerson:OWNER[[debitor.partnerRel.holderPerson:OWNER]]
|
|
||||||
role:debitor.partnerRel.holderPerson:ADMIN[[debitor.partnerRel.holderPerson:ADMIN]]
|
|
||||||
role:debitor.partnerRel.holderPerson:REFERRER[[debitor.partnerRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph debitor["`**debitor**`"]
|
|
||||||
direction TB
|
|
||||||
style debitor fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph debitor.refundBankAccount["`**debitor.refundBankAccount**`"]
|
|
||||||
direction TB
|
|
||||||
style debitor.refundBankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph debitor.refundBankAccount:roles[ ]
|
|
||||||
style debitor.refundBankAccount:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:debitor.refundBankAccount:OWNER[[debitor.refundBankAccount:OWNER]]
|
|
||||||
role:debitor.refundBankAccount:ADMIN[[debitor.refundBankAccount:ADMIN]]
|
|
||||||
role:debitor.refundBankAccount:REFERRER[[debitor.refundBankAccount:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph debitor.partnerRel.anchorPerson["`**debitor.partnerRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style debitor.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph debitor.partnerRel.anchorPerson:roles[ ]
|
|
||||||
style debitor.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:debitor.partnerRel.anchorPerson:OWNER[[debitor.partnerRel.anchorPerson:OWNER]]
|
|
||||||
role:debitor.partnerRel.anchorPerson:ADMIN[[debitor.partnerRel.anchorPerson:ADMIN]]
|
|
||||||
role:debitor.partnerRel.anchorPerson:REFERRER[[debitor.partnerRel.anchorPerson: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 debitor.debitorRel.contact["`**debitor.debitorRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style debitor.debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph debitor.debitorRel.contact:roles[ ]
|
|
||||||
style debitor.debitorRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:debitor.debitorRel.contact:OWNER[[debitor.debitorRel.contact:OWNER]]
|
|
||||||
role:debitor.debitorRel.contact:ADMIN[[debitor.debitorRel.contact:ADMIN]]
|
|
||||||
role:debitor.debitorRel.contact:REFERRER[[debitor.debitorRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
||||||
@ -207,51 +44,10 @@ subgraph debitorRel["`**debitorRel**`"]
|
|||||||
end
|
end
|
||||||
|
|
||||||
%% granting roles to roles
|
%% granting roles to roles
|
||||||
role:global:ADMIN -.-> role:debitor.debitorRel.anchorPerson:OWNER
|
role:global:ADMIN -.-> role:debitorRel:OWNER
|
||||||
role:debitor.debitorRel.anchorPerson:OWNER -.-> role:debitor.debitorRel.anchorPerson:ADMIN
|
role:debitorRel:OWNER -.-> role:debitorRel:ADMIN
|
||||||
role:debitor.debitorRel.anchorPerson:ADMIN -.-> role:debitor.debitorRel.anchorPerson:REFERRER
|
role:debitorRel:ADMIN -.-> role:debitorRel:AGENT
|
||||||
role:global:ADMIN -.-> role:debitor.debitorRel.holderPerson:OWNER
|
role:debitorRel:AGENT -.-> role:debitorRel:TENANT
|
||||||
role:debitor.debitorRel.holderPerson:OWNER -.-> role:debitor.debitorRel.holderPerson:ADMIN
|
|
||||||
role:debitor.debitorRel.holderPerson:ADMIN -.-> role:debitor.debitorRel.holderPerson:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:debitor.debitorRel.contact:OWNER
|
|
||||||
role:debitor.debitorRel.contact:OWNER -.-> role:debitor.debitorRel.contact:ADMIN
|
|
||||||
role:debitor.debitorRel.contact:ADMIN -.-> role:debitor.debitorRel.contact:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:debitor.refundBankAccount:OWNER
|
|
||||||
role:debitor.refundBankAccount:OWNER -.-> role:debitor.refundBankAccount:ADMIN
|
|
||||||
role:debitor.refundBankAccount:ADMIN -.-> role:debitor.refundBankAccount:REFERRER
|
|
||||||
role:debitor.refundBankAccount:ADMIN -.-> role:debitor.debitorRel:AGENT
|
|
||||||
role:debitor.debitorRel:AGENT -.-> role:debitor.refundBankAccount:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:debitor.partnerRel.anchorPerson:OWNER
|
|
||||||
role:debitor.partnerRel.anchorPerson:OWNER -.-> role:debitor.partnerRel.anchorPerson:ADMIN
|
|
||||||
role:debitor.partnerRel.anchorPerson:ADMIN -.-> role:debitor.partnerRel.anchorPerson:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:debitor.partnerRel.holderPerson:OWNER
|
|
||||||
role:debitor.partnerRel.holderPerson:OWNER -.-> role:debitor.partnerRel.holderPerson:ADMIN
|
|
||||||
role:debitor.partnerRel.holderPerson:ADMIN -.-> role:debitor.partnerRel.holderPerson:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:debitor.partnerRel.contact:OWNER
|
|
||||||
role:debitor.partnerRel.contact:OWNER -.-> role:debitor.partnerRel.contact:ADMIN
|
|
||||||
role:debitor.partnerRel.contact:ADMIN -.-> role:debitor.partnerRel.contact:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:debitor.partnerRel:OWNER
|
|
||||||
role:debitor.partnerRel:OWNER -.-> role:debitor.partnerRel:ADMIN
|
|
||||||
role:debitor.partnerRel:ADMIN -.-> role:debitor.partnerRel:AGENT
|
|
||||||
role:debitor.partnerRel:AGENT -.-> role:debitor.partnerRel:TENANT
|
|
||||||
role:debitor.partnerRel.contact:ADMIN -.-> role:debitor.partnerRel:TENANT
|
|
||||||
role:debitor.partnerRel:TENANT -.-> role:debitor.partnerRel.anchorPerson:REFERRER
|
|
||||||
role:debitor.partnerRel:TENANT -.-> role:debitor.partnerRel.holderPerson:REFERRER
|
|
||||||
role:debitor.partnerRel:TENANT -.-> role:debitor.partnerRel.contact:REFERRER
|
|
||||||
role:debitor.partnerRel.anchorPerson:ADMIN -.-> role:debitor.partnerRel:OWNER
|
|
||||||
role:debitor.partnerRel.holderPerson:ADMIN -.-> role:debitor.partnerRel:AGENT
|
|
||||||
role:debitor.partnerRel:ADMIN -.-> role:debitor.debitorRel:ADMIN
|
|
||||||
role:debitor.partnerRel:AGENT -.-> role:debitor.debitorRel:AGENT
|
|
||||||
role:debitor.debitorRel:AGENT -.-> role:debitor.partnerRel:TENANT
|
|
||||||
role:global:ADMIN -.-> role:debitorRel.anchorPerson:OWNER
|
|
||||||
role:debitorRel.anchorPerson:OWNER -.-> role:debitorRel.anchorPerson:ADMIN
|
|
||||||
role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel.anchorPerson:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:debitorRel.holderPerson:OWNER
|
|
||||||
role:debitorRel.holderPerson:OWNER -.-> role:debitorRel.holderPerson:ADMIN
|
|
||||||
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel.holderPerson:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:debitorRel.contact:OWNER
|
|
||||||
role:debitorRel.contact:OWNER -.-> role:debitorRel.contact:ADMIN
|
|
||||||
role:debitorRel.contact:ADMIN -.-> role:debitorRel.contact:REFERRER
|
|
||||||
role:debitorRel:AGENT ==> role:bookingItem:OWNER
|
role:debitorRel:AGENT ==> role:bookingItem:OWNER
|
||||||
role:bookingItem:OWNER ==> role:bookingItem:ADMIN
|
role:bookingItem:OWNER ==> role:bookingItem:ADMIN
|
||||||
role:debitorRel:AGENT ==> role:bookingItem:ADMIN
|
role:debitorRel:AGENT ==> role:bookingItem:ADMIN
|
||||||
|
@ -98,78 +98,79 @@ execute procedure insertTriggerForHsBookingItem_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-booking-item-rbac-INSERT:1 endDelimiter:--//
|
--changeset hs-booking-item-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- granting INSERT permission to hs_office_relation ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates INSERT INTO hs_booking_item permissions for the related hs_office_relation rows.
|
Grants INSERT INTO hs_booking_item permissions to specified role of pre-existing hs_office_relation rows.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
row hs_office_relation;
|
row hs_office_relation;
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO hs_booking_item permissions for the related hs_office_relation rows');
|
call defineContext('create INSERT INTO hs_booking_item permissions for pre-exising hs_office_relation rows');
|
||||||
|
|
||||||
FOR row IN SELECT * FROM hs_office_relation
|
FOR row IN SELECT * FROM hs_office_relation
|
||||||
WHERE type = 'DEBITOR'
|
WHERE type = 'DEBITOR'
|
||||||
LOOP
|
LOOP
|
||||||
call grantPermissionToRole(
|
call grantPermissionToRole(
|
||||||
createPermission(row.uuid, 'INSERT', 'hs_booking_item'),
|
createPermission(row.uuid, 'INSERT', 'hs_booking_item'),
|
||||||
hsOfficeRelationADMIN(row));
|
hsOfficeRelationADMIN(row));
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds hs_booking_item INSERT permission to specified role of new hs_office_relation rows.
|
Grants hs_booking_item INSERT permission to specified role of new hs_office_relation rows.
|
||||||
*/
|
*/
|
||||||
create or replace function hs_booking_item_hs_office_relation_insert_tf()
|
create or replace function new_hs_booking_item_grants_insert_to_hs_office_relation_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
if NEW.type = 'DEBITOR' then
|
if NEW.type = 'DEBITOR' then
|
||||||
call grantPermissionToRole(
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_booking_item'),
|
createPermission(NEW.uuid, 'INSERT', 'hs_booking_item'),
|
||||||
hsOfficeRelationADMIN(NEW));
|
hsOfficeRelationADMIN(NEW));
|
||||||
end if;
|
end if;
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_hs_booking_item_hs_office_relation_insert_tg
|
create trigger z_new_hs_booking_item_grants_insert_to_hs_office_relation_tg
|
||||||
after insert on hs_office_relation
|
after insert on hs_office_relation
|
||||||
for each row
|
for each row
|
||||||
execute procedure hs_booking_item_hs_office_relation_insert_tf();
|
execute procedure new_hs_booking_item_grants_insert_to_hs_office_relation_tf();
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs_booking_item-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to hs_booking_item,
|
Checks if the user respectively the assumed roles are allowed to insert a row to hs_booking_item.
|
||||||
where the check is performed by an indirect role.
|
|
||||||
|
|
||||||
An indirect role is a role which depends on an object uuid which is not a direct foreign key
|
|
||||||
of the source entity, but needs to be fetched via joined tables.
|
|
||||||
*/
|
*/
|
||||||
create or replace function hs_booking_item_insert_permission_check_tf()
|
create or replace function hs_booking_item_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
|
||||||
declare
|
declare
|
||||||
superRoleObjectUuid uuid;
|
superObjectUuid uuid;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
superRoleObjectUuid := (SELECT debitorRel.uuid
|
-- check INSERT permission via indirect foreign key: NEW.debitorUuid
|
||||||
FROM hs_office_relation debitorRel
|
superObjectUuid := (SELECT debitorRel.uuid
|
||||||
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
FROM hs_office_relation debitorRel
|
||||||
WHERE debitor.uuid = NEW.debitorUuid
|
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||||
);
|
WHERE debitor.uuid = NEW.debitorUuid
|
||||||
assert superRoleObjectUuid is not null, 'superRoleObjectUuid must not be null';
|
);
|
||||||
|
assert superObjectUuid is not null, 'object uuid fetched depending on hs_booking_item.debitorUuid must not be null, also check fetchSql in RBAC DSL';
|
||||||
if ( not hasInsertPermission(superRoleObjectUuid, 'INSERT', 'hs_booking_item') ) then
|
if hasInsertPermission(superObjectUuid, 'hs_booking_item') then
|
||||||
raise exception
|
return NEW;
|
||||||
'[403] insert into hs_booking_item not allowed for current subjects % (%)',
|
|
||||||
currentSubjects(), currentSubjectsUuids();
|
|
||||||
end if;
|
end if;
|
||||||
return NEW;
|
|
||||||
|
raise exception '[403] insert into hs_booking_item not allowed for current subjects % (%)',
|
||||||
|
currentSubjects(), currentSubjectsUuids();
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger hs_booking_item_insert_permission_check_tg
|
create trigger hs_booking_item_insert_permission_check_tg
|
||||||
@ -178,18 +179,20 @@ create trigger hs_booking_item_insert_permission_check_tg
|
|||||||
execute procedure hs_booking_item_insert_permission_check_tf();
|
execute procedure hs_booking_item_insert_permission_check_tf();
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-booking-item-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-booking-item-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
call generateRbacIdentityViewFromQuery('hs_booking_item',
|
call generateRbacIdentityViewFromQuery('hs_booking_item',
|
||||||
$idName$
|
$idName$
|
||||||
SELECT bookingItem.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingItem.caption) as idName
|
SELECT bookingItem.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingItem.caption) as idName
|
||||||
FROM hs_booking_item bookingItem
|
FROM hs_booking_item bookingItem
|
||||||
JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingItem.debitorUuid
|
JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingItem.debitorUuid
|
||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-booking-item-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-booking-item-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -34,6 +34,55 @@ create table if not exists hs_hosting_asset
|
|||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hosting-asset-HIERARCHY-CHECK:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
create or replace function hs_hosting_asset_type_hierarchy_check_tf()
|
||||||
|
returns trigger
|
||||||
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
actualParentType HsHostingAssetType;
|
||||||
|
expectedParentType HsHostingAssetType;
|
||||||
|
begin
|
||||||
|
if NEW.parentAssetUuid is not null then
|
||||||
|
actualParentType := (select type
|
||||||
|
from hs_hosting_asset
|
||||||
|
where NEW.parentAssetUuid = uuid);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
expectedParentType := (select case NEW.type
|
||||||
|
when 'CLOUD_SERVER' then null
|
||||||
|
when 'MANAGED_SERVER' then null
|
||||||
|
when 'MANAGED_WEBSPACE' then 'MANAGED_SERVER'
|
||||||
|
when 'UNIX_USER' then 'MANAGED_WEBSPACE'
|
||||||
|
when 'DOMAIN_SETUP' then 'UNIX_USER'
|
||||||
|
when 'EMAIL_ALIAS' then 'MANAGED_WEBSPACE'
|
||||||
|
when 'EMAIL_ADDRESS' then 'DOMAIN_SETUP'
|
||||||
|
when 'PGSQL_USER' then 'MANAGED_WEBSPACE'
|
||||||
|
when 'PGSQL_DATABASE' then 'MANAGED_WEBSPACE'
|
||||||
|
when 'MARIADB_USER' then 'MANAGED_WEBSPACE'
|
||||||
|
when 'MARIADB_DATABASE' then 'MANAGED_WEBSPACE'
|
||||||
|
else raiseException(format('[400] unknown asset type %s', NEW.type::text))
|
||||||
|
end);
|
||||||
|
|
||||||
|
if expectedParentType is not null and actualParentType is null then
|
||||||
|
raise exception '[400] % must have % as parent, but got <NULL>',
|
||||||
|
NEW.type, expectedParentType;
|
||||||
|
elsif expectedParentType is not null and actualParentType <> expectedParentType then
|
||||||
|
raise exception '[400] % must have % as parent, but got %s',
|
||||||
|
NEW.type, expectedParentType, actualParentType;
|
||||||
|
end if;
|
||||||
|
return NEW;
|
||||||
|
end; $$;
|
||||||
|
|
||||||
|
create trigger hs_hosting_asset_type_hierarchy_check_tg
|
||||||
|
before insert on hs_hosting_asset
|
||||||
|
for each row
|
||||||
|
execute procedure hs_hosting_asset_type_hierarchy_check_tf();
|
||||||
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-hosting-asset-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
--changeset hs-hosting-asset-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -6,385 +6,6 @@ This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manua
|
|||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
subgraph parentServer.bookingItem["`**parentServer.bookingItem**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem:roles[ ]
|
|
||||||
style parentServer.bookingItem:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem:OWNER[[parentServer.bookingItem:OWNER]]
|
|
||||||
role:parentServer.bookingItem:ADMIN[[parentServer.bookingItem:ADMIN]]
|
|
||||||
role:parentServer.bookingItem:AGENT[[parentServer.bookingItem:AGENT]]
|
|
||||||
role:parentServer.bookingItem:TENANT[[parentServer.bookingItem:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.anchorPerson["`**parentServer.bookingItem.debitorRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.anchorPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitorRel.anchorPerson:OWNER[[parentServer.bookingItem.debitorRel.anchorPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.anchorPerson:ADMIN[[parentServer.bookingItem.debitorRel.anchorPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.anchorPerson:REFERRER[[parentServer.bookingItem.debitorRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.holderPerson["`**parentServer.bookingItem.debitorRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.holderPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitorRel.holderPerson:OWNER[[parentServer.bookingItem.debitorRel.holderPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.holderPerson:ADMIN[[parentServer.bookingItem.debitorRel.holderPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.holderPerson:REFERRER[[parentServer.bookingItem.debitorRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer["`**parentServer**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.holderPerson["`**parentServer.bookingItem.debitor.partnerRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.holderPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.holderPerson:OWNER[[parentServer.bookingItem.debitor.partnerRel.holderPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.holderPerson:ADMIN[[parentServer.bookingItem.debitor.partnerRel.holderPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.holderPerson:REFERRER[[parentServer.bookingItem.debitor.partnerRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.anchorPerson["`**parentServer.bookingItem.debitor.partnerRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.anchorPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.anchorPerson:OWNER[[parentServer.bookingItem.debitor.partnerRel.anchorPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.anchorPerson:ADMIN[[parentServer.bookingItem.debitor.partnerRel.anchorPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.anchorPerson:REFERRER[[parentServer.bookingItem.debitor.partnerRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.anchorPerson["`**bookingItem.debitor.debitorRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.anchorPerson:roles[ ]
|
|
||||||
style bookingItem.debitor.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.debitorRel.anchorPerson:OWNER[[bookingItem.debitor.debitorRel.anchorPerson:OWNER]]
|
|
||||||
role:bookingItem.debitor.debitorRel.anchorPerson:ADMIN[[bookingItem.debitor.debitorRel.anchorPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitor.debitorRel.anchorPerson:REFERRER[[bookingItem.debitor.debitorRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.contact["`**parentServer.bookingItem.debitorRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.contact:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitorRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitorRel.contact:OWNER[[parentServer.bookingItem.debitorRel.contact:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.contact:ADMIN[[parentServer.bookingItem.debitorRel.contact:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.contact:REFERRER[[parentServer.bookingItem.debitorRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel["`**bookingItem.debitor.partnerRel**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel:roles[ ]
|
|
||||||
style bookingItem.debitor.partnerRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.partnerRel:OWNER[[bookingItem.debitor.partnerRel:OWNER]]
|
|
||||||
role:bookingItem.debitor.partnerRel:ADMIN[[bookingItem.debitor.partnerRel:ADMIN]]
|
|
||||||
role:bookingItem.debitor.partnerRel:AGENT[[bookingItem.debitor.partnerRel:AGENT]]
|
|
||||||
role:bookingItem.debitor.partnerRel:TENANT[[bookingItem.debitor.partnerRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.anchorPerson["`**bookingItem.debitor.partnerRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.anchorPerson:roles[ ]
|
|
||||||
style bookingItem.debitor.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.partnerRel.anchorPerson:OWNER[[bookingItem.debitor.partnerRel.anchorPerson:OWNER]]
|
|
||||||
role:bookingItem.debitor.partnerRel.anchorPerson:ADMIN[[bookingItem.debitor.partnerRel.anchorPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitor.partnerRel.anchorPerson:REFERRER[[bookingItem.debitor.partnerRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel["`**bookingItem.debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel:roles[ ]
|
|
||||||
style bookingItem.debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitorRel:OWNER[[bookingItem.debitorRel:OWNER]]
|
|
||||||
role:bookingItem.debitorRel:ADMIN[[bookingItem.debitorRel:ADMIN]]
|
|
||||||
role:bookingItem.debitorRel:AGENT[[bookingItem.debitorRel:AGENT]]
|
|
||||||
role:bookingItem.debitorRel:TENANT[[bookingItem.debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.contact["`**parentServer.bookingItem.debitor.partnerRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.contact:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.contact:OWNER[[parentServer.bookingItem.debitor.partnerRel.contact:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.contact:ADMIN[[parentServer.bookingItem.debitor.partnerRel.contact:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.contact:REFERRER[[parentServer.bookingItem.debitor.partnerRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.anchorPerson["`**bookingItem.debitorRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.anchorPerson:roles[ ]
|
|
||||||
style bookingItem.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:OWNER[[bookingItem.debitorRel.anchorPerson:OWNER]]
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:ADMIN[[bookingItem.debitorRel.anchorPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:REFERRER[[bookingItem.debitorRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel["`**parentServer.bookingItem.debitor.debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel:OWNER[[parentServer.bookingItem.debitor.debitorRel:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel:ADMIN[[parentServer.bookingItem.debitor.debitorRel:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel:AGENT[[parentServer.bookingItem.debitor.debitorRel:AGENT]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel:TENANT[[parentServer.bookingItem.debitor.debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.holderPerson["`**bookingItem.debitorRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.holderPerson:roles[ ]
|
|
||||||
style bookingItem.debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitorRel.holderPerson:OWNER[[bookingItem.debitorRel.holderPerson:OWNER]]
|
|
||||||
role:bookingItem.debitorRel.holderPerson:ADMIN[[bookingItem.debitorRel.holderPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitorRel.holderPerson:REFERRER[[bookingItem.debitorRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.refundBankAccount["`**bookingItem.debitor.refundBankAccount**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.refundBankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.refundBankAccount:roles[ ]
|
|
||||||
style bookingItem.debitor.refundBankAccount:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.refundBankAccount:OWNER[[bookingItem.debitor.refundBankAccount:OWNER]]
|
|
||||||
role:bookingItem.debitor.refundBankAccount:ADMIN[[bookingItem.debitor.refundBankAccount:ADMIN]]
|
|
||||||
role:bookingItem.debitor.refundBankAccount:REFERRER[[bookingItem.debitor.refundBankAccount:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel["`**parentServer.bookingItem.debitor.partnerRel**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel:OWNER[[parentServer.bookingItem.debitor.partnerRel:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel:ADMIN[[parentServer.bookingItem.debitor.partnerRel:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel:AGENT[[parentServer.bookingItem.debitor.partnerRel:AGENT]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel:TENANT[[parentServer.bookingItem.debitor.partnerRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.contact["`**bookingItem.debitor.debitorRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.contact:roles[ ]
|
|
||||||
style bookingItem.debitor.debitorRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.debitorRel.contact:OWNER[[bookingItem.debitor.debitorRel.contact:OWNER]]
|
|
||||||
role:bookingItem.debitor.debitorRel.contact:ADMIN[[bookingItem.debitor.debitorRel.contact:ADMIN]]
|
|
||||||
role:bookingItem.debitor.debitorRel.contact:REFERRER[[bookingItem.debitor.debitorRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor["`**parentServer.bookingItem.debitor**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.holderPerson["`**parentServer.bookingItem.debitor.debitorRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.holderPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.holderPerson:OWNER[[parentServer.bookingItem.debitor.debitorRel.holderPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.holderPerson:ADMIN[[parentServer.bookingItem.debitor.debitorRel.holderPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.holderPerson:REFERRER[[parentServer.bookingItem.debitor.debitorRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.contact["`**bookingItem.debitor.partnerRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.contact:roles[ ]
|
|
||||||
style bookingItem.debitor.partnerRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.partnerRel.contact:OWNER[[bookingItem.debitor.partnerRel.contact:OWNER]]
|
|
||||||
role:bookingItem.debitor.partnerRel.contact:ADMIN[[bookingItem.debitor.partnerRel.contact:ADMIN]]
|
|
||||||
role:bookingItem.debitor.partnerRel.contact:REFERRER[[bookingItem.debitor.partnerRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel["`**parentServer.bookingItem.debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitorRel:OWNER[[parentServer.bookingItem.debitorRel:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitorRel:ADMIN[[parentServer.bookingItem.debitorRel:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitorRel:AGENT[[parentServer.bookingItem.debitorRel:AGENT]]
|
|
||||||
role:parentServer.bookingItem.debitorRel:TENANT[[parentServer.bookingItem.debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem["`**bookingItem**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem:roles[ ]
|
|
||||||
style bookingItem:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem:OWNER[[bookingItem:OWNER]]
|
|
||||||
role:bookingItem:ADMIN[[bookingItem:ADMIN]]
|
|
||||||
role:bookingItem:AGENT[[bookingItem:AGENT]]
|
|
||||||
role:bookingItem:TENANT[[bookingItem:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.parentServer["`**parentServer.parentServer**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.parentServer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.contact["`**parentServer.bookingItem.debitor.debitorRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.contact:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.contact:OWNER[[parentServer.bookingItem.debitor.debitorRel.contact:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.contact:ADMIN[[parentServer.bookingItem.debitor.debitorRel.contact:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.contact:REFERRER[[parentServer.bookingItem.debitor.debitorRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.holderPerson["`**bookingItem.debitor.partnerRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.holderPerson:roles[ ]
|
|
||||||
style bookingItem.debitor.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.partnerRel.holderPerson:OWNER[[bookingItem.debitor.partnerRel.holderPerson:OWNER]]
|
|
||||||
role:bookingItem.debitor.partnerRel.holderPerson:ADMIN[[bookingItem.debitor.partnerRel.holderPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitor.partnerRel.holderPerson:REFERRER[[bookingItem.debitor.partnerRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.contact["`**bookingItem.debitorRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.contact:roles[ ]
|
|
||||||
style bookingItem.debitorRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitorRel.contact:OWNER[[bookingItem.debitorRel.contact:OWNER]]
|
|
||||||
role:bookingItem.debitorRel.contact:ADMIN[[bookingItem.debitorRel.contact:ADMIN]]
|
|
||||||
role:bookingItem.debitorRel.contact:REFERRER[[bookingItem.debitorRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.refundBankAccount["`**parentServer.bookingItem.debitor.refundBankAccount**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.refundBankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.refundBankAccount:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.refundBankAccount:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.refundBankAccount:OWNER[[parentServer.bookingItem.debitor.refundBankAccount:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.refundBankAccount:ADMIN[[parentServer.bookingItem.debitor.refundBankAccount:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.refundBankAccount:REFERRER[[parentServer.bookingItem.debitor.refundBankAccount:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor["`**bookingItem.debitor**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.holderPerson["`**bookingItem.debitor.debitorRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.holderPerson:roles[ ]
|
|
||||||
style bookingItem.debitor.debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.debitorRel.holderPerson:OWNER[[bookingItem.debitor.debitorRel.holderPerson:OWNER]]
|
|
||||||
role:bookingItem.debitor.debitorRel.holderPerson:ADMIN[[bookingItem.debitor.debitorRel.holderPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitor.debitorRel.holderPerson:REFERRER[[bookingItem.debitor.debitorRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel["`**bookingItem.debitor.debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel:roles[ ]
|
|
||||||
style bookingItem.debitor.debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.debitorRel:OWNER[[bookingItem.debitor.debitorRel:OWNER]]
|
|
||||||
role:bookingItem.debitor.debitorRel:ADMIN[[bookingItem.debitor.debitorRel:ADMIN]]
|
|
||||||
role:bookingItem.debitor.debitorRel:AGENT[[bookingItem.debitor.debitorRel:AGENT]]
|
|
||||||
role:bookingItem.debitor.debitorRel:TENANT[[bookingItem.debitor.debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph asset["`**asset**`"]
|
subgraph asset["`**asset**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style asset fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
style asset fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
@ -407,41 +28,50 @@ subgraph asset["`**asset**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.anchorPerson["`**parentServer.bookingItem.debitor.debitorRel.anchorPerson**`"]
|
subgraph bookingItem["`**bookingItem**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style parentServer.bookingItem.debitor.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style bookingItem fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.anchorPerson:roles[ ]
|
subgraph bookingItem:roles[ ]
|
||||||
style parentServer.bookingItem.debitor.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
style bookingItem:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.anchorPerson:OWNER[[parentServer.bookingItem.debitor.debitorRel.anchorPerson:OWNER]]
|
role:bookingItem:OWNER[[bookingItem:OWNER]]
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.anchorPerson:ADMIN[[parentServer.bookingItem.debitor.debitorRel.anchorPerson:ADMIN]]
|
role:bookingItem:ADMIN[[bookingItem:ADMIN]]
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.anchorPerson:REFERRER[[parentServer.bookingItem.debitor.debitorRel.anchorPerson:REFERRER]]
|
role:bookingItem:AGENT[[bookingItem:AGENT]]
|
||||||
|
role:bookingItem:TENANT[[bookingItem:TENANT]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph bookingItem.debitorRel["`**bookingItem.debitorRel**`"]
|
||||||
|
direction TB
|
||||||
|
style bookingItem.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph bookingItem.debitorRel:roles[ ]
|
||||||
|
style bookingItem.debitorRel:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:bookingItem.debitorRel:OWNER[[bookingItem.debitorRel:OWNER]]
|
||||||
|
role:bookingItem.debitorRel:ADMIN[[bookingItem.debitorRel:ADMIN]]
|
||||||
|
role:bookingItem.debitorRel:AGENT[[bookingItem.debitorRel:AGENT]]
|
||||||
|
role:bookingItem.debitorRel:TENANT[[bookingItem.debitorRel:TENANT]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph parentServer["`**parentServer**`"]
|
||||||
|
direction TB
|
||||||
|
style parentServer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph parentServer:roles[ ]
|
||||||
|
style parentServer:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:parentServer:ADMIN[[parentServer:ADMIN]]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
%% granting roles to roles
|
%% granting roles to roles
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitor.refundBankAccount:OWNER
|
role:global:ADMIN -.-> role:bookingItem.debitorRel:OWNER
|
||||||
role:bookingItem.debitor.refundBankAccount:OWNER -.-> role:bookingItem.debitor.refundBankAccount:ADMIN
|
role:bookingItem.debitorRel:OWNER -.-> role:bookingItem.debitorRel:ADMIN
|
||||||
role:bookingItem.debitor.refundBankAccount:ADMIN -.-> role:bookingItem.debitor.refundBankAccount:REFERRER
|
role:bookingItem.debitorRel:ADMIN -.-> role:bookingItem.debitorRel:AGENT
|
||||||
role:bookingItem.debitor.refundBankAccount:ADMIN -.-> role:bookingItem.debitor.debitorRel:AGENT
|
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem.debitorRel:TENANT
|
||||||
role:bookingItem.debitor.debitorRel:AGENT -.-> role:bookingItem.debitor.refundBankAccount:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitor.partnerRel:OWNER
|
|
||||||
role:bookingItem.debitor.partnerRel:OWNER -.-> role:bookingItem.debitor.partnerRel:ADMIN
|
|
||||||
role:bookingItem.debitor.partnerRel:ADMIN -.-> role:bookingItem.debitor.partnerRel:AGENT
|
|
||||||
role:bookingItem.debitor.partnerRel:AGENT -.-> role:bookingItem.debitor.partnerRel:TENANT
|
|
||||||
role:bookingItem.debitor.partnerRel:ADMIN -.-> role:bookingItem.debitor.debitorRel:ADMIN
|
|
||||||
role:bookingItem.debitor.partnerRel:AGENT -.-> role:bookingItem.debitor.debitorRel:AGENT
|
|
||||||
role:bookingItem.debitor.debitorRel:AGENT -.-> role:bookingItem.debitor.partnerRel:TENANT
|
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitorRel.anchorPerson:OWNER
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:OWNER -.-> role:bookingItem.debitorRel.anchorPerson:ADMIN
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:ADMIN -.-> role:bookingItem.debitorRel.anchorPerson:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitorRel.holderPerson:OWNER
|
|
||||||
role:bookingItem.debitorRel.holderPerson:OWNER -.-> role:bookingItem.debitorRel.holderPerson:ADMIN
|
|
||||||
role:bookingItem.debitorRel.holderPerson:ADMIN -.-> role:bookingItem.debitorRel.holderPerson:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitorRel.contact:OWNER
|
|
||||||
role:bookingItem.debitorRel.contact:OWNER -.-> role:bookingItem.debitorRel.contact:ADMIN
|
|
||||||
role:bookingItem.debitorRel.contact:ADMIN -.-> role:bookingItem.debitorRel.contact:REFERRER
|
|
||||||
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:OWNER
|
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:OWNER
|
||||||
role:bookingItem:OWNER -.-> role:bookingItem:ADMIN
|
role:bookingItem:OWNER -.-> role:bookingItem:ADMIN
|
||||||
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:ADMIN
|
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:ADMIN
|
||||||
|
@ -6,385 +6,6 @@ This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manua
|
|||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
subgraph parentServer.bookingItem["`**parentServer.bookingItem**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem:roles[ ]
|
|
||||||
style parentServer.bookingItem:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem:OWNER[[parentServer.bookingItem:OWNER]]
|
|
||||||
role:parentServer.bookingItem:ADMIN[[parentServer.bookingItem:ADMIN]]
|
|
||||||
role:parentServer.bookingItem:AGENT[[parentServer.bookingItem:AGENT]]
|
|
||||||
role:parentServer.bookingItem:TENANT[[parentServer.bookingItem:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.anchorPerson["`**parentServer.bookingItem.debitorRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.anchorPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitorRel.anchorPerson:OWNER[[parentServer.bookingItem.debitorRel.anchorPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.anchorPerson:ADMIN[[parentServer.bookingItem.debitorRel.anchorPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.anchorPerson:REFERRER[[parentServer.bookingItem.debitorRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.holderPerson["`**parentServer.bookingItem.debitorRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.holderPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitorRel.holderPerson:OWNER[[parentServer.bookingItem.debitorRel.holderPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.holderPerson:ADMIN[[parentServer.bookingItem.debitorRel.holderPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.holderPerson:REFERRER[[parentServer.bookingItem.debitorRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer["`**parentServer**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.holderPerson["`**parentServer.bookingItem.debitor.partnerRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.holderPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.holderPerson:OWNER[[parentServer.bookingItem.debitor.partnerRel.holderPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.holderPerson:ADMIN[[parentServer.bookingItem.debitor.partnerRel.holderPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.holderPerson:REFERRER[[parentServer.bookingItem.debitor.partnerRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.anchorPerson["`**parentServer.bookingItem.debitor.partnerRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.anchorPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.anchorPerson:OWNER[[parentServer.bookingItem.debitor.partnerRel.anchorPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.anchorPerson:ADMIN[[parentServer.bookingItem.debitor.partnerRel.anchorPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.anchorPerson:REFERRER[[parentServer.bookingItem.debitor.partnerRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.anchorPerson["`**bookingItem.debitor.debitorRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.anchorPerson:roles[ ]
|
|
||||||
style bookingItem.debitor.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.debitorRel.anchorPerson:OWNER[[bookingItem.debitor.debitorRel.anchorPerson:OWNER]]
|
|
||||||
role:bookingItem.debitor.debitorRel.anchorPerson:ADMIN[[bookingItem.debitor.debitorRel.anchorPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitor.debitorRel.anchorPerson:REFERRER[[bookingItem.debitor.debitorRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.contact["`**parentServer.bookingItem.debitorRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.contact:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitorRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitorRel.contact:OWNER[[parentServer.bookingItem.debitorRel.contact:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.contact:ADMIN[[parentServer.bookingItem.debitorRel.contact:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.contact:REFERRER[[parentServer.bookingItem.debitorRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel["`**bookingItem.debitor.partnerRel**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel:roles[ ]
|
|
||||||
style bookingItem.debitor.partnerRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.partnerRel:OWNER[[bookingItem.debitor.partnerRel:OWNER]]
|
|
||||||
role:bookingItem.debitor.partnerRel:ADMIN[[bookingItem.debitor.partnerRel:ADMIN]]
|
|
||||||
role:bookingItem.debitor.partnerRel:AGENT[[bookingItem.debitor.partnerRel:AGENT]]
|
|
||||||
role:bookingItem.debitor.partnerRel:TENANT[[bookingItem.debitor.partnerRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.anchorPerson["`**bookingItem.debitor.partnerRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.anchorPerson:roles[ ]
|
|
||||||
style bookingItem.debitor.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.partnerRel.anchorPerson:OWNER[[bookingItem.debitor.partnerRel.anchorPerson:OWNER]]
|
|
||||||
role:bookingItem.debitor.partnerRel.anchorPerson:ADMIN[[bookingItem.debitor.partnerRel.anchorPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitor.partnerRel.anchorPerson:REFERRER[[bookingItem.debitor.partnerRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel["`**bookingItem.debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel:roles[ ]
|
|
||||||
style bookingItem.debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitorRel:OWNER[[bookingItem.debitorRel:OWNER]]
|
|
||||||
role:bookingItem.debitorRel:ADMIN[[bookingItem.debitorRel:ADMIN]]
|
|
||||||
role:bookingItem.debitorRel:AGENT[[bookingItem.debitorRel:AGENT]]
|
|
||||||
role:bookingItem.debitorRel:TENANT[[bookingItem.debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.contact["`**parentServer.bookingItem.debitor.partnerRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.contact:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.contact:OWNER[[parentServer.bookingItem.debitor.partnerRel.contact:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.contact:ADMIN[[parentServer.bookingItem.debitor.partnerRel.contact:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.contact:REFERRER[[parentServer.bookingItem.debitor.partnerRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.anchorPerson["`**bookingItem.debitorRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.anchorPerson:roles[ ]
|
|
||||||
style bookingItem.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:OWNER[[bookingItem.debitorRel.anchorPerson:OWNER]]
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:ADMIN[[bookingItem.debitorRel.anchorPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:REFERRER[[bookingItem.debitorRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel["`**parentServer.bookingItem.debitor.debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel:OWNER[[parentServer.bookingItem.debitor.debitorRel:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel:ADMIN[[parentServer.bookingItem.debitor.debitorRel:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel:AGENT[[parentServer.bookingItem.debitor.debitorRel:AGENT]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel:TENANT[[parentServer.bookingItem.debitor.debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.holderPerson["`**bookingItem.debitorRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.holderPerson:roles[ ]
|
|
||||||
style bookingItem.debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitorRel.holderPerson:OWNER[[bookingItem.debitorRel.holderPerson:OWNER]]
|
|
||||||
role:bookingItem.debitorRel.holderPerson:ADMIN[[bookingItem.debitorRel.holderPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitorRel.holderPerson:REFERRER[[bookingItem.debitorRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.refundBankAccount["`**bookingItem.debitor.refundBankAccount**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.refundBankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.refundBankAccount:roles[ ]
|
|
||||||
style bookingItem.debitor.refundBankAccount:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.refundBankAccount:OWNER[[bookingItem.debitor.refundBankAccount:OWNER]]
|
|
||||||
role:bookingItem.debitor.refundBankAccount:ADMIN[[bookingItem.debitor.refundBankAccount:ADMIN]]
|
|
||||||
role:bookingItem.debitor.refundBankAccount:REFERRER[[bookingItem.debitor.refundBankAccount:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel["`**parentServer.bookingItem.debitor.partnerRel**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel:OWNER[[parentServer.bookingItem.debitor.partnerRel:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel:ADMIN[[parentServer.bookingItem.debitor.partnerRel:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel:AGENT[[parentServer.bookingItem.debitor.partnerRel:AGENT]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel:TENANT[[parentServer.bookingItem.debitor.partnerRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.contact["`**bookingItem.debitor.debitorRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.contact:roles[ ]
|
|
||||||
style bookingItem.debitor.debitorRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.debitorRel.contact:OWNER[[bookingItem.debitor.debitorRel.contact:OWNER]]
|
|
||||||
role:bookingItem.debitor.debitorRel.contact:ADMIN[[bookingItem.debitor.debitorRel.contact:ADMIN]]
|
|
||||||
role:bookingItem.debitor.debitorRel.contact:REFERRER[[bookingItem.debitor.debitorRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor["`**parentServer.bookingItem.debitor**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.holderPerson["`**parentServer.bookingItem.debitor.debitorRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.holderPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.holderPerson:OWNER[[parentServer.bookingItem.debitor.debitorRel.holderPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.holderPerson:ADMIN[[parentServer.bookingItem.debitor.debitorRel.holderPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.holderPerson:REFERRER[[parentServer.bookingItem.debitor.debitorRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.contact["`**bookingItem.debitor.partnerRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.contact:roles[ ]
|
|
||||||
style bookingItem.debitor.partnerRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.partnerRel.contact:OWNER[[bookingItem.debitor.partnerRel.contact:OWNER]]
|
|
||||||
role:bookingItem.debitor.partnerRel.contact:ADMIN[[bookingItem.debitor.partnerRel.contact:ADMIN]]
|
|
||||||
role:bookingItem.debitor.partnerRel.contact:REFERRER[[bookingItem.debitor.partnerRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel["`**parentServer.bookingItem.debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitorRel:OWNER[[parentServer.bookingItem.debitorRel:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitorRel:ADMIN[[parentServer.bookingItem.debitorRel:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitorRel:AGENT[[parentServer.bookingItem.debitorRel:AGENT]]
|
|
||||||
role:parentServer.bookingItem.debitorRel:TENANT[[parentServer.bookingItem.debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem["`**bookingItem**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem:roles[ ]
|
|
||||||
style bookingItem:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem:OWNER[[bookingItem:OWNER]]
|
|
||||||
role:bookingItem:ADMIN[[bookingItem:ADMIN]]
|
|
||||||
role:bookingItem:AGENT[[bookingItem:AGENT]]
|
|
||||||
role:bookingItem:TENANT[[bookingItem:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.parentServer["`**parentServer.parentServer**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.parentServer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.contact["`**parentServer.bookingItem.debitor.debitorRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.contact:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.contact:OWNER[[parentServer.bookingItem.debitor.debitorRel.contact:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.contact:ADMIN[[parentServer.bookingItem.debitor.debitorRel.contact:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.contact:REFERRER[[parentServer.bookingItem.debitor.debitorRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.holderPerson["`**bookingItem.debitor.partnerRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.holderPerson:roles[ ]
|
|
||||||
style bookingItem.debitor.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.partnerRel.holderPerson:OWNER[[bookingItem.debitor.partnerRel.holderPerson:OWNER]]
|
|
||||||
role:bookingItem.debitor.partnerRel.holderPerson:ADMIN[[bookingItem.debitor.partnerRel.holderPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitor.partnerRel.holderPerson:REFERRER[[bookingItem.debitor.partnerRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.contact["`**bookingItem.debitorRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.contact:roles[ ]
|
|
||||||
style bookingItem.debitorRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitorRel.contact:OWNER[[bookingItem.debitorRel.contact:OWNER]]
|
|
||||||
role:bookingItem.debitorRel.contact:ADMIN[[bookingItem.debitorRel.contact:ADMIN]]
|
|
||||||
role:bookingItem.debitorRel.contact:REFERRER[[bookingItem.debitorRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.refundBankAccount["`**parentServer.bookingItem.debitor.refundBankAccount**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.refundBankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.refundBankAccount:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.refundBankAccount:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.refundBankAccount:OWNER[[parentServer.bookingItem.debitor.refundBankAccount:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.refundBankAccount:ADMIN[[parentServer.bookingItem.debitor.refundBankAccount:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.refundBankAccount:REFERRER[[parentServer.bookingItem.debitor.refundBankAccount:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor["`**bookingItem.debitor**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.holderPerson["`**bookingItem.debitor.debitorRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.holderPerson:roles[ ]
|
|
||||||
style bookingItem.debitor.debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.debitorRel.holderPerson:OWNER[[bookingItem.debitor.debitorRel.holderPerson:OWNER]]
|
|
||||||
role:bookingItem.debitor.debitorRel.holderPerson:ADMIN[[bookingItem.debitor.debitorRel.holderPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitor.debitorRel.holderPerson:REFERRER[[bookingItem.debitor.debitorRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel["`**bookingItem.debitor.debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel:roles[ ]
|
|
||||||
style bookingItem.debitor.debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.debitorRel:OWNER[[bookingItem.debitor.debitorRel:OWNER]]
|
|
||||||
role:bookingItem.debitor.debitorRel:ADMIN[[bookingItem.debitor.debitorRel:ADMIN]]
|
|
||||||
role:bookingItem.debitor.debitorRel:AGENT[[bookingItem.debitor.debitorRel:AGENT]]
|
|
||||||
role:bookingItem.debitor.debitorRel:TENANT[[bookingItem.debitor.debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph asset["`**asset**`"]
|
subgraph asset["`**asset**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style asset fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
style asset fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
@ -407,41 +28,50 @@ subgraph asset["`**asset**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.anchorPerson["`**parentServer.bookingItem.debitor.debitorRel.anchorPerson**`"]
|
subgraph bookingItem["`**bookingItem**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style parentServer.bookingItem.debitor.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style bookingItem fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.anchorPerson:roles[ ]
|
subgraph bookingItem:roles[ ]
|
||||||
style parentServer.bookingItem.debitor.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
style bookingItem:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.anchorPerson:OWNER[[parentServer.bookingItem.debitor.debitorRel.anchorPerson:OWNER]]
|
role:bookingItem:OWNER[[bookingItem:OWNER]]
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.anchorPerson:ADMIN[[parentServer.bookingItem.debitor.debitorRel.anchorPerson:ADMIN]]
|
role:bookingItem:ADMIN[[bookingItem:ADMIN]]
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.anchorPerson:REFERRER[[parentServer.bookingItem.debitor.debitorRel.anchorPerson:REFERRER]]
|
role:bookingItem:AGENT[[bookingItem:AGENT]]
|
||||||
|
role:bookingItem:TENANT[[bookingItem:TENANT]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph bookingItem.debitorRel["`**bookingItem.debitorRel**`"]
|
||||||
|
direction TB
|
||||||
|
style bookingItem.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph bookingItem.debitorRel:roles[ ]
|
||||||
|
style bookingItem.debitorRel:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:bookingItem.debitorRel:OWNER[[bookingItem.debitorRel:OWNER]]
|
||||||
|
role:bookingItem.debitorRel:ADMIN[[bookingItem.debitorRel:ADMIN]]
|
||||||
|
role:bookingItem.debitorRel:AGENT[[bookingItem.debitorRel:AGENT]]
|
||||||
|
role:bookingItem.debitorRel:TENANT[[bookingItem.debitorRel:TENANT]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph parentServer["`**parentServer**`"]
|
||||||
|
direction TB
|
||||||
|
style parentServer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph parentServer:roles[ ]
|
||||||
|
style parentServer:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:parentServer:ADMIN[[parentServer:ADMIN]]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
%% granting roles to roles
|
%% granting roles to roles
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitor.refundBankAccount:OWNER
|
role:global:ADMIN -.-> role:bookingItem.debitorRel:OWNER
|
||||||
role:bookingItem.debitor.refundBankAccount:OWNER -.-> role:bookingItem.debitor.refundBankAccount:ADMIN
|
role:bookingItem.debitorRel:OWNER -.-> role:bookingItem.debitorRel:ADMIN
|
||||||
role:bookingItem.debitor.refundBankAccount:ADMIN -.-> role:bookingItem.debitor.refundBankAccount:REFERRER
|
role:bookingItem.debitorRel:ADMIN -.-> role:bookingItem.debitorRel:AGENT
|
||||||
role:bookingItem.debitor.refundBankAccount:ADMIN -.-> role:bookingItem.debitor.debitorRel:AGENT
|
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem.debitorRel:TENANT
|
||||||
role:bookingItem.debitor.debitorRel:AGENT -.-> role:bookingItem.debitor.refundBankAccount:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitor.partnerRel:OWNER
|
|
||||||
role:bookingItem.debitor.partnerRel:OWNER -.-> role:bookingItem.debitor.partnerRel:ADMIN
|
|
||||||
role:bookingItem.debitor.partnerRel:ADMIN -.-> role:bookingItem.debitor.partnerRel:AGENT
|
|
||||||
role:bookingItem.debitor.partnerRel:AGENT -.-> role:bookingItem.debitor.partnerRel:TENANT
|
|
||||||
role:bookingItem.debitor.partnerRel:ADMIN -.-> role:bookingItem.debitor.debitorRel:ADMIN
|
|
||||||
role:bookingItem.debitor.partnerRel:AGENT -.-> role:bookingItem.debitor.debitorRel:AGENT
|
|
||||||
role:bookingItem.debitor.debitorRel:AGENT -.-> role:bookingItem.debitor.partnerRel:TENANT
|
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitorRel.anchorPerson:OWNER
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:OWNER -.-> role:bookingItem.debitorRel.anchorPerson:ADMIN
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:ADMIN -.-> role:bookingItem.debitorRel.anchorPerson:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitorRel.holderPerson:OWNER
|
|
||||||
role:bookingItem.debitorRel.holderPerson:OWNER -.-> role:bookingItem.debitorRel.holderPerson:ADMIN
|
|
||||||
role:bookingItem.debitorRel.holderPerson:ADMIN -.-> role:bookingItem.debitorRel.holderPerson:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitorRel.contact:OWNER
|
|
||||||
role:bookingItem.debitorRel.contact:OWNER -.-> role:bookingItem.debitorRel.contact:ADMIN
|
|
||||||
role:bookingItem.debitorRel.contact:ADMIN -.-> role:bookingItem.debitorRel.contact:REFERRER
|
|
||||||
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:OWNER
|
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:OWNER
|
||||||
role:bookingItem:OWNER -.-> role:bookingItem:ADMIN
|
role:bookingItem:OWNER -.-> role:bookingItem:ADMIN
|
||||||
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:ADMIN
|
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:ADMIN
|
||||||
|
@ -6,385 +6,6 @@ This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manua
|
|||||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
subgraph parentServer.bookingItem["`**parentServer.bookingItem**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem:roles[ ]
|
|
||||||
style parentServer.bookingItem:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem:OWNER[[parentServer.bookingItem:OWNER]]
|
|
||||||
role:parentServer.bookingItem:ADMIN[[parentServer.bookingItem:ADMIN]]
|
|
||||||
role:parentServer.bookingItem:AGENT[[parentServer.bookingItem:AGENT]]
|
|
||||||
role:parentServer.bookingItem:TENANT[[parentServer.bookingItem:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.anchorPerson["`**parentServer.bookingItem.debitorRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.anchorPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitorRel.anchorPerson:OWNER[[parentServer.bookingItem.debitorRel.anchorPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.anchorPerson:ADMIN[[parentServer.bookingItem.debitorRel.anchorPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.anchorPerson:REFERRER[[parentServer.bookingItem.debitorRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.holderPerson["`**parentServer.bookingItem.debitorRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.holderPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitorRel.holderPerson:OWNER[[parentServer.bookingItem.debitorRel.holderPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.holderPerson:ADMIN[[parentServer.bookingItem.debitorRel.holderPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.holderPerson:REFERRER[[parentServer.bookingItem.debitorRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer["`**parentServer**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.holderPerson["`**parentServer.bookingItem.debitor.partnerRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.holderPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.holderPerson:OWNER[[parentServer.bookingItem.debitor.partnerRel.holderPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.holderPerson:ADMIN[[parentServer.bookingItem.debitor.partnerRel.holderPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.holderPerson:REFERRER[[parentServer.bookingItem.debitor.partnerRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.anchorPerson["`**parentServer.bookingItem.debitor.partnerRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.anchorPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.anchorPerson:OWNER[[parentServer.bookingItem.debitor.partnerRel.anchorPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.anchorPerson:ADMIN[[parentServer.bookingItem.debitor.partnerRel.anchorPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.anchorPerson:REFERRER[[parentServer.bookingItem.debitor.partnerRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.anchorPerson["`**bookingItem.debitor.debitorRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.anchorPerson:roles[ ]
|
|
||||||
style bookingItem.debitor.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.debitorRel.anchorPerson:OWNER[[bookingItem.debitor.debitorRel.anchorPerson:OWNER]]
|
|
||||||
role:bookingItem.debitor.debitorRel.anchorPerson:ADMIN[[bookingItem.debitor.debitorRel.anchorPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitor.debitorRel.anchorPerson:REFERRER[[bookingItem.debitor.debitorRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.contact["`**parentServer.bookingItem.debitorRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel.contact:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitorRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitorRel.contact:OWNER[[parentServer.bookingItem.debitorRel.contact:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.contact:ADMIN[[parentServer.bookingItem.debitorRel.contact:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitorRel.contact:REFERRER[[parentServer.bookingItem.debitorRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel["`**bookingItem.debitor.partnerRel**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel:roles[ ]
|
|
||||||
style bookingItem.debitor.partnerRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.partnerRel:OWNER[[bookingItem.debitor.partnerRel:OWNER]]
|
|
||||||
role:bookingItem.debitor.partnerRel:ADMIN[[bookingItem.debitor.partnerRel:ADMIN]]
|
|
||||||
role:bookingItem.debitor.partnerRel:AGENT[[bookingItem.debitor.partnerRel:AGENT]]
|
|
||||||
role:bookingItem.debitor.partnerRel:TENANT[[bookingItem.debitor.partnerRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.anchorPerson["`**bookingItem.debitor.partnerRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.anchorPerson:roles[ ]
|
|
||||||
style bookingItem.debitor.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.partnerRel.anchorPerson:OWNER[[bookingItem.debitor.partnerRel.anchorPerson:OWNER]]
|
|
||||||
role:bookingItem.debitor.partnerRel.anchorPerson:ADMIN[[bookingItem.debitor.partnerRel.anchorPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitor.partnerRel.anchorPerson:REFERRER[[bookingItem.debitor.partnerRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel["`**bookingItem.debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel:roles[ ]
|
|
||||||
style bookingItem.debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitorRel:OWNER[[bookingItem.debitorRel:OWNER]]
|
|
||||||
role:bookingItem.debitorRel:ADMIN[[bookingItem.debitorRel:ADMIN]]
|
|
||||||
role:bookingItem.debitorRel:AGENT[[bookingItem.debitorRel:AGENT]]
|
|
||||||
role:bookingItem.debitorRel:TENANT[[bookingItem.debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.contact["`**parentServer.bookingItem.debitor.partnerRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel.contact:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.contact:OWNER[[parentServer.bookingItem.debitor.partnerRel.contact:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.contact:ADMIN[[parentServer.bookingItem.debitor.partnerRel.contact:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel.contact:REFERRER[[parentServer.bookingItem.debitor.partnerRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.anchorPerson["`**bookingItem.debitorRel.anchorPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.anchorPerson:roles[ ]
|
|
||||||
style bookingItem.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:OWNER[[bookingItem.debitorRel.anchorPerson:OWNER]]
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:ADMIN[[bookingItem.debitorRel.anchorPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:REFERRER[[bookingItem.debitorRel.anchorPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel["`**parentServer.bookingItem.debitor.debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel:OWNER[[parentServer.bookingItem.debitor.debitorRel:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel:ADMIN[[parentServer.bookingItem.debitor.debitorRel:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel:AGENT[[parentServer.bookingItem.debitor.debitorRel:AGENT]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel:TENANT[[parentServer.bookingItem.debitor.debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.holderPerson["`**bookingItem.debitorRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.holderPerson:roles[ ]
|
|
||||||
style bookingItem.debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitorRel.holderPerson:OWNER[[bookingItem.debitorRel.holderPerson:OWNER]]
|
|
||||||
role:bookingItem.debitorRel.holderPerson:ADMIN[[bookingItem.debitorRel.holderPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitorRel.holderPerson:REFERRER[[bookingItem.debitorRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.refundBankAccount["`**bookingItem.debitor.refundBankAccount**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.refundBankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.refundBankAccount:roles[ ]
|
|
||||||
style bookingItem.debitor.refundBankAccount:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.refundBankAccount:OWNER[[bookingItem.debitor.refundBankAccount:OWNER]]
|
|
||||||
role:bookingItem.debitor.refundBankAccount:ADMIN[[bookingItem.debitor.refundBankAccount:ADMIN]]
|
|
||||||
role:bookingItem.debitor.refundBankAccount:REFERRER[[bookingItem.debitor.refundBankAccount:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel["`**parentServer.bookingItem.debitor.partnerRel**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.partnerRel:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.partnerRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel:OWNER[[parentServer.bookingItem.debitor.partnerRel:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel:ADMIN[[parentServer.bookingItem.debitor.partnerRel:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel:AGENT[[parentServer.bookingItem.debitor.partnerRel:AGENT]]
|
|
||||||
role:parentServer.bookingItem.debitor.partnerRel:TENANT[[parentServer.bookingItem.debitor.partnerRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.contact["`**bookingItem.debitor.debitorRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.contact:roles[ ]
|
|
||||||
style bookingItem.debitor.debitorRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.debitorRel.contact:OWNER[[bookingItem.debitor.debitorRel.contact:OWNER]]
|
|
||||||
role:bookingItem.debitor.debitorRel.contact:ADMIN[[bookingItem.debitor.debitorRel.contact:ADMIN]]
|
|
||||||
role:bookingItem.debitor.debitorRel.contact:REFERRER[[bookingItem.debitor.debitorRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor["`**parentServer.bookingItem.debitor**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.holderPerson["`**parentServer.bookingItem.debitor.debitorRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.holderPerson:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.holderPerson:OWNER[[parentServer.bookingItem.debitor.debitorRel.holderPerson:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.holderPerson:ADMIN[[parentServer.bookingItem.debitor.debitorRel.holderPerson:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.holderPerson:REFERRER[[parentServer.bookingItem.debitor.debitorRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.contact["`**bookingItem.debitor.partnerRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.contact:roles[ ]
|
|
||||||
style bookingItem.debitor.partnerRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.partnerRel.contact:OWNER[[bookingItem.debitor.partnerRel.contact:OWNER]]
|
|
||||||
role:bookingItem.debitor.partnerRel.contact:ADMIN[[bookingItem.debitor.partnerRel.contact:ADMIN]]
|
|
||||||
role:bookingItem.debitor.partnerRel.contact:REFERRER[[bookingItem.debitor.partnerRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel["`**parentServer.bookingItem.debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitorRel:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitorRel:OWNER[[parentServer.bookingItem.debitorRel:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitorRel:ADMIN[[parentServer.bookingItem.debitorRel:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitorRel:AGENT[[parentServer.bookingItem.debitorRel:AGENT]]
|
|
||||||
role:parentServer.bookingItem.debitorRel:TENANT[[parentServer.bookingItem.debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem["`**bookingItem**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem:roles[ ]
|
|
||||||
style bookingItem:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem:OWNER[[bookingItem:OWNER]]
|
|
||||||
role:bookingItem:ADMIN[[bookingItem:ADMIN]]
|
|
||||||
role:bookingItem:AGENT[[bookingItem:AGENT]]
|
|
||||||
role:bookingItem:TENANT[[bookingItem:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.parentServer["`**parentServer.parentServer**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.parentServer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.contact["`**parentServer.bookingItem.debitor.debitorRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.contact:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.debitorRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.contact:OWNER[[parentServer.bookingItem.debitor.debitorRel.contact:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.contact:ADMIN[[parentServer.bookingItem.debitor.debitorRel.contact:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.contact:REFERRER[[parentServer.bookingItem.debitor.debitorRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.holderPerson["`**bookingItem.debitor.partnerRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.partnerRel.holderPerson:roles[ ]
|
|
||||||
style bookingItem.debitor.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.partnerRel.holderPerson:OWNER[[bookingItem.debitor.partnerRel.holderPerson:OWNER]]
|
|
||||||
role:bookingItem.debitor.partnerRel.holderPerson:ADMIN[[bookingItem.debitor.partnerRel.holderPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitor.partnerRel.holderPerson:REFERRER[[bookingItem.debitor.partnerRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.contact["`**bookingItem.debitorRel.contact**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitorRel.contact:roles[ ]
|
|
||||||
style bookingItem.debitorRel.contact:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitorRel.contact:OWNER[[bookingItem.debitorRel.contact:OWNER]]
|
|
||||||
role:bookingItem.debitorRel.contact:ADMIN[[bookingItem.debitorRel.contact:ADMIN]]
|
|
||||||
role:bookingItem.debitorRel.contact:REFERRER[[bookingItem.debitorRel.contact:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.refundBankAccount["`**parentServer.bookingItem.debitor.refundBankAccount**`"]
|
|
||||||
direction TB
|
|
||||||
style parentServer.bookingItem.debitor.refundBankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.refundBankAccount:roles[ ]
|
|
||||||
style parentServer.bookingItem.debitor.refundBankAccount:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.refundBankAccount:OWNER[[parentServer.bookingItem.debitor.refundBankAccount:OWNER]]
|
|
||||||
role:parentServer.bookingItem.debitor.refundBankAccount:ADMIN[[parentServer.bookingItem.debitor.refundBankAccount:ADMIN]]
|
|
||||||
role:parentServer.bookingItem.debitor.refundBankAccount:REFERRER[[parentServer.bookingItem.debitor.refundBankAccount:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor["`**bookingItem.debitor**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.holderPerson["`**bookingItem.debitor.debitorRel.holderPerson**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel.holderPerson:roles[ ]
|
|
||||||
style bookingItem.debitor.debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.debitorRel.holderPerson:OWNER[[bookingItem.debitor.debitorRel.holderPerson:OWNER]]
|
|
||||||
role:bookingItem.debitor.debitorRel.holderPerson:ADMIN[[bookingItem.debitor.debitorRel.holderPerson:ADMIN]]
|
|
||||||
role:bookingItem.debitor.debitorRel.holderPerson:REFERRER[[bookingItem.debitor.debitorRel.holderPerson:REFERRER]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel["`**bookingItem.debitor.debitorRel**`"]
|
|
||||||
direction TB
|
|
||||||
style bookingItem.debitor.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
|
||||||
|
|
||||||
subgraph bookingItem.debitor.debitorRel:roles[ ]
|
|
||||||
style bookingItem.debitor.debitorRel:roles fill:#99bcdb,stroke:white
|
|
||||||
|
|
||||||
role:bookingItem.debitor.debitorRel:OWNER[[bookingItem.debitor.debitorRel:OWNER]]
|
|
||||||
role:bookingItem.debitor.debitorRel:ADMIN[[bookingItem.debitor.debitorRel:ADMIN]]
|
|
||||||
role:bookingItem.debitor.debitorRel:AGENT[[bookingItem.debitor.debitorRel:AGENT]]
|
|
||||||
role:bookingItem.debitor.debitorRel:TENANT[[bookingItem.debitor.debitorRel:TENANT]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph asset["`**asset**`"]
|
subgraph asset["`**asset**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style asset fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
style asset fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
@ -407,53 +28,56 @@ subgraph asset["`**asset**`"]
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.anchorPerson["`**parentServer.bookingItem.debitor.debitorRel.anchorPerson**`"]
|
subgraph bookingItem["`**bookingItem**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style parentServer.bookingItem.debitor.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style bookingItem fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
subgraph parentServer.bookingItem.debitor.debitorRel.anchorPerson:roles[ ]
|
subgraph bookingItem:roles[ ]
|
||||||
style parentServer.bookingItem.debitor.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
style bookingItem:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.anchorPerson:OWNER[[parentServer.bookingItem.debitor.debitorRel.anchorPerson:OWNER]]
|
role:bookingItem:OWNER[[bookingItem:OWNER]]
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.anchorPerson:ADMIN[[parentServer.bookingItem.debitor.debitorRel.anchorPerson:ADMIN]]
|
role:bookingItem:ADMIN[[bookingItem:ADMIN]]
|
||||||
role:parentServer.bookingItem.debitor.debitorRel.anchorPerson:REFERRER[[parentServer.bookingItem.debitor.debitorRel.anchorPerson:REFERRER]]
|
role:bookingItem:AGENT[[bookingItem:AGENT]]
|
||||||
|
role:bookingItem:TENANT[[bookingItem:TENANT]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph bookingItem.debitorRel["`**bookingItem.debitorRel**`"]
|
||||||
|
direction TB
|
||||||
|
style bookingItem.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph bookingItem.debitorRel:roles[ ]
|
||||||
|
style bookingItem.debitorRel:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:bookingItem.debitorRel:OWNER[[bookingItem.debitorRel:OWNER]]
|
||||||
|
role:bookingItem.debitorRel:ADMIN[[bookingItem.debitorRel:ADMIN]]
|
||||||
|
role:bookingItem.debitorRel:AGENT[[bookingItem.debitorRel:AGENT]]
|
||||||
|
role:bookingItem.debitorRel:TENANT[[bookingItem.debitorRel:TENANT]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph parentServer["`**parentServer**`"]
|
||||||
|
direction TB
|
||||||
|
style parentServer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph parentServer:roles[ ]
|
||||||
|
style parentServer:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:parentServer:ADMIN[[parentServer:ADMIN]]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
%% granting roles to roles
|
%% granting roles to roles
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitor.refundBankAccount:OWNER
|
role:global:ADMIN -.-> role:bookingItem.debitorRel:OWNER
|
||||||
role:bookingItem.debitor.refundBankAccount:OWNER -.-> role:bookingItem.debitor.refundBankAccount:ADMIN
|
role:bookingItem.debitorRel:OWNER -.-> role:bookingItem.debitorRel:ADMIN
|
||||||
role:bookingItem.debitor.refundBankAccount:ADMIN -.-> role:bookingItem.debitor.refundBankAccount:REFERRER
|
role:bookingItem.debitorRel:ADMIN -.-> role:bookingItem.debitorRel:AGENT
|
||||||
role:bookingItem.debitor.refundBankAccount:ADMIN -.-> role:bookingItem.debitor.debitorRel:AGENT
|
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem.debitorRel:TENANT
|
||||||
role:bookingItem.debitor.debitorRel:AGENT -.-> role:bookingItem.debitor.refundBankAccount:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitor.partnerRel:OWNER
|
|
||||||
role:bookingItem.debitor.partnerRel:OWNER -.-> role:bookingItem.debitor.partnerRel:ADMIN
|
|
||||||
role:bookingItem.debitor.partnerRel:ADMIN -.-> role:bookingItem.debitor.partnerRel:AGENT
|
|
||||||
role:bookingItem.debitor.partnerRel:AGENT -.-> role:bookingItem.debitor.partnerRel:TENANT
|
|
||||||
role:bookingItem.debitor.partnerRel:ADMIN -.-> role:bookingItem.debitor.debitorRel:ADMIN
|
|
||||||
role:bookingItem.debitor.partnerRel:AGENT -.-> role:bookingItem.debitor.debitorRel:AGENT
|
|
||||||
role:bookingItem.debitor.debitorRel:AGENT -.-> role:bookingItem.debitor.partnerRel:TENANT
|
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitorRel.anchorPerson:OWNER
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:OWNER -.-> role:bookingItem.debitorRel.anchorPerson:ADMIN
|
|
||||||
role:bookingItem.debitorRel.anchorPerson:ADMIN -.-> role:bookingItem.debitorRel.anchorPerson:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitorRel.holderPerson:OWNER
|
|
||||||
role:bookingItem.debitorRel.holderPerson:OWNER -.-> role:bookingItem.debitorRel.holderPerson:ADMIN
|
|
||||||
role:bookingItem.debitorRel.holderPerson:ADMIN -.-> role:bookingItem.debitorRel.holderPerson:REFERRER
|
|
||||||
role:global:ADMIN -.-> role:bookingItem.debitorRel.contact:OWNER
|
|
||||||
role:bookingItem.debitorRel.contact:OWNER -.-> role:bookingItem.debitorRel.contact:ADMIN
|
|
||||||
role:bookingItem.debitorRel.contact:ADMIN -.-> role:bookingItem.debitorRel.contact:REFERRER
|
|
||||||
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:OWNER
|
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:OWNER
|
||||||
role:bookingItem:OWNER -.-> role:bookingItem:ADMIN
|
role:bookingItem:OWNER -.-> role:bookingItem:ADMIN
|
||||||
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:ADMIN
|
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:ADMIN
|
||||||
role:bookingItem:ADMIN -.-> role:bookingItem:AGENT
|
role:bookingItem:ADMIN -.-> role:bookingItem:AGENT
|
||||||
role:bookingItem:AGENT -.-> role:bookingItem:TENANT
|
role:bookingItem:AGENT -.-> role:bookingItem:TENANT
|
||||||
role:bookingItem:TENANT -.-> role:bookingItem.debitorRel:TENANT
|
role:bookingItem:TENANT -.-> role:bookingItem.debitorRel:TENANT
|
||||||
role:parentServer.bookingItem.debitorRel:AGENT -.-> role:parentServer.bookingItem:OWNER
|
|
||||||
role:parentServer.bookingItem:OWNER -.-> role:parentServer.bookingItem:ADMIN
|
|
||||||
role:parentServer.bookingItem.debitorRel:AGENT -.-> role:parentServer.bookingItem:ADMIN
|
|
||||||
role:parentServer.bookingItem:ADMIN -.-> role:parentServer.bookingItem:AGENT
|
|
||||||
role:parentServer.bookingItem:AGENT -.-> role:parentServer.bookingItem:TENANT
|
|
||||||
role:parentServer.bookingItem:TENANT -.-> role:parentServer.bookingItem.debitorRel:TENANT
|
|
||||||
role:bookingItem:ADMIN ==> role:asset:OWNER
|
role:bookingItem:ADMIN ==> role:asset:OWNER
|
||||||
role:asset:OWNER ==> role:asset:ADMIN
|
role:asset:OWNER ==> role:asset:ADMIN
|
||||||
role:asset:ADMIN ==> role:asset:TENANT
|
role:asset:ADMIN ==> role:asset:TENANT
|
||||||
@ -461,6 +85,7 @@ role:asset:TENANT ==> role:bookingItem:TENANT
|
|||||||
|
|
||||||
%% granting permissions to roles
|
%% granting permissions to roles
|
||||||
role:bookingItem:AGENT ==> perm:asset:INSERT
|
role:bookingItem:AGENT ==> perm:asset:INSERT
|
||||||
|
role:parentServer:ADMIN ==> perm:asset:INSERT
|
||||||
role:asset:OWNER ==> perm:asset:DELETE
|
role:asset:OWNER ==> perm:asset:DELETE
|
||||||
role:asset:ADMIN ==> perm:asset:UPDATE
|
role:asset:ADMIN ==> perm:asset:UPDATE
|
||||||
role:asset:TENANT ==> perm:asset:SELECT
|
role:asset:TENANT ==> perm:asset:SELECT
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
### rbac asset inOtherCases
|
||||||
|
|
||||||
|
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
|
flowchart TB
|
||||||
|
|
||||||
|
subgraph asset["`**asset**`"]
|
||||||
|
direction TB
|
||||||
|
style asset fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph asset:roles[ ]
|
||||||
|
style asset:roles fill:#dd4901,stroke:white
|
||||||
|
|
||||||
|
role:asset:OWNER[[asset:OWNER]]
|
||||||
|
role:asset:ADMIN[[asset:ADMIN]]
|
||||||
|
role:asset:TENANT[[asset:TENANT]]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph asset:permissions[ ]
|
||||||
|
style asset:permissions fill:#dd4901,stroke:white
|
||||||
|
|
||||||
|
perm:asset:INSERT{{asset:INSERT}}
|
||||||
|
perm:asset:DELETE{{asset:DELETE}}
|
||||||
|
perm:asset:UPDATE{{asset:UPDATE}}
|
||||||
|
perm:asset:SELECT{{asset:SELECT}}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph bookingItem["`**bookingItem**`"]
|
||||||
|
direction TB
|
||||||
|
style bookingItem fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph bookingItem:roles[ ]
|
||||||
|
style bookingItem:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:bookingItem:OWNER[[bookingItem:OWNER]]
|
||||||
|
role:bookingItem:ADMIN[[bookingItem:ADMIN]]
|
||||||
|
role:bookingItem:AGENT[[bookingItem:AGENT]]
|
||||||
|
role:bookingItem:TENANT[[bookingItem:TENANT]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph bookingItem.debitorRel["`**bookingItem.debitorRel**`"]
|
||||||
|
direction TB
|
||||||
|
style bookingItem.debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph bookingItem.debitorRel:roles[ ]
|
||||||
|
style bookingItem.debitorRel:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:bookingItem.debitorRel:OWNER[[bookingItem.debitorRel:OWNER]]
|
||||||
|
role:bookingItem.debitorRel:ADMIN[[bookingItem.debitorRel:ADMIN]]
|
||||||
|
role:bookingItem.debitorRel:AGENT[[bookingItem.debitorRel:AGENT]]
|
||||||
|
role:bookingItem.debitorRel:TENANT[[bookingItem.debitorRel:TENANT]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph parentServer["`**parentServer**`"]
|
||||||
|
direction TB
|
||||||
|
style parentServer fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph parentServer:roles[ ]
|
||||||
|
style parentServer:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:parentServer:ADMIN[[parentServer:ADMIN]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
%% granting roles to roles
|
||||||
|
role:global:ADMIN -.-> role:bookingItem.debitorRel:OWNER
|
||||||
|
role:bookingItem.debitorRel:OWNER -.-> role:bookingItem.debitorRel:ADMIN
|
||||||
|
role:bookingItem.debitorRel:ADMIN -.-> role:bookingItem.debitorRel:AGENT
|
||||||
|
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem.debitorRel:TENANT
|
||||||
|
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:OWNER
|
||||||
|
role:bookingItem:OWNER -.-> role:bookingItem:ADMIN
|
||||||
|
role:bookingItem.debitorRel:AGENT -.-> role:bookingItem:ADMIN
|
||||||
|
role:bookingItem:ADMIN -.-> role:bookingItem:AGENT
|
||||||
|
role:bookingItem:AGENT -.-> role:bookingItem:TENANT
|
||||||
|
role:bookingItem:TENANT -.-> role:bookingItem.debitorRel:TENANT
|
||||||
|
role:bookingItem:ADMIN ==> role:asset:OWNER
|
||||||
|
role:asset:OWNER ==> role:asset:ADMIN
|
||||||
|
role:asset:ADMIN ==> role:asset:TENANT
|
||||||
|
role:asset:TENANT ==> role:bookingItem:TENANT
|
||||||
|
|
||||||
|
%% granting permissions to roles
|
||||||
|
role:asset:OWNER ==> perm:asset:DELETE
|
||||||
|
role:asset:ADMIN ==> perm:asset:UPDATE
|
||||||
|
role:asset:TENANT ==> perm:asset:SELECT
|
||||||
|
|
||||||
|
```
|
@ -64,6 +64,7 @@ begin
|
|||||||
IF NEW.type = 'CLOUD_SERVER' THEN
|
IF NEW.type = 'CLOUD_SERVER' THEN
|
||||||
ELSIF NEW.type = 'MANAGED_SERVER' THEN
|
ELSIF NEW.type = 'MANAGED_SERVER' THEN
|
||||||
ELSIF NEW.type = 'MANAGED_WEBSPACE' THEN
|
ELSIF NEW.type = 'MANAGED_WEBSPACE' THEN
|
||||||
|
ELSE
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||||
@ -90,80 +91,126 @@ execute procedure insertTriggerForHsHostingAsset_tf();
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-hosting-asset-rbac-INSERT:1 endDelimiter:--//
|
--changeset hs-hosting-asset-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- granting INSERT permission to hs_booking_item ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates INSERT INTO hs_hosting_asset permissions for the related hs_booking_item rows.
|
Grants INSERT INTO hs_hosting_asset permissions to specified role of pre-existing hs_booking_item rows.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
row hs_booking_item;
|
row hs_booking_item;
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO hs_hosting_asset permissions for the related hs_booking_item rows');
|
call defineContext('create INSERT INTO hs_hosting_asset permissions for pre-exising hs_booking_item rows');
|
||||||
|
|
||||||
FOR row IN SELECT * FROM hs_booking_item
|
FOR row IN SELECT * FROM hs_booking_item
|
||||||
|
-- unconditional for all rows in that table
|
||||||
LOOP
|
LOOP
|
||||||
call grantPermissionToRole(
|
call grantPermissionToRole(
|
||||||
createPermission(row.uuid, 'INSERT', 'hs_hosting_asset'),
|
createPermission(row.uuid, 'INSERT', 'hs_hosting_asset'),
|
||||||
hsBookingItemAGENT(row));
|
hsBookingItemAGENT(row));
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds hs_hosting_asset INSERT permission to specified role of new hs_booking_item rows.
|
Grants hs_hosting_asset INSERT permission to specified role of new hs_booking_item rows.
|
||||||
*/
|
*/
|
||||||
create or replace function hs_hosting_asset_hs_booking_item_insert_tf()
|
create or replace function new_hs_hosting_asset_grants_insert_to_hs_booking_item_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
-- unconditional for all rows in that table
|
||||||
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_hosting_asset'),
|
createPermission(NEW.uuid, 'INSERT', 'hs_hosting_asset'),
|
||||||
hsBookingItemAGENT(NEW));
|
hsBookingItemAGENT(NEW));
|
||||||
|
-- end.
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
create trigger z_hs_hosting_asset_hs_booking_item_insert_tg
|
create trigger z_new_hs_hosting_asset_grants_insert_to_hs_booking_item_tg
|
||||||
after insert on hs_booking_item
|
after insert on hs_booking_item
|
||||||
for each row
|
for each row
|
||||||
execute procedure hs_hosting_asset_hs_booking_item_insert_tf();
|
execute procedure new_hs_hosting_asset_grants_insert_to_hs_booking_item_tf();
|
||||||
|
|
||||||
|
-- granting INSERT permission to hs_hosting_asset ----------------------------
|
||||||
|
|
||||||
|
-- Granting INSERT INTO hs_hosting_asset permissions to specified role of pre-existing hs_hosting_asset rows slipped,
|
||||||
|
-- because there cannot yet be any pre-existing rows in the same table yet.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to hs_hosting_asset,
|
Grants hs_hosting_asset INSERT permission to specified role of new hs_hosting_asset rows.
|
||||||
where the check is performed by a direct role.
|
|
||||||
|
|
||||||
A direct role is a role depending on a foreign key directly available in the NEW row.
|
|
||||||
*/
|
*/
|
||||||
create or replace function hs_hosting_asset_insert_permission_missing_tf()
|
create or replace function new_hs_hosting_asset_grants_insert_to_hs_hosting_asset_tf()
|
||||||
|
returns trigger
|
||||||
|
language plpgsql
|
||||||
|
strict as $$
|
||||||
|
begin
|
||||||
|
if NEW.type = 'MANAGED_SERVER' then
|
||||||
|
call grantPermissionToRole(
|
||||||
|
createPermission(NEW.uuid, 'INSERT', 'hs_hosting_asset'),
|
||||||
|
hsHostingAssetADMIN(NEW));
|
||||||
|
end if;
|
||||||
|
return NEW;
|
||||||
|
end; $$;
|
||||||
|
|
||||||
|
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||||
|
create trigger z_new_hs_hosting_asset_grants_insert_to_hs_hosting_asset_tg
|
||||||
|
after insert on hs_hosting_asset
|
||||||
|
for each row
|
||||||
|
execute procedure new_hs_hosting_asset_grants_insert_to_hs_hosting_asset_tf();
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs_hosting_asset-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks if the user respectively the assumed roles are allowed to insert a row to hs_hosting_asset.
|
||||||
|
*/
|
||||||
|
create or replace function hs_hosting_asset_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
superObjectUuid uuid;
|
||||||
begin
|
begin
|
||||||
|
-- check INSERT permission via direct foreign key: NEW.bookingItemUuid
|
||||||
|
if NEW.type in ('MANAGED_SERVER', 'CLOUD_SERVER', 'MANAGED_WEBSPACE') and hasInsertPermission(NEW.bookingItemUuid, 'hs_hosting_asset') then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
-- check INSERT permission via direct foreign key: NEW.parentAssetUuid
|
||||||
|
if NEW.type in ('MANAGED_WEBSPACE') and hasInsertPermission(NEW.parentAssetUuid, 'hs_hosting_asset') then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
|
||||||
raise exception '[403] insert into hs_hosting_asset not allowed for current subjects % (%)',
|
raise exception '[403] insert into hs_hosting_asset not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create trigger hs_hosting_asset_insert_permission_check_tg
|
create trigger hs_hosting_asset_insert_permission_check_tg
|
||||||
before insert on hs_hosting_asset
|
before insert on hs_hosting_asset
|
||||||
for each row
|
for each row
|
||||||
when ( not hasInsertPermission(NEW.bookingItemUuid, 'INSERT', 'hs_hosting_asset') )
|
execute procedure hs_hosting_asset_insert_permission_check_tf();
|
||||||
execute procedure hs_hosting_asset_insert_permission_missing_tf();
|
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-hosting-asset-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-hosting-asset-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
call generateRbacIdentityViewFromQuery('hs_hosting_asset',
|
call generateRbacIdentityViewFromQuery('hs_hosting_asset',
|
||||||
$idName$
|
$idName$
|
||||||
SELECT asset.uuid as uuid, bookingItemIV.idName || '-' || cleanIdentifier(asset.identifier) as idName
|
SELECT asset.uuid as uuid, bookingItemIV.idName || '-' || cleanIdentifier(asset.identifier) as idName
|
||||||
FROM hs_hosting_asset asset
|
FROM hs_hosting_asset asset
|
||||||
JOIN hs_booking_item_iv bookingItemIV ON bookingItemIV.uuid = asset.bookingItemUuid
|
JOIN hs_booking_item_iv bookingItemIV ON bookingItemIV.uuid = asset.bookingItemUuid
|
||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-hosting-asset-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-hosting-asset-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
@ -18,6 +18,7 @@ declare
|
|||||||
currentTask varchar;
|
currentTask varchar;
|
||||||
relatedDebitor hs_office_debitor;
|
relatedDebitor hs_office_debitor;
|
||||||
relatedBookingItem hs_booking_item;
|
relatedBookingItem hs_booking_item;
|
||||||
|
managedServerUuid uuid;
|
||||||
begin
|
begin
|
||||||
currentTask := 'creating hosting-asset test-data ' || givenPartnerNumber::text || givenDebitorSuffix;
|
currentTask := 'creating hosting-asset test-data ' || givenPartnerNumber::text || givenDebitorSuffix;
|
||||||
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
|
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
|
||||||
@ -33,14 +34,15 @@ begin
|
|||||||
from hs_booking_item item
|
from hs_booking_item item
|
||||||
where item.debitoruuid = relatedDebitor.uuid
|
where item.debitoruuid = relatedDebitor.uuid
|
||||||
and item.caption = 'some PrivateCloud';
|
and item.caption = 'some PrivateCloud';
|
||||||
|
select uuid_generate_v4() into managedServerUuid;
|
||||||
|
|
||||||
raise notice 'creating test hosting-asset: %', givenPartnerNumber::text || givenDebitorSuffix::text;
|
raise notice 'creating test hosting-asset: %', givenPartnerNumber::text || givenDebitorSuffix::text;
|
||||||
raise notice '- using debitor (%): %', relatedDebitor.uuid, relatedDebitor;
|
raise notice '- using debitor (%): %', relatedDebitor.uuid, relatedDebitor;
|
||||||
insert
|
insert
|
||||||
into hs_hosting_asset (uuid, bookingitemuuid, type, identifier, caption, config)
|
into hs_hosting_asset (uuid, bookingitemuuid, type, parentAssetUuid, identifier, caption, config)
|
||||||
values (uuid_generate_v4(), relatedBookingItem.uuid, 'MANAGED_SERVER'::HsHostingAssetType, 'vm10' || givenDebitorSuffix, 'some ManagedServer', '{ "CPU": 2, "SDD": 512, "extra": 42 }'::jsonb),
|
values (managedServerUuid, relatedBookingItem.uuid, 'MANAGED_SERVER', null, 'vm10' || givenDebitorSuffix, 'some ManagedServer', '{ "CPU": 2, "SDD": 512, "extra": 42 }'::jsonb),
|
||||||
(uuid_generate_v4(), relatedBookingItem.uuid, 'CLOUD_SERVER'::HsHostingAssetType, 'vm20' || givenDebitorSuffix, 'another CloudServer', '{ "CPU": 2, "HDD": 1024, "extra": 42 }'::jsonb),
|
(uuid_generate_v4(), relatedBookingItem.uuid, 'CLOUD_SERVER', null, 'vm20' || givenDebitorSuffix, 'another CloudServer', '{ "CPU": 2, "HDD": 1024, "extra": 42 }'::jsonb),
|
||||||
(uuid_generate_v4(), relatedBookingItem.uuid, 'MANAGED_WEBSPACE'::HsHostingAssetType, givenWebspacePrefix || '01', 'some Webspace', '{ "RAM": 1, "SDD": 512, "HDD": 2048, "extra": 42 }'::jsonb);
|
(uuid_generate_v4(), relatedBookingItem.uuid, 'MANAGED_WEBSPACE', managedServerUuid, givenWebspacePrefix || '01', 'some Webspace', '{ "RAM": 1, "SDD": 512, "HDD": 2048, "extra": 42 }'::jsonb);
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ databaseChangeLog:
|
|||||||
file: db/changelog/0-basis/006-numeric-hash-functions.sql
|
file: db/changelog/0-basis/006-numeric-hash-functions.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/0-basis/007-table-columns.sql
|
file: db/changelog/0-basis/007-table-columns.sql
|
||||||
|
- include:
|
||||||
|
file: db/changelog/0-basis/008-raise-functions.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/0-basis/009-check-environment.sql
|
file: db/changelog/0-basis/009-check-environment.sql
|
||||||
- include:
|
- include:
|
||||||
|
@ -68,12 +68,13 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var count = assetRepo.count();
|
final var count = assetRepo.count();
|
||||||
final var givenBookingItem = givenBookingItem("First", "some CloudServer");
|
final var givenManagedServer = givenManagedServer("First", "some ManagedServer");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(em, () -> {
|
||||||
final var newAsset = HsHostingAssetEntity.builder()
|
final var newAsset = HsHostingAssetEntity.builder()
|
||||||
.bookingItem(givenBookingItem)
|
.bookingItem(givenManagedServer.getBookingItem())
|
||||||
|
.parentAsset(givenManagedServer)
|
||||||
.caption("some new managed webspace")
|
.caption("some new managed webspace")
|
||||||
.type(HsHostingAssetType.MANAGED_WEBSPACE)
|
.type(HsHostingAssetType.MANAGED_WEBSPACE)
|
||||||
.identifier("xyz90")
|
.identifier("xyz90")
|
||||||
@ -96,14 +97,14 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll()).stream()
|
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll()).stream()
|
||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
.toList();
|
.toList();
|
||||||
final var givenBookingItem = givenBookingItem("First", "some CloudServer");
|
final var givenBookingItem = givenBookingItem("First", "some PrivateCloud");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(em, () -> {
|
||||||
final var newAsset = HsHostingAssetEntity.builder()
|
final var newAsset = HsHostingAssetEntity.builder()
|
||||||
.bookingItem(givenBookingItem)
|
.bookingItem(givenBookingItem)
|
||||||
.type(HsHostingAssetType.MANAGED_WEBSPACE)
|
.type(HsHostingAssetType.MANAGED_SERVER)
|
||||||
.identifier("xyz91")
|
.identifier("vm9000")
|
||||||
.caption("some new managed webspace")
|
.caption("some new managed webspace")
|
||||||
.build();
|
.build();
|
||||||
return toCleanup(assetRepo.save(newAsset));
|
return toCleanup(assetRepo.save(newAsset));
|
||||||
@ -114,27 +115,27 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
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_hosting_asset#D-1000111-someCloudServer-xyz91:ADMIN",
|
"hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:ADMIN",
|
||||||
"hs_hosting_asset#D-1000111-someCloudServer-xyz91:OWNER",
|
"hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:OWNER",
|
||||||
"hs_hosting_asset#D-1000111-someCloudServer-xyz91:TENANT"));
|
"hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:TENANT"));
|
||||||
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,
|
||||||
// global-admin
|
|
||||||
|
|
||||||
// owner
|
// owner
|
||||||
"{ grant perm:hs_hosting_asset#D-1000111-someCloudServer-xyz91:DELETE to role:hs_hosting_asset#D-1000111-someCloudServer-xyz91:OWNER by system and assume }",
|
"{ grant perm:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:DELETE to role:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:OWNER by system and assume }",
|
||||||
|
"{ grant role:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:OWNER to role:hs_booking_item#D-1000111-somePrivateCloud:ADMIN by system and assume }",
|
||||||
|
|
||||||
// admin
|
// admin
|
||||||
"{ grant perm:hs_hosting_asset#D-1000111-someCloudServer-xyz91:UPDATE to role:hs_hosting_asset#D-1000111-someCloudServer-xyz91:ADMIN by system and assume }",
|
"{ grant perm:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:INSERT>hs_hosting_asset to role:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:ADMIN by system and assume }",
|
||||||
"{ grant role:hs_hosting_asset#D-1000111-someCloudServer-xyz91:ADMIN to role:hs_hosting_asset#D-1000111-someCloudServer-xyz91:OWNER by system and assume }",
|
"{ grant perm:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:UPDATE to role:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:ADMIN by system and assume }",
|
||||||
"{ grant role:hs_hosting_asset#D-1000111-someCloudServer-xyz91:OWNER to role:hs_booking_item#D-1000111-someCloudServer:ADMIN by system and assume }",
|
"{ grant role:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:ADMIN to role:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:OWNER by system and assume }",
|
||||||
|
|
||||||
// tenant
|
// tenant
|
||||||
"{ grant perm:hs_hosting_asset#D-1000111-someCloudServer-xyz91:SELECT to role:hs_hosting_asset#D-1000111-someCloudServer-xyz91:TENANT by system and assume }",
|
"{ grant perm:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:SELECT to role:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:TENANT by system and assume }",
|
||||||
"{ grant role:hs_hosting_asset#D-1000111-someCloudServer-xyz91:TENANT to role:hs_hosting_asset#D-1000111-someCloudServer-xyz91:ADMIN by system and assume }",
|
"{ grant role:hs_booking_item#D-1000111-somePrivateCloud:TENANT to role:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:TENANT by system and assume }",
|
||||||
"{ grant role:hs_booking_item#D-1000111-someCloudServer:TENANT to role:hs_hosting_asset#D-1000111-someCloudServer-xyz91:TENANT by system and assume }",
|
"{ grant role:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:TENANT to role:hs_hosting_asset#D-1000111-somePrivateCloud-vm9000:ADMIN by system and assume }",
|
||||||
|
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
@ -161,7 +162,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
// then
|
// then
|
||||||
allTheseServersAreReturned(
|
allTheseServersAreReturned(
|
||||||
result,
|
result,
|
||||||
"HsHostingAssetEntity(D-1000212:some PrivateCloud, MANAGED_WEBSPACE, bbb01, some Webspace, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })",
|
"HsHostingAssetEntity(D-1000212:some PrivateCloud, MANAGED_WEBSPACE, D-1000212:some PrivateCloud:vm1012, bbb01, some Webspace, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })",
|
||||||
"HsHostingAssetEntity(D-1000212:some PrivateCloud, MANAGED_SERVER, vm1012, some ManagedServer, { CPU: 2, SDD: 512, extra: 42 })",
|
"HsHostingAssetEntity(D-1000212:some PrivateCloud, MANAGED_SERVER, vm1012, some ManagedServer, { CPU: 2, SDD: 512, extra: 42 })",
|
||||||
"HsHostingAssetEntity(D-1000212:some PrivateCloud, CLOUD_SERVER, vm2012, another CloudServer, { CPU: 2, HDD: 1024, extra: 42 })");
|
"HsHostingAssetEntity(D-1000212:some PrivateCloud, CLOUD_SERVER, vm2012, another CloudServer, { CPU: 2, HDD: 1024, extra: 42 })");
|
||||||
}
|
}
|
||||||
@ -178,7 +179,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
// then:
|
// then:
|
||||||
exactlyTheseAssetsAreReturned(
|
exactlyTheseAssetsAreReturned(
|
||||||
result,
|
result,
|
||||||
"HsHostingAssetEntity(D-1000111:some PrivateCloud, MANAGED_WEBSPACE, aaa01, some Webspace, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })",
|
"HsHostingAssetEntity(D-1000111:some PrivateCloud, MANAGED_WEBSPACE, D-1000111:some PrivateCloud:vm1011, aaa01, some Webspace, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })",
|
||||||
"HsHostingAssetEntity(D-1000111:some PrivateCloud, MANAGED_SERVER, vm1011, some ManagedServer, { CPU: 2, SDD: 512, extra: 42 })",
|
"HsHostingAssetEntity(D-1000111:some PrivateCloud, MANAGED_SERVER, vm1011, some ManagedServer, { CPU: 2, SDD: 512, extra: 42 })",
|
||||||
"HsHostingAssetEntity(D-1000111:some PrivateCloud, CLOUD_SERVER, vm2011, another CloudServer, { CPU: 2, HDD: 1024, extra: 42 })");
|
"HsHostingAssetEntity(D-1000111:some PrivateCloud, CLOUD_SERVER, vm2011, another CloudServer, { CPU: 2, HDD: 1024, extra: 42 })");
|
||||||
}
|
}
|
||||||
@ -352,6 +353,13 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HsHostingAssetEntity givenManagedServer(final String debitorName, final String hostingAssetCaption) {
|
||||||
|
final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike(debitorName).stream().findAny().orElseThrow();
|
||||||
|
return assetRepo.findAllByDebitorUuid(givenDebitor.getUuid()).stream()
|
||||||
|
.filter(i -> i.getCaption().equals(hostingAssetCaption))
|
||||||
|
.findAny().orElseThrow();
|
||||||
|
}
|
||||||
|
|
||||||
void exactlyTheseAssetsAreReturned(
|
void exactlyTheseAssetsAreReturned(
|
||||||
final List<HsHostingAssetEntity> actualResult,
|
final List<HsHostingAssetEntity> actualResult,
|
||||||
final String... serverNames) {
|
final String... serverNames) {
|
||||||
|
Loading…
Reference in New Issue
Block a user