fixes for generated multiple insert permission grants, hs_booking_item and hs_hosting_asset green
This commit is contained in:
parent
69b6baaeb3
commit
708064142f
@ -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;
|
||||||
@ -157,7 +158,9 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject {
|
|||||||
directlyFetchedByDependsOnColumn(),
|
directlyFetchedByDependsOnColumn(),
|
||||||
NULLABLE)
|
NULLABLE)
|
||||||
.toRole("parentServer", ADMIN).grantPermission(INSERT)
|
.toRole("parentServer", ADMIN).grantPermission(INSERT)
|
||||||
)
|
.toRole("bookingItem", AGENT).grantPermission(INSERT)
|
||||||
|
),
|
||||||
|
inOtherCases(then -> {})
|
||||||
)
|
)
|
||||||
|
|
||||||
.createRole(OWNER, (with) -> {
|
.createRole(OWNER, (with) -> {
|
||||||
|
@ -64,27 +64,28 @@ public class InsertTriggerGenerator {
|
|||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
preExistingRow ${rawSuperTable};
|
row ${rawSuperTable};
|
||||||
begin
|
begin
|
||||||
call defineContext('create INSERT INTO ${rawSubTable} permissions for pre-exising ${rawSuperTable} rows');
|
call defineContext('create INSERT INTO ${rawSubTable} permissions for pre-exising ${rawSuperTable} rows');
|
||||||
|
|
||||||
FOR preExistingRow IN SELECT * FROM ${rawSuperTable}
|
FOR row IN SELECT * FROM ${rawSuperTable}
|
||||||
${whenCondition}
|
${whenCondition}
|
||||||
LOOP
|
LOOP
|
||||||
call grantPermissionToRole(
|
call grantPermissionToRole(
|
||||||
createPermission(preExistingRow.uuid, 'INSERT', '${rawSubTable}'),
|
createPermission(row.uuid, 'INSERT', '${rawSubTable}'),
|
||||||
hsBookingItemAGENT(preExistingRow));
|
${superRoleRef});
|
||||||
END LOOP;
|
END LOOP;
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
""",
|
""",
|
||||||
with("whenCondition", g.getSuperRoleDef().getEntityAlias().isCaseDependent()
|
with("whenCondition", g.getSuperRoleDef().getEntityAlias().isCaseDependent()
|
||||||
// TODO.impl: .type needs to be dynamically generated
|
// TODO.impl: 'type' needs to be dynamically generated
|
||||||
? "WHERE preExistingRow.type = '${value}'"
|
? "WHERE type = '${value}'"
|
||||||
.replace("${value}", g.getSuperRoleDef().getEntityAlias().usingCase().value)
|
.replace("${value}", g.getSuperRoleDef().getEntityAlias().usingCase().value)
|
||||||
: "-- unconditional for all rows in that table"),
|
: "-- unconditional for all rows in that table"),
|
||||||
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
|
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
|
||||||
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()));
|
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()),
|
||||||
|
with("superRoleRef", toRoleDescriptor(g.getSuperRoleDef(), "row")));
|
||||||
} else {
|
} else {
|
||||||
plPgSql.writeLn("""
|
plPgSql.writeLn("""
|
||||||
-- Granting INSERT INTO hs_hosting_asset permissions to specified role of pre-existing hs_hosting_asset rows slipped,
|
-- Granting INSERT INTO hs_hosting_asset permissions to specified role of pre-existing hs_hosting_asset rows slipped,
|
||||||
@ -166,46 +167,64 @@ public class InsertTriggerGenerator {
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset ${rawSubTable}-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
--changeset ${rawSubTable}-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to insert a row to ${rawSubTable},
|
Checks if the user respectively the assumed roles are allowed to insert a row to ${rawSubTable}.
|
||||||
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 ${rawSubTable}_insert_permission_missing_tf()
|
create or replace function ${rawSubTable}_insert_permission_check_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
|
declare
|
||||||
|
superObjectUuid uuid;
|
||||||
begin
|
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 (
|
|
||||||
""",
|
""",
|
||||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||||
plPgSql.chopEmptyLines();
|
plPgSql.chopEmptyLines();
|
||||||
|
|
||||||
plPgSql.indented(3, () -> {
|
plPgSql.indented(1, () -> {
|
||||||
getInsertGrants().forEach(g -> {
|
getInsertGrants().forEach(g -> {
|
||||||
final RbacView.EntityAlias superRoleEntityAlias = g.getSuperRoleDef().getEntityAlias();
|
final RbacView.EntityAlias superRoleEntityAlias = g.getSuperRoleDef().getEntityAlias();
|
||||||
final RbacView.EntityAlias permissionEntityAlias = g.getPermDef().entityAlias;
|
|
||||||
final var caseCondition = superRoleEntityAlias.isCaseDependent()
|
if (g.getSuperRoleDef().getEntityAlias().isFetchedByDirectForeignKey()) {
|
||||||
? ("NEW.type in (" + toStringList(g.getForCases()) + ") and ")
|
final var caseCondition = g.isConditional()
|
||||||
: "";
|
? ("NEW.type in (" + toStringList(g.getForCases()) + ") and ")
|
||||||
if ( g.getSuperRoleDef().isGlobalAdmin() ) {
|
: "";
|
||||||
plPgSql.writeLn(
|
if (g.getSuperRoleDef().isGlobalAdmin()) {
|
||||||
"${caseCondition}isGlobalAdmin() or",
|
plPgSql.writeLn(
|
||||||
|
"""
|
||||||
|
-- check INSERT INSERT permission via isGlobalAdmin
|
||||||
|
if ${caseCondition}isGlobalAdmin() then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
""",
|
||||||
with("caseCondition", caseCondition));
|
with("caseCondition", caseCondition));
|
||||||
} else {
|
} else {
|
||||||
plPgSql.writeLn(
|
plPgSql.writeLn(
|
||||||
"${caseCondition}hasInsertPermission(NEW.${refColumn}, '${rawSubTable}') or",
|
"""
|
||||||
|
-- check INSERT permission via direct foreign key: NEW.${refColumn}
|
||||||
|
if ${caseCondition}hasInsertPermission(NEW.${refColumn}, '${rawSubTable}') then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
""",
|
||||||
with("caseCondition", caseCondition),
|
with("caseCondition", caseCondition),
|
||||||
with("refColumn", superRoleEntityAlias.dependsOnColumName()),
|
with("refColumn", superRoleEntityAlias.dependsOnColumName()),
|
||||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
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 hasInsertPermission(superObjectUuid, '${rawSubTable}') then
|
||||||
|
return NEW;
|
||||||
|
end if;
|
||||||
|
""",
|
||||||
|
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()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
plPgSql.chopTail(" or\n");
|
plPgSql.chopTail(" or\n");
|
||||||
@ -213,8 +232,14 @@ public class InsertTriggerGenerator {
|
|||||||
plPgSql.writeLn();
|
plPgSql.writeLn();
|
||||||
|
|
||||||
plPgSql.writeLn("""
|
plPgSql.writeLn("""
|
||||||
) )
|
raise exception '[403] insert into ${rawSubTable} not allowed for current subjects % (%)',
|
||||||
execute procedure ${rawSubTable}_insert_permission_missing_tf();
|
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()));
|
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -535,7 +535,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() {
|
||||||
@ -860,6 +860,7 @@ 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()
|
||||||
|
.map(g -> g.forCase(processingCase))
|
||||||
.orElseGet(() -> new RbacGrantDefinition(permDef, roleDef, processingCase));
|
.orElseGet(() -> new RbacGrantDefinition(permDef, roleDef, processingCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,469 @@
|
|||||||
|
### rbac asset inOtherCases
|
||||||
|
|
||||||
|
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
|
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
|
||||||
|
|
||||||
|
subgraph parentServer:roles[ ]
|
||||||
|
style parentServer:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:parentServer:ADMIN[[parentServer:ADMIN]]
|
||||||
|
end
|
||||||
|
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**`"]
|
||||||
|
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 parentServer.bookingItem.debitor.debitorRel.anchorPerson["`**parentServer.bookingItem.debitor.debitorRel.anchorPerson**`"]
|
||||||
|
direction TB
|
||||||
|
style parentServer.bookingItem.debitor.debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph parentServer.bookingItem.debitor.debitorRel.anchorPerson:roles[ ]
|
||||||
|
style parentServer.bookingItem.debitor.debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:parentServer.bookingItem.debitor.debitorRel.anchorPerson:OWNER[[parentServer.bookingItem.debitor.debitorRel.anchorPerson:OWNER]]
|
||||||
|
role:parentServer.bookingItem.debitor.debitorRel.anchorPerson:ADMIN[[parentServer.bookingItem.debitor.debitorRel.anchorPerson:ADMIN]]
|
||||||
|
role:parentServer.bookingItem.debitor.debitorRel.anchorPerson:REFERRER[[parentServer.bookingItem.debitor.debitorRel.anchorPerson:REFERRER]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
%% granting roles to roles
|
||||||
|
role:global:ADMIN -.-> role:bookingItem.debitor.refundBankAccount:OWNER
|
||||||
|
role:bookingItem.debitor.refundBankAccount:OWNER -.-> role:bookingItem.debitor.refundBankAccount:ADMIN
|
||||||
|
role:bookingItem.debitor.refundBankAccount:ADMIN -.-> role:bookingItem.debitor.refundBankAccount:REFERRER
|
||||||
|
role:bookingItem.debitor.refundBankAccount:ADMIN -.-> role:bookingItem.debitor.debitorRel:AGENT
|
||||||
|
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: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:bookingItem:AGENT ==> perm:asset:INSERT
|
||||||
|
role:parentServer:ADMIN ==> perm:asset:INSERT
|
||||||
|
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);
|
||||||
@ -178,7 +179,7 @@ declare
|
|||||||
superObjectUuid uuid;
|
superObjectUuid uuid;
|
||||||
begin
|
begin
|
||||||
-- check INSERT permission via direct foreign key: NEW.bookingItemUuid
|
-- check INSERT permission via direct foreign key: NEW.bookingItemUuid
|
||||||
if NEW.type in ('CLOUD_SERVER', 'MANAGED_SERVER', 'MANAGED_WEBSPACE') and hasInsertPermission(NEW.bookingItemUuid, 'hs_hosting_asset') then
|
if NEW.type in ('MANAGED_SERVER', 'CLOUD_SERVER', 'MANAGED_WEBSPACE') and hasInsertPermission(NEW.bookingItemUuid, 'hs_hosting_asset') then
|
||||||
return NEW;
|
return NEW;
|
||||||
end if;
|
end if;
|
||||||
-- check INSERT permission via direct foreign key: NEW.parentAssetUuid
|
-- check INSERT permission via direct foreign key: NEW.parentAssetUuid
|
||||||
|
Loading…
Reference in New Issue
Block a user