fixes for generated multiple insert permission grants, hs_booking_item and hs_hosting_asset green

This commit is contained in:
Michael Hoennig 2024-04-26 10:41:56 +02:00
parent 69b6baaeb3
commit 708064142f
7 changed files with 547 additions and 47 deletions

View File

@ -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_WEBSPACE;
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.ColumnValue.usingCase;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
@ -157,7 +158,9 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject {
directlyFetchedByDependsOnColumn(),
NULLABLE)
.toRole("parentServer", ADMIN).grantPermission(INSERT)
)
.toRole("bookingItem", AGENT).grantPermission(INSERT)
),
inOtherCases(then -> {})
)
.createRole(OWNER, (with) -> {

View File

@ -64,27 +64,28 @@ public class InsertTriggerGenerator {
*/
do language plpgsql $$
declare
preExistingRow ${rawSuperTable};
row ${rawSuperTable};
begin
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}
LOOP
call grantPermissionToRole(
createPermission(preExistingRow.uuid, 'INSERT', '${rawSubTable}'),
hsBookingItemAGENT(preExistingRow));
createPermission(row.uuid, 'INSERT', '${rawSubTable}'),
${superRoleRef});
END LOOP;
end;
$$;
""",
with("whenCondition", g.getSuperRoleDef().getEntityAlias().isCaseDependent()
// TODO.impl: .type needs to be dynamically generated
? "WHERE preExistingRow.type = '${value}'"
// 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("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,
@ -166,46 +167,64 @@ public class InsertTriggerGenerator {
-- ============================================================================
--changeset ${rawSubTable}-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/**
Checks if the user or 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.
Checks if the user respectively the assumed roles are allowed to insert a row to ${rawSubTable}.
*/
create or replace function ${rawSubTable}_insert_permission_missing_tf()
create or replace function ${rawSubTable}_insert_permission_check_tf()
returns trigger
language plpgsql as $$
declare
superObjectUuid uuid;
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.indented(3, () -> {
plPgSql.indented(1, () -> {
getInsertGrants().forEach(g -> {
final RbacView.EntityAlias superRoleEntityAlias = g.getSuperRoleDef().getEntityAlias();
final RbacView.EntityAlias permissionEntityAlias = g.getPermDef().entityAlias;
final var caseCondition = superRoleEntityAlias.isCaseDependent()
? ("NEW.type in (" + toStringList(g.getForCases()) + ") and ")
: "";
if ( g.getSuperRoleDef().isGlobalAdmin() ) {
plPgSql.writeLn(
"${caseCondition}isGlobalAdmin() or",
if (g.getSuperRoleDef().getEntityAlias().isFetchedByDirectForeignKey()) {
final var caseCondition = g.isConditional()
? ("NEW.type in (" + toStringList(g.getForCases()) + ") and ")
: "";
if (g.getSuperRoleDef().isGlobalAdmin()) {
plPgSql.writeLn(
"""
-- check INSERT INSERT permission via isGlobalAdmin
if ${caseCondition}isGlobalAdmin() then
return NEW;
end if;
""",
with("caseCondition", caseCondition));
} else {
plPgSql.writeLn(
"${caseCondition}hasInsertPermission(NEW.${refColumn}, '${rawSubTable}') or",
} else {
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 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");
@ -213,8 +232,14 @@ public class InsertTriggerGenerator {
plPgSql.writeLn();
plPgSql.writeLn("""
) )
execute procedure ${rawSubTable}_insert_permission_missing_tf();
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()));

View File

@ -32,10 +32,10 @@ public class RbacIdentityViewGenerator {
$idName$);
""";
case SQL_QUERY -> """
call generateRbacIdentityViewFromQuery('${rawTableName}',
$idName$
${identityViewSqlPart}
$idName$);
call generateRbacIdentityViewFromQuery('${rawTableName}',
$idName$
${identityViewSqlPart}
$idName$);
""";
default -> throw new IllegalStateException("illegal SQL part given");
},
@ -43,5 +43,6 @@ public class RbacIdentityViewGenerator {
with("rawTableName", rawTableName));
plPgSql.writeLn("--//");
plPgSql.writeLn();
}
}

View File

@ -535,7 +535,7 @@ public class RbacView {
private final RbacPermissionDefinition permDef;
private boolean assumed = true;
private boolean toCreate = false;
private Set<CaseDef> forCases = new HashSet<>();
private Set<CaseDef> forCases = new LinkedHashSet<>();
@Override
public String toString() {
@ -860,6 +860,7 @@ public class RbacView {
return grantDefs.stream()
.filter(g -> g.permDef == permDef && g.superRoleDef == roleDef)
.findFirst()
.map(g -> g.forCase(processingCase))
.orElseGet(() -> new RbacGrantDefinition(permDef, roleDef, processingCase));
}

View File

@ -2,8 +2,6 @@ package net.hostsharing.hsadminng.rbac.rbacdef;
import org.apache.commons.lang3.StringUtils;
import java.util.regex.Pattern;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.joining;
@ -111,9 +109,11 @@ public class StringWriter {
String apply(final String textToAppend) {
text = textToAppend;
stream(varDefs).forEach(varDef -> {
final var pattern = Pattern.compile("\\$\\{" + varDef.name() + "}", Pattern.CASE_INSENSITIVE);
final var matcher = pattern.matcher(text);
text = matcher.replaceAll(varDef.value());
// TODO.impl: I actually want a case-independent search+replace but ...
// for which the substitution String can contain sequences of "${...}" to be replaced by further varDefs.
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;
}

View File

@ -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
```

View File

@ -64,6 +64,7 @@ begin
IF NEW.type = 'CLOUD_SERVER' THEN
ELSIF NEW.type = 'MANAGED_SERVER' THEN
ELSIF NEW.type = 'MANAGED_WEBSPACE' THEN
ELSE
END IF;
call leaveTriggerForObjectUuid(NEW.uuid);
@ -178,7 +179,7 @@ declare
superObjectUuid uuid;
begin
-- 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;
end if;
-- check INSERT permission via direct foreign key: NEW.parentAssetUuid