move Parter+Debitor person+contact to related Relationsship #20
@ -16,11 +16,11 @@ import org.hibernate.annotations.GenericGenerator;
|
|||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
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.Nullable.NULLABLE;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
|
||||||
@ -108,7 +108,7 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
public static RbacView rbac() {
|
public static RbacView rbac() {
|
||||||
return rbacViewFor("debitor", HsOfficeDebitorEntity.class)
|
return rbacViewFor("debitor", HsOfficeDebitorEntity.class)
|
||||||
.withIdentityView(SQL.query("""
|
.withIdentityView(SQL.query("""
|
||||||
SELECT debitor.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_relationship partnerRel
|
JOIN hs_office_relationship partnerRel
|
||||||
@ -116,9 +116,10 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
JOIN hs_office_relationship debitorRel
|
JOIN hs_office_relationship debitorRel
|
||||||
ON debitorRel.relAnchorUuid = partnerRel.relHolderUuid AND partnerRel.relType = 'ACCOUNTING'
|
ON debitorRel.relAnchorUuid = partnerRel.relHolderUuid AND partnerRel.relType = 'ACCOUNTING'
|
||||||
WHERE debitorRel.uuid = debitor.debitorRelUuid)
|
WHERE debitorRel.uuid = debitor.debitorRelUuid)
|
||||||
|| to_char(debitorNumberSuffix, 'fm00')
|
|| to_char(debitorNumberSuffix, 'fm00') as idName
|
||||||
from hs_office_debitor as debitor
|
FROM hs_office_debitor AS debitor
|
||||||
"""))
|
"""))
|
||||||
|
.withRestrictedViewOrderBy(SQL.projection("defaultPrefix"))
|
||||||
.withUpdatableColumns(
|
.withUpdatableColumns(
|
||||||
"debitorRel",
|
"debitorRel",
|
||||||
"billable",
|
"billable",
|
||||||
@ -129,13 +130,13 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
"vatBusiness",
|
"vatBusiness",
|
||||||
"vatReverseCharge",
|
"vatReverseCharge",
|
||||||
"defaultPrefix" /* TODO: do we want that updatable? */)
|
"defaultPrefix" /* TODO: do we want that updatable? */)
|
||||||
.createPermission(custom("new-debitor")).grantedTo("global", ADMIN)
|
.toRole("global", ADMIN).grantPermission("debitor", INSERT)
|
||||||
|
|
||||||
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationshipEntity.class,
|
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationshipEntity.class,
|
||||||
fetchedBySql("""
|
fetchedBySql("""
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM hs_office_relationship AS r
|
FROM hs_office_relationship AS r
|
||||||
WHERE r.relType = 'ACCOUNTING' AND r.relHolderUuid = ${REF}.debitorRelUuid
|
WHERE r.relType = 'ACCOUNTING' AND r.uuid = ${REF}.debitorRelUuid
|
||||||
"""),
|
"""),
|
||||||
dependsOnColumn("debitorRelUuid"))
|
dependsOnColumn("debitorRelUuid"))
|
||||||
.createPermission(DELETE).grantedTo("debitorRel", OWNER)
|
.createPermission(DELETE).grantedTo("debitorRel", OWNER)
|
||||||
@ -143,21 +144,27 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
.createPermission(SELECT).grantedTo("debitorRel", TENANT)
|
.createPermission(SELECT).grantedTo("debitorRel", TENANT)
|
||||||
|
|
||||||
.importEntityAlias("refundBankAccount", HsOfficeBankAccountEntity.class,
|
.importEntityAlias("refundBankAccount", HsOfficeBankAccountEntity.class,
|
||||||
dependsOnColumn("refundBankAccountUuid"), fetchedBySql("""
|
dependsOnColumn("refundBankAccountUuid"),
|
||||||
|
fetchedBySql("""
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM hs_office_relationship AS r
|
FROM hs_office_relationship AS r
|
||||||
WHERE r.relType = 'ACCOUNTING' AND r.relHolderUuid = ${REF}.debitorRelUuid
|
WHERE r.relType = 'ACCOUNTING' AND r.relHolderUuid = ${REF}.debitorRelUuid
|
||||||
""")
|
"""),
|
||||||
|
NULLABLE
|
||||||
)
|
)
|
||||||
.toRole("refundBankAccount", ADMIN).grantRole("debitorRel", AGENT)
|
.toRole("refundBankAccount", ADMIN).grantRole("debitorRel", AGENT)
|
||||||
.toRole("debitorRel", AGENT).grantRole("refundBankAccount", REFERRER)
|
.toRole("debitorRel", AGENT).grantRole("refundBankAccount", REFERRER)
|
||||||
|
|
||||||
.importEntityAlias("partnerRel", HsOfficeRelationshipEntity.class,
|
.importEntityAlias("partnerRel", HsOfficeRelationshipEntity.class,
|
||||||
dependsOnColumn("partnerRelUuid"), fetchedBySql("""
|
dependsOnColumn("debitorRelUuid"),
|
||||||
SELECT *
|
fetchedBySql("""
|
||||||
FROM hs_office_relationship AS partnerRel
|
SELECT partnerRel.*
|
||||||
WHERE ${debitorRel}.relAnchorUuid = partnerRel.relHolderUuid
|
FROM hs_office_relationship AS partnerRel
|
||||||
""")
|
JOIN hs_office_relationship AS debitorRel
|
||||||
|
ON debitorRel.relType = 'ACCOUNTING' AND debitorRel.relAnchorUuid = partnerRel.relHolderUuid
|
||||||
|
WHERE partnerRel.relType = 'PARTNER'
|
||||||
|
AND ${REF}.debitorRelUuid = debitorRel.uuid
|
||||||
|
""")
|
||||||
)
|
)
|
||||||
.toRole("partnerRel", ADMIN).grantRole("debitorRel", ADMIN)
|
.toRole("partnerRel", ADMIN).grantRole("debitorRel", ADMIN)
|
||||||
.toRole("partnerRel", AGENT).grantRole("debitorRel", AGENT)
|
.toRole("partnerRel", AGENT).grantRole("debitorRel", AGENT)
|
||||||
@ -169,6 +176,6 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
rbac().generateWithBaseFileName("273-hs-office-debitor-rbac-generated");
|
rbac().generateWithBaseFileName("273-hs-office-debitor-rbac");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ public class HsOfficePartnerDetailsEntity implements HasUuid, Stringifyable {
|
|||||||
"birthName",
|
"birthName",
|
||||||
"birthday",
|
"birthday",
|
||||||
"dateOfDeath")
|
"dateOfDeath")
|
||||||
.createPermission(custom("new-partner-details")).grantedTo("global", ADMIN)
|
.toRole("global", ADMIN).grantPermission("partner-details", INSERT)
|
||||||
|
|
||||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationshipEntity.class,
|
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationshipEntity.class,
|
||||||
fetchedBySql("""
|
fetchedBySql("""
|
||||||
|
@ -27,7 +27,6 @@ import jakarta.persistence.ManyToOne;
|
|||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||||
@ -105,7 +104,7 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
|
|||||||
"partnerRoleUuid",
|
"partnerRoleUuid",
|
||||||
"personUuid",
|
"personUuid",
|
||||||
"contactUuid")
|
"contactUuid")
|
||||||
.createPermission(custom("new-partner")).grantedTo("global", ADMIN)
|
.toRole("global", ADMIN).grantPermission("partner", INSERT) // FIXME: global -> partnerRel.relAnchor?
|
||||||
|
|
||||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationshipEntity.class,
|
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationshipEntity.class,
|
||||||
fetchedBySql("SELECT * FROM hs_office_relationship AS r WHERE r.uuid = ${ref}.partnerRoleUuid"),
|
fetchedBySql("SELECT * FROM hs_office_relationship AS r WHERE r.uuid = ${ref}.partnerRoleUuid"),
|
||||||
|
@ -55,7 +55,7 @@ public class InsertTriggerGenerator {
|
|||||||
LOOP
|
LOOP
|
||||||
roleUuid := findRoleId(${rawSuperRoleDescriptor});
|
roleUuid := findRoleId(${rawSuperRoleDescriptor});
|
||||||
permissionUuid := createPermission(row.uuid, 'INSERT', '${rawSubTableName}');
|
permissionUuid := createPermission(row.uuid, 'INSERT', '${rawSubTableName}');
|
||||||
call grantPermissionToRole(roleUuid, permissionUuid);
|
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END;
|
END;
|
||||||
$$;
|
$$;
|
||||||
|
@ -32,6 +32,7 @@ import java.util.stream.Stream;
|
|||||||
import static java.lang.reflect.Modifier.isStatic;
|
import static java.lang.reflect.Modifier.isStatic;
|
||||||
import static java.util.Arrays.stream;
|
import static java.util.Arrays.stream;
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||||
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.autoFetched;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.autoFetched;
|
||||||
import static org.apache.commons.lang3.StringUtils.uncapitalize;
|
import static org.apache.commons.lang3.StringUtils.uncapitalize;
|
||||||
@ -141,35 +142,42 @@ public class RbacView {
|
|||||||
if (rootEntityAliasProxy != null) {
|
if (rootEntityAliasProxy != null) {
|
||||||
throw new IllegalStateException("there is already an entityAliasProxy: " + rootEntityAliasProxy);
|
throw new IllegalStateException("there is already an entityAliasProxy: " + rootEntityAliasProxy);
|
||||||
}
|
}
|
||||||
rootEntityAliasProxy = importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum, false);
|
rootEntityAliasProxy = importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum, false, NOT_NULL);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RbacView importSubEntityAlias(
|
public RbacView importSubEntityAlias(
|
||||||
final String aliasName, final Class<? extends HasUuid> entityClass,
|
final String aliasName, final Class<? extends HasUuid> entityClass,
|
||||||
final SQL fetchSql, final Column dependsOnColum) {
|
final SQL fetchSql, final Column dependsOnColum) {
|
||||||
importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum, true);
|
importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum, true, NOT_NULL);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RbacView importEntityAlias(
|
||||||
|
final String aliasName, final Class<? extends HasUuid> entityClass,
|
||||||
|
final Column dependsOnColum, final SQL fetchSql, final Nullable nullable) {
|
||||||
|
importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum, false, nullable);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RbacView importEntityAlias(
|
public RbacView importEntityAlias(
|
||||||
final String aliasName, final Class<? extends HasUuid> entityClass,
|
final String aliasName, final Class<? extends HasUuid> entityClass,
|
||||||
final Column dependsOnColum, final SQL fetchSql) {
|
final Column dependsOnColum, final SQL fetchSql) {
|
||||||
importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum, false);
|
importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum, false, NOT_NULL);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RbacView importEntityAlias(
|
public RbacView importEntityAlias(
|
||||||
final String aliasName, final Class<? extends HasUuid> entityClass,
|
final String aliasName, final Class<? extends HasUuid> entityClass,
|
||||||
final Column dependsOnColum) {
|
final Column dependsOnColum) {
|
||||||
importEntityAliasImpl(aliasName, entityClass, autoFetched(), dependsOnColum, false);
|
importEntityAliasImpl(aliasName, entityClass, autoFetched(), dependsOnColum, false, null);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private EntityAlias importEntityAliasImpl(
|
private EntityAlias importEntityAliasImpl(
|
||||||
final String aliasName, final Class<? extends HasUuid> entityClass,
|
final String aliasName, final Class<? extends HasUuid> entityClass,
|
||||||
final SQL fetchSql, final Column dependsOnColum, boolean asSubEntity) {
|
final SQL fetchSql, final Column dependsOnColum, boolean asSubEntity, final Nullable nullable) {
|
||||||
final var entityAlias = new EntityAlias(aliasName, entityClass, fetchSql, dependsOnColum, asSubEntity);
|
final var entityAlias = new EntityAlias(aliasName, entityClass, fetchSql, dependsOnColum, asSubEntity, nullable);
|
||||||
entityAliases.put(aliasName, entityAlias);
|
entityAliases.put(aliasName, entityAlias);
|
||||||
try {
|
try {
|
||||||
importAsAlias(aliasName, rbacDefinition(entityClass), asSubEntity);
|
importAsAlias(aliasName, rbacDefinition(entityClass), asSubEntity);
|
||||||
@ -281,6 +289,7 @@ public class RbacView {
|
|||||||
return RbacView.this;
|
return RbacView.this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: switch order or parameters for more natural readability
|
||||||
public RbacView grantPermission(final String entityAliasName, final Permission perm) {
|
public RbacView grantPermission(final String entityAliasName, final Permission perm) {
|
||||||
final var entityAlias = findEntityAlias(entityAliasName);
|
final var entityAlias = findEntityAlias(entityAliasName);
|
||||||
final var forTable = entityAlias.getRawTableName();
|
final var forTable = entityAlias.getRawTableName();
|
||||||
@ -290,6 +299,11 @@ public class RbacView {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum Nullable {
|
||||||
|
NOT_NULL, // DEFAULT
|
||||||
|
NULLABLE
|
||||||
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
public class RbacGrantDefinition {
|
public class RbacGrantDefinition {
|
||||||
@ -560,14 +574,14 @@ public class RbacView {
|
|||||||
.orElseGet(() -> new RbacGrantDefinition(subRoleDefinition, superRoleDefinition));
|
.orElseGet(() -> new RbacGrantDefinition(subRoleDefinition, superRoleDefinition));
|
||||||
}
|
}
|
||||||
|
|
||||||
record EntityAlias(String aliasName, Class<? extends RbacObject> entityClass, SQL fetchSql, Column dependsOnColum, boolean isSubEntity) {
|
record EntityAlias(String aliasName, Class<? extends RbacObject> entityClass, SQL fetchSql, Column dependsOnColum, boolean isSubEntity, Nullable nullable) {
|
||||||
|
|
||||||
public EntityAlias(final String aliasName) {
|
public EntityAlias(final String aliasName) {
|
||||||
this(aliasName, null, null, null, false);
|
this(aliasName, null, null, null, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityAlias(final String aliasName, final Class<? extends RbacObject> entityClass) {
|
public EntityAlias(final String aliasName, final Class<? extends RbacObject> entityClass) {
|
||||||
this(aliasName, entityClass, null, null, false);
|
this(aliasName, entityClass, null, null, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isGlobal() {
|
boolean isGlobal() {
|
||||||
@ -646,20 +660,15 @@ public class RbacView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public record Permission(String permission) {
|
public enum Permission {
|
||||||
|
INSERT,
|
||||||
public static final Permission INSERT = new Permission("INSERT");
|
DELETE,
|
||||||
public static final Permission DELETE = new Permission("DELETE");
|
UPDATE,
|
||||||
public static final Permission UPDATE = new Permission("UPDATE");
|
SELECT;
|
||||||
public static final Permission SELECT = new Permission("SELECT");
|
|
||||||
|
|
||||||
public static Permission custom(final String permission) {
|
|
||||||
return new Permission(permission);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return ":" + permission;
|
return ":" + name();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,8 +37,11 @@ public class RbacViewPostgresGenerator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return plPgSql.toString();
|
return plPgSql.toString()
|
||||||
}
|
.replace("\n\n\n", "\n\n")
|
||||||
|
.replace("-- ====", "\n-- ====")
|
||||||
|
.replace("\n\n--//", "\n--//");
|
||||||
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void generateToChangeLog(final Path outputPath) {
|
public void generateToChangeLog(final Path outputPath) {
|
||||||
|
@ -82,6 +82,7 @@ class RolesGrantsAndPermissionsGenerator {
|
|||||||
plPgSql.writeLn("begin");
|
plPgSql.writeLn("begin");
|
||||||
plPgSql.indented(() -> {
|
plPgSql.indented(() -> {
|
||||||
plPgSql.writeLn("call enterTriggerForObjectUuid(NEW.uuid);");
|
plPgSql.writeLn("call enterTriggerForObjectUuid(NEW.uuid);");
|
||||||
|
plPgSql.writeLn();
|
||||||
generateCreateRolesAndGrantsAfterInsert(plPgSql);
|
generateCreateRolesAndGrantsAfterInsert(plPgSql);
|
||||||
plPgSql.ensureSingleEmptyLine();
|
plPgSql.ensureSingleEmptyLine();
|
||||||
plPgSql.writeLn("call leaveTriggerForObjectUuid(NEW.uuid);");
|
plPgSql.writeLn("call leaveTriggerForObjectUuid(NEW.uuid);");
|
||||||
@ -109,7 +110,7 @@ class RolesGrantsAndPermissionsGenerator {
|
|||||||
|
|
||||||
plPgSql.chopEmptyLines();
|
plPgSql.chopEmptyLines();
|
||||||
plPgSql.indented(() -> {
|
plPgSql.indented(() -> {
|
||||||
updatableEntityAliases()
|
referencedEntityAliases()
|
||||||
.forEach((ea) -> {
|
.forEach((ea) -> {
|
||||||
plPgSql.writeLn(entityRefVar(OLD, ea) + " " + ea.getRawTableName() + ";");
|
plPgSql.writeLn(entityRefVar(OLD, ea) + " " + ea.getRawTableName() + ";");
|
||||||
plPgSql.writeLn(entityRefVar(NEW, ea) + " " + ea.getRawTableName() + ";");
|
plPgSql.writeLn(entityRefVar(NEW, ea) + " " + ea.getRawTableName() + ";");
|
||||||
@ -120,6 +121,7 @@ class RolesGrantsAndPermissionsGenerator {
|
|||||||
plPgSql.writeLn("begin");
|
plPgSql.writeLn("begin");
|
||||||
plPgSql.indented(() -> {
|
plPgSql.indented(() -> {
|
||||||
plPgSql.writeLn("call enterTriggerForObjectUuid(NEW.uuid);");
|
plPgSql.writeLn("call enterTriggerForObjectUuid(NEW.uuid);");
|
||||||
|
plPgSql.writeLn();
|
||||||
generateUpdateRolesAndGrantsAfterUpdate(plPgSql);
|
generateUpdateRolesAndGrantsAfterUpdate(plPgSql);
|
||||||
plPgSql.ensureSingleEmptyLine();
|
plPgSql.ensureSingleEmptyLine();
|
||||||
plPgSql.writeLn("call leaveTriggerForObjectUuid(NEW.uuid);");
|
plPgSql.writeLn("call leaveTriggerForObjectUuid(NEW.uuid);");
|
||||||
@ -134,9 +136,10 @@ class RolesGrantsAndPermissionsGenerator {
|
|||||||
|
|
||||||
private void generateCreateRolesAndGrantsAfterInsert(final StringWriter plPgSql) {
|
private void generateCreateRolesAndGrantsAfterInsert(final StringWriter plPgSql) {
|
||||||
referencedEntityAliases()
|
referencedEntityAliases()
|
||||||
.forEach((ea) -> plPgSql.writeLn(
|
.forEach((ea) -> {
|
||||||
ea.fetchSql().sql + " into " + entityRefVar(NEW, ea) + ";",
|
generateFetchedVars(plPgSql, ea, NEW);
|
||||||
with("ref", NEW.name())));
|
plPgSql.writeLn();
|
||||||
|
});
|
||||||
|
|
||||||
createRolesWithGrantsSql(plPgSql, OWNER);
|
createRolesWithGrantsSql(plPgSql, OWNER);
|
||||||
createRolesWithGrantsSql(plPgSql, ADMIN);
|
createRolesWithGrantsSql(plPgSql, ADMIN);
|
||||||
@ -165,14 +168,11 @@ class RolesGrantsAndPermissionsGenerator {
|
|||||||
private void generateUpdateRolesAndGrantsAfterUpdate(final StringWriter plPgSql) {
|
private void generateUpdateRolesAndGrantsAfterUpdate(final StringWriter plPgSql) {
|
||||||
plPgSql.ensureSingleEmptyLine();
|
plPgSql.ensureSingleEmptyLine();
|
||||||
|
|
||||||
updatableEntityAliases()
|
referencedEntityAliases()
|
||||||
.forEach((ea) -> {
|
.forEach((ea) -> {
|
||||||
plPgSql.writeLn(
|
generateFetchedVars(plPgSql, ea, OLD);
|
||||||
ea.fetchSql().sql + " into " + entityRefVar(OLD, ea) + ";",
|
generateFetchedVars(plPgSql, ea, NEW);
|
||||||
with("ref", OLD.name()));
|
plPgSql.writeLn();
|
||||||
plPgSql.writeLn(
|
|
||||||
ea.fetchSql().sql + " into " + entityRefVar(NEW, ea) + ";",
|
|
||||||
with("ref", NEW.name()));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
updatableEntityAliases()
|
updatableEntityAliases()
|
||||||
@ -190,6 +190,23 @@ class RolesGrantsAndPermissionsGenerator {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void generateFetchedVars(
|
||||||
|
final StringWriter plPgSql,
|
||||||
|
final RbacView.EntityAlias ea,
|
||||||
|
final PostgresTriggerReference old) {
|
||||||
|
plPgSql.writeLn(
|
||||||
|
ea.fetchSql().sql + " INTO " + entityRefVar(old, ea) + ";",
|
||||||
|
with("ref", old.name()));
|
||||||
|
if (ea.nullable() == RbacView.Nullable.NOT_NULL) {
|
||||||
|
plPgSql.writeLn(
|
||||||
|
"assert ${entityRefVar}.uuid is not null, format('${entityRefVar} must not be null for ${REF}.${dependsOnColumn} = %s', ${REF}.${dependsOnColumn});",
|
||||||
|
with("entityRefVar", entityRefVar(old, ea)),
|
||||||
|
with("dependsOnColumn", ea.dependsOnColumName()),
|
||||||
|
with("ref", old.name()));
|
||||||
|
plPgSql.writeLn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isUpdatable(final RbacView.Column c) {
|
private boolean isUpdatable(final RbacView.Column c) {
|
||||||
return rbacDef.getUpdatableColumns().contains(c);
|
return rbacDef.getUpdatableColumns().contains(c);
|
||||||
}
|
}
|
||||||
@ -256,7 +273,7 @@ class RolesGrantsAndPermissionsGenerator {
|
|||||||
.replace("${entityRef}", rbacDef.isRootEntityAlias(permDef.entityAlias)
|
.replace("${entityRef}", rbacDef.isRootEntityAlias(permDef.entityAlias)
|
||||||
? ref.name()
|
? ref.name()
|
||||||
: refVarName(ref, permDef.entityAlias))
|
: refVarName(ref, permDef.entityAlias))
|
||||||
.replace("${perm}", permDef.permission.permission());
|
.replace("${perm}", permDef.permission.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String refVarName(final PostgresTriggerReference ref, final RbacView.EntityAlias entityAlias) {
|
private String refVarName(final PostgresTriggerReference ref, final RbacView.EntityAlias entityAlias) {
|
||||||
@ -333,7 +350,7 @@ class RolesGrantsAndPermissionsGenerator {
|
|||||||
final var arrayElements = permissionGrantsForRole.stream()
|
final var arrayElements = permissionGrantsForRole.stream()
|
||||||
.map(RbacView.RbacGrantDefinition::getPermDef)
|
.map(RbacView.RbacGrantDefinition::getPermDef)
|
||||||
.map(RbacPermissionDefinition::getPermission)
|
.map(RbacPermissionDefinition::getPermission)
|
||||||
.map(RbacView.Permission::permission)
|
.map(RbacView.Permission::name)
|
||||||
.map(p -> "'" + p + "'")
|
.map(p -> "'" + p + "'")
|
||||||
.sorted()
|
.sorted()
|
||||||
.toList();
|
.toList();
|
||||||
|
@ -103,8 +103,8 @@ public class StringWriter {
|
|||||||
text = matcher.replaceAll(varDef.value());
|
text = matcher.replaceAll(varDef.value());
|
||||||
});
|
});
|
||||||
return text;
|
return text;
|
||||||
} catch (Exception exc) {
|
} catch (final RuntimeException exc) {
|
||||||
throw exc;
|
throw exc; // FIXME: just for debugging, remove try/catch before merging to master
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -609,7 +609,7 @@ select exists(
|
|||||||
);
|
);
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
create or replace procedure grantPermissionToRole(roleUuid uuid, permissionUuid uuid)
|
create or replace procedure grantPermissionToRole(permissionUuid uuid, roleUuid uuid)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
perform assertReferenceType('roleId (ascendant)', roleUuid, 'RbacRole');
|
perform assertReferenceType('roleId (ascendant)', roleUuid, 'RbacRole');
|
||||||
@ -622,10 +622,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
create or replace procedure grantPermissionToRole(roleDesc RbacRoleDescriptor, permissionUuid uuid)
|
create or replace procedure grantPermissionToRole(permissionUuid uuid, roleDesc RbacRoleDescriptor)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(findRoleId(roleDesc), permissionUuid);
|
call grantPermissionToRole(permissionUuid, findRoleId(roleDesc));
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
@ -671,6 +671,11 @@ declare
|
|||||||
superRoleId uuid;
|
superRoleId uuid;
|
||||||
subRoleId uuid;
|
subRoleId uuid;
|
||||||
begin
|
begin
|
||||||
|
-- FIXME: maybe separate method grantRoleToRoleIfNotNull(...)?
|
||||||
|
if superRole.objectUuid is null or subRole.objectuuid is null then
|
||||||
|
return;
|
||||||
|
end if;
|
||||||
|
|
||||||
superRoleId := findRoleId(superRole);
|
superRoleId := findRoleId(superRole);
|
||||||
subRoleId := findRoleId(subRole);
|
subRoleId := findRoleId(subRole);
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ do language plpgsql $$
|
|||||||
LOOP
|
LOOP
|
||||||
roleUuid := findRoleId(testCustomerAdmin(row));
|
roleUuid := findRoleId(testCustomerAdmin(row));
|
||||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'test_package');
|
permissionUuid := createPermission(row.uuid, 'INSERT', 'test_package');
|
||||||
call grantPermissionToRole(roleUuid, permissionUuid);
|
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END;
|
END;
|
||||||
$$;
|
$$;
|
||||||
@ -174,8 +174,8 @@ create or replace function test_package_test_customer_insert_tf()
|
|||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
call grantPermissionToRole(
|
||||||
testCustomerAdmin(NEW),
|
createPermission(NEW.uuid, 'INSERT', 'test_package'),
|
||||||
createPermission(NEW.uuid, 'INSERT', 'test_package'));
|
testCustomerAdmin(NEW));
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ do language plpgsql $$
|
|||||||
LOOP
|
LOOP
|
||||||
roleUuid := findRoleId(testPackageAdmin(row));
|
roleUuid := findRoleId(testPackageAdmin(row));
|
||||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'test_domain');
|
permissionUuid := createPermission(row.uuid, 'INSERT', 'test_domain');
|
||||||
call grantPermissionToRole(roleUuid, permissionUuid);
|
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END;
|
END;
|
||||||
$$;
|
$$;
|
||||||
@ -173,8 +173,8 @@ create or replace function test_domain_test_package_insert_tf()
|
|||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
call grantPermissionToRole(
|
||||||
testPackageAdmin(NEW),
|
createPermission(NEW.uuid, 'INSERT', 'test_domain'),
|
||||||
createPermission(NEW.uuid, 'INSERT', 'test_domain'));
|
testPackageAdmin(NEW));
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ do language plpgsql $$
|
|||||||
LOOP
|
LOOP
|
||||||
roleUuid := findRoleId(globalGuest());
|
roleUuid := findRoleId(globalGuest());
|
||||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_person');
|
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_person');
|
||||||
call grantPermissionToRole(roleUuid, permissionUuid);
|
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END;
|
END;
|
||||||
$$;
|
$$;
|
||||||
@ -108,8 +108,8 @@ create or replace function hs_office_person_global_insert_tf()
|
|||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
call grantPermissionToRole(
|
||||||
globalGuest(),
|
createPermission(NEW.uuid, 'INSERT', 'hs_office_person'),
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_person'));
|
globalGuest());
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ do language plpgsql $$
|
|||||||
call createHsOfficeRelationshipTestData('Third OHG', 'ACCOUNTING', 'Third OHG', 'third contact');
|
call createHsOfficeRelationshipTestData('Third OHG', 'ACCOUNTING', 'Third OHG', 'third contact');
|
||||||
|
|
||||||
call createHsOfficeRelationshipTestData('Smith', 'PARTNER', 'Hostsharing eG', 'sixth contact');
|
call createHsOfficeRelationshipTestData('Smith', 'PARTNER', 'Hostsharing eG', 'sixth contact');
|
||||||
call createHsOfficeRelationshipTestData('Smith', 'ACCOUNTING', 'Smith', 'third contact', 'members-announce');
|
call createHsOfficeRelationshipTestData('Smith', 'ACCOUNTING', 'Smith', 'third contact');
|
||||||
call createHsOfficeRelationshipTestData('Smith', 'SUBSCRIBER', 'Third OHG', 'third contact', 'members-announce');
|
call createHsOfficeRelationshipTestData('Smith', 'SUBSCRIBER', 'Third OHG', 'third contact', 'members-announce');
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
@ -94,7 +94,7 @@ do language plpgsql $$
|
|||||||
LOOP
|
LOOP
|
||||||
roleUuid := findRoleId(globalGuest());
|
roleUuid := findRoleId(globalGuest());
|
||||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_bankaccount');
|
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_bankaccount');
|
||||||
call grantPermissionToRole(roleUuid, permissionUuid);
|
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END;
|
END;
|
||||||
$$;
|
$$;
|
||||||
@ -108,8 +108,8 @@ create or replace function hs_office_bankaccount_global_insert_tf()
|
|||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
call grantPermissionToRole(
|
call grantPermissionToRole(
|
||||||
globalGuest(),
|
createPermission(NEW.uuid, 'INSERT', 'hs_office_bankaccount'),
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_bankaccount'));
|
globalGuest());
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
|
@ -1,74 +1,275 @@
|
|||||||
### hs_office_debitor RBAC Roles
|
### rbac debitor
|
||||||
|
|
||||||
|
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-12T16:22:27.339854728.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||||
flowchart TB
|
flowchart TB
|
||||||
|
|
||||||
subgraph partnerRelationship[hsOfficeRelationship:PARTNER]
|
subgraph debitorRel.anchorPerson["`**debitorRel.anchorPerson**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style partnerRelationship fill:#eee
|
style debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
role:partnerRelationship.owner[relationship.owner]
|
|
||||||
--> role:partnerRelationship.admin[relationship.admin]
|
|
||||||
--> role:partnerRelationship.agent[relationship.agent]
|
|
||||||
--> role:partnerRelationship.tenant[relationship.tenant]
|
|
||||||
|
|
||||||
partnerPersonAdmin>e.g. partnerPerson.admin] --> role:partnerRelationship.agent
|
subgraph debitorRel.anchorPerson:roles[ ]
|
||||||
otherPersonAdmin>e.g. operationalPerson.admin] --> role:partnerRelationship.tenant
|
style debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||||
role:partnerRelationship.tenant --> partnerPersonReferrer>e.g. partnerPerson.referrer]
|
|
||||||
|
role:debitorRel.anchorPerson:owner[[debitorRel.anchorPerson:owner]]
|
||||||
|
role:debitorRel.anchorPerson:admin[[debitorRel.anchorPerson:admin]]
|
||||||
|
role:debitorRel.anchorPerson:referrer[[debitorRel.anchorPerson:referrer]]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph internal[ ]
|
subgraph debitorRel.holderPerson["`**debitorRel.holderPerson**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style internal fill:#fff
|
style debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
subgraph refundBankAccount
|
subgraph debitorRel.holderPerson:roles[ ]
|
||||||
direction TB
|
style debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
||||||
style refundBankAccount fill:#eee
|
|
||||||
|
role:debitorRel.holderPerson:owner[[debitorRel.holderPerson:owner]]
|
||||||
role:refundBankAccount.owner[bankAccount.owner]
|
role:debitorRel.holderPerson:admin[[debitorRel.holderPerson:admin]]
|
||||||
--> role:refundBankAccount.admin[bankAccount.admin]
|
role:debitorRel.holderPerson:referrer[[debitorRel.holderPerson:referrer]]
|
||||||
--> role:refundBankAccount.referrer[bankAccount.referrer]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
subgraph debitorRelationship[hsOfficeRelationship:DEBITOR]
|
|
||||||
direction TB
|
|
||||||
style debitorRelationship fill:#eee
|
|
||||||
|
|
||||||
role:debitorRelationship.owner[relationship.owner]
|
|
||||||
--> role:debitorRelationship.admin[relationship.admin]
|
|
||||||
--> role:debitorRelationship.agent[relationship.agent]
|
|
||||||
--> role:debitorRelationship.tenant[relationship.tenant]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph debitor
|
|
||||||
direction TB
|
|
||||||
|
|
||||||
role:debitorRelationship.owner[debitorRelationship.owner]
|
|
||||||
%% permissions
|
|
||||||
==> perm:debitor.*{{debitor.*}}
|
|
||||||
|
|
||||||
role:debitorRelationship.admin[debitorRelationship.admin]
|
|
||||||
%% permissions
|
|
||||||
==> perm:debitor.edit{{debitor.edit}}
|
|
||||||
%% incoming
|
|
||||||
role:partnerRelationship.admin ==> role:debitorRelationship.admin
|
|
||||||
%% outgoing
|
|
||||||
role:debitorRelationship.admin ==> role:partnerRelationship.agent
|
|
||||||
|
|
||||||
role:debitorRelationship.agent[debitorRelationship.agent]
|
|
||||||
%% incoming
|
|
||||||
role:partnerRelationship.agent ==> role:debitorRelationship.agent
|
|
||||||
role:refundBankAccount.admin ==> role:debitorRelationship.agent
|
|
||||||
%% outgoing
|
|
||||||
role:debitorRelationship.agent ==> role:partnerRelationship.tenant
|
|
||||||
role:debitorRelationship.agent ==> role:refundBankAccount.referrer
|
|
||||||
|
|
||||||
role:debitorRelationship.tenant[debitorRelationship.tenant]
|
|
||||||
==> perm:debitor.view{{debitor.view}}
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
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**`"]
|
||||||
|
direction TB
|
||||||
|
style debitor fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph debitor:permissions[ ]
|
||||||
|
style debitor:permissions fill:#dd4901,stroke:white
|
||||||
|
|
||||||
|
perm:debitor:INSERT{{debitor:INSERT}}
|
||||||
|
perm:debitor:DELETE{{debitor:DELETE}}
|
||||||
|
perm:debitor:UPDATE{{debitor:UPDATE}}
|
||||||
|
perm:debitor:SELECT{{debitor:SELECT}}
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph debitorRel["`**debitorRel**`"]
|
||||||
|
direction TB
|
||||||
|
style debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
subgraph debitorRel.anchorPerson["`**debitorRel.anchorPerson**`"]
|
||||||
|
direction TB
|
||||||
|
style debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph debitorRel.anchorPerson:roles[ ]
|
||||||
|
style debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:debitorRel.anchorPerson:owner[[debitorRel.anchorPerson:owner]]
|
||||||
|
role:debitorRel.anchorPerson:admin[[debitorRel.anchorPerson:admin]]
|
||||||
|
role:debitorRel.anchorPerson:referrer[[debitorRel.anchorPerson:referrer]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph debitorRel.holderPerson["`**debitorRel.holderPerson**`"]
|
||||||
|
direction TB
|
||||||
|
style debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph debitorRel.holderPerson:roles[ ]
|
||||||
|
style debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:debitorRel.holderPerson:owner[[debitorRel.holderPerson:owner]]
|
||||||
|
role:debitorRel.holderPerson:admin[[debitorRel.holderPerson:admin]]
|
||||||
|
role:debitorRel.holderPerson:referrer[[debitorRel.holderPerson:referrer]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph debitorRel.contact["`**debitorRel.contact**`"]
|
||||||
|
direction TB
|
||||||
|
style debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph debitorRel.contact:roles[ ]
|
||||||
|
style debitorRel.contact:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:debitorRel.contact:owner[[debitorRel.contact:owner]]
|
||||||
|
role:debitorRel.contact:admin[[debitorRel.contact:admin]]
|
||||||
|
role:debitorRel.contact:referrer[[debitorRel.contact:referrer]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph debitorRel:roles[ ]
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph partnerRel["`**partnerRel**`"]
|
||||||
|
direction TB
|
||||||
|
style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"]
|
||||||
|
direction TB
|
||||||
|
style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph partnerRel.holderPerson:roles[ ]
|
||||||
|
style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:partnerRel.holderPerson:owner[[partnerRel.holderPerson:owner]]
|
||||||
|
role:partnerRel.holderPerson:admin[[partnerRel.holderPerson:admin]]
|
||||||
|
role:partnerRel.holderPerson:referrer[[partnerRel.holderPerson:referrer]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph partnerRel.contact["`**partnerRel.contact**`"]
|
||||||
|
direction TB
|
||||||
|
style partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph partnerRel.contact:roles[ ]
|
||||||
|
style partnerRel.contact:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:partnerRel.contact:owner[[partnerRel.contact:owner]]
|
||||||
|
role:partnerRel.contact:admin[[partnerRel.contact:admin]]
|
||||||
|
role:partnerRel.contact:referrer[[partnerRel.contact:referrer]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
|
||||||
|
direction TB
|
||||||
|
style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph partnerRel.anchorPerson:roles[ ]
|
||||||
|
style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:partnerRel.anchorPerson:owner[[partnerRel.anchorPerson:owner]]
|
||||||
|
role:partnerRel.anchorPerson:admin[[partnerRel.anchorPerson:admin]]
|
||||||
|
role:partnerRel.anchorPerson:referrer[[partnerRel.anchorPerson:referrer]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph partnerRel:roles[ ]
|
||||||
|
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 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 partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
|
||||||
|
direction TB
|
||||||
|
style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph partnerRel.anchorPerson:roles[ ]
|
||||||
|
style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:partnerRel.anchorPerson:owner[[partnerRel.anchorPerson:owner]]
|
||||||
|
role:partnerRel.anchorPerson:admin[[partnerRel.anchorPerson:admin]]
|
||||||
|
role:partnerRel.anchorPerson:referrer[[partnerRel.anchorPerson:referrer]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph refundBankAccount["`**refundBankAccount**`"]
|
||||||
|
direction TB
|
||||||
|
style refundBankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
|
subgraph refundBankAccount:roles[ ]
|
||||||
|
style refundBankAccount:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
|
role:refundBankAccount:owner[[refundBankAccount:owner]]
|
||||||
|
role:refundBankAccount:admin[[refundBankAccount:admin]]
|
||||||
|
role:refundBankAccount:referrer[[refundBankAccount:referrer]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
%% granting roles to roles
|
||||||
|
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:global:admin -.-> role:debitorRel:owner
|
||||||
|
role:debitorRel:owner -.-> role:debitorRel:admin
|
||||||
|
role:debitorRel.anchorPerson:admin -.-> role:debitorRel:admin
|
||||||
|
role:debitorRel:admin -.-> role:debitorRel:agent
|
||||||
|
role:debitorRel.holderPerson:admin -.-> role:debitorRel:agent
|
||||||
|
role:debitorRel:agent -.-> role:debitorRel:tenant
|
||||||
|
role:debitorRel.holderPerson:admin -.-> 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:global:admin -.-> role:refundBankAccount:owner
|
||||||
|
role:refundBankAccount:owner -.-> role:refundBankAccount:admin
|
||||||
|
role:refundBankAccount:admin -.-> role:refundBankAccount:referrer
|
||||||
|
role:refundBankAccount:admin ==> role:debitorRel:agent
|
||||||
|
role:debitorRel:agent ==> role:refundBankAccount:referrer
|
||||||
|
role:global:admin -.-> role:partnerRel.anchorPerson:owner
|
||||||
|
role:partnerRel.anchorPerson:owner -.-> role:partnerRel.anchorPerson:admin
|
||||||
|
role:partnerRel.anchorPerson:admin -.-> role:partnerRel.anchorPerson:referrer
|
||||||
|
role:global:admin -.-> role:partnerRel.holderPerson:owner
|
||||||
|
role:partnerRel.holderPerson:owner -.-> role:partnerRel.holderPerson:admin
|
||||||
|
role:partnerRel.holderPerson:admin -.-> role:partnerRel.holderPerson:referrer
|
||||||
|
role:global:admin -.-> role:partnerRel.contact:owner
|
||||||
|
role:partnerRel.contact:owner -.-> role:partnerRel.contact:admin
|
||||||
|
role:partnerRel.contact:admin -.-> role:partnerRel.contact:referrer
|
||||||
|
role:global:admin -.-> role:partnerRel:owner
|
||||||
|
role:partnerRel:owner -.-> role:partnerRel:admin
|
||||||
|
role:partnerRel.anchorPerson:admin -.-> role:partnerRel:admin
|
||||||
|
role:partnerRel:admin -.-> role:partnerRel:agent
|
||||||
|
role:partnerRel.holderPerson:admin -.-> role:partnerRel:agent
|
||||||
|
role:partnerRel:agent -.-> role:partnerRel:tenant
|
||||||
|
role:partnerRel.holderPerson:admin -.-> role:partnerRel:tenant
|
||||||
|
role:partnerRel.contact:admin -.-> role:partnerRel:tenant
|
||||||
|
role:partnerRel:tenant -.-> role:partnerRel.anchorPerson:referrer
|
||||||
|
role:partnerRel:tenant -.-> role:partnerRel.holderPerson:referrer
|
||||||
|
role:partnerRel:tenant -.-> role:partnerRel.contact:referrer
|
||||||
|
role:partnerRel:admin ==> role:debitorRel:admin
|
||||||
|
role:partnerRel:agent ==> role:debitorRel:agent
|
||||||
|
role:debitorRel:agent ==> role:partnerRel:tenant
|
||||||
|
|
||||||
|
%% granting permissions to roles
|
||||||
|
role:global:admin ==> perm:debitor:INSERT
|
||||||
|
role:debitorRel:owner ==> perm:debitor:DELETE
|
||||||
|
role:debitorRel:admin ==> perm:debitor:UPDATE
|
||||||
|
role:debitorRel:tenant ==> perm:debitor:SELECT
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
--liquibase formatted sql
|
--liquibase formatted sql
|
||||||
|
-- This code generated was by RbacViewPostgresGenerator at 2024-03-12T16:22:27.348469700.
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-debitor-rbac-OBJECT:1 endDelimiter:--//
|
--changeset hs-office-debitor-rbac-OBJECT:1 endDelimiter:--//
|
||||||
@ -15,249 +17,273 @@ call generateRbacRoleDescriptors('hsOfficeDebitor', 'hs_office_debitor');
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-debitor-rbac-ROLES-CREATION:1 endDelimiter:--//
|
--changeset hs-office-debitor-rbac-insert-trigger:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates and updates the roles and their assignments for debitor entities.
|
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
create or replace function hsOfficeDebitorRbacRolesTrigger()
|
create or replace procedure buildRbacSystemForHsOfficeDebitor(
|
||||||
returns trigger
|
NEW hs_office_debitor
|
||||||
language plpgsql
|
)
|
||||||
strict as $$
|
language plpgsql as $$
|
||||||
|
|
||||||
declare
|
declare
|
||||||
debitorUuid uuid;
|
newPartnerRel hs_office_relationship;
|
||||||
|
newDebitorRel hs_office_relationship;
|
||||||
oldDebitorRel hs_office_relationship;
|
newRefundBankAccount hs_office_bankaccount;
|
||||||
newDebitorRel hs_office_relationship;
|
|
||||||
|
|
||||||
newPartnerRel hs_office_relationship;
|
|
||||||
|
|
||||||
newBankAccount hs_office_bankaccount;
|
|
||||||
oldBankAccount hs_office_bankaccount;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
call enterTriggerForObjectUuid(NEW.uuid);
|
call enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
debitorUuid := NEW.uuid;
|
SELECT partnerRel.*
|
||||||
|
FROM hs_office_relationship AS partnerRel
|
||||||
|
JOIN hs_office_relationship AS debitorRel
|
||||||
|
ON debitorRel.relType = 'ACCOUNTING' AND debitorRel.relAnchorUuid = partnerRel.relHolderUuid
|
||||||
|
WHERE partnerRel.relType = 'PARTNER'
|
||||||
|
AND NEW.debitorRelUuid = debitorRel.uuid
|
||||||
|
INTO newPartnerRel;
|
||||||
|
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.debitorRelUuid = %s', NEW.debitorRelUuid);
|
||||||
|
|
||||||
select * into newDebitorRel
|
SELECT *
|
||||||
from hs_office_relationship as r where r.relType = 'ACCOUNTING' and r.relHolderUuid = NEW.debitorRelUuid;
|
FROM hs_office_relationship AS r
|
||||||
|
WHERE r.relType = 'ACCOUNTING' AND r.uuid = NEW.debitorRelUuid
|
||||||
|
INTO newDebitorRel;
|
||||||
|
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorRelUuid = %s', NEW.debitorRelUuid);
|
||||||
|
|
||||||
select * into newPartnerRel
|
SELECT *
|
||||||
from hs_office_relationship as partnerRel
|
FROM hs_office_relationship AS r
|
||||||
where newDebitorRel.relAnchorUuid = partnerRel.relHolderUuid;
|
WHERE r.relType = 'ACCOUNTING' AND r.relHolderUuid = NEW.debitorRelUuid
|
||||||
|
INTO newRefundBankAccount;
|
||||||
|
|
||||||
select * into newBankAccount
|
call grantRoleToRole(hsOfficeBankAccountReferrer(newRefundBankAccount), hsOfficeRelationshipAgent(newDebitorRel));
|
||||||
from hs_office_bankaccount as b where b.uuid = NEW.refundBankAccountUuid;
|
call grantRoleToRole(hsOfficeRelationshipAdmin(newDebitorRel), hsOfficeRelationshipAdmin(newPartnerRel));
|
||||||
|
call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeBankAccountAdmin(newRefundBankAccount));
|
||||||
|
call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeRelationshipAgent(newPartnerRel));
|
||||||
|
call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRel), hsOfficeRelationshipAgent(newDebitorRel));
|
||||||
|
|
||||||
if TG_OP = 'INSERT' then
|
call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationshipOwner(newDebitorRel));
|
||||||
|
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationshipTenant(newDebitorRel));
|
||||||
|
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationshipAdmin(newDebitorRel));
|
||||||
|
|
||||||
-- Permissions and Grants for Debitor
|
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||||
|
end; $$;
|
||||||
|
|
||||||
call grantPermissionsToRole(
|
/*
|
||||||
getRoleId(hsOfficeRelationshipOwner(newDebitorRel)),
|
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_debitor row.
|
||||||
createPermissions(partnerUuid, array ['DELETE'])
|
*/
|
||||||
);
|
|
||||||
|
|
||||||
call grantPermissionsToRole(
|
create or replace function insertTriggerForHsOfficeDebitor_tf()
|
||||||
getRoleId(hsOfficeRelationshipAdmin(newDebitorRel), 'fail'),
|
returns trigger
|
||||||
createPermissions(partnerUuid, array ['UPDATE'])
|
language plpgsql
|
||||||
);
|
strict as $$
|
||||||
|
begin
|
||||||
|
call buildRbacSystemForHsOfficeDebitor(NEW);
|
||||||
|
return NEW;
|
||||||
|
end; $$;
|
||||||
|
|
||||||
call grantPermissionsToRole(
|
create trigger insertTriggerForHsOfficeDebitor_tg
|
||||||
getRoleId(hsOfficeRelationshipTenant(newDebitorRel), 'fail'),
|
after insert on hs_office_debitor
|
||||||
createPermissions(partnerUuid, array ['SELECT'])
|
for each row
|
||||||
);
|
execute procedure insertTriggerForHsOfficeDebitor_tf();
|
||||||
|
--//
|
||||||
|
|
||||||
-- Grants to and from related Partner Relationship
|
|
||||||
|
|
||||||
-- call grantRoleToRole(hsOfficeRelationshipAdmin(newDebitorRel), hsOfficeRelationshipAdmin(newPartnerRel), true);
|
-- ============================================================================
|
||||||
-- call grantRoleToRole(hsOfficeRelationshipAgent(newPartnerRel), hsOfficeRelationshipAdmin(newDebitorRel), true);
|
--changeset hs-office-debitor-rbac-update-trigger:1 endDelimiter:--//
|
||||||
--
|
-- ----------------------------------------------------------------------------
|
||||||
-- call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeRelationshipAgent(newPartnerRel), true);
|
|
||||||
-- call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRel), hsOfficeRelationshipAgent(newDebitorRel), true);
|
|
||||||
|
|
||||||
-- Grants to and from refundBankAccount
|
/*
|
||||||
|
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
|
||||||
|
*/
|
||||||
|
|
||||||
-- if newBankAccount is not null then
|
create or replace procedure updateRbacRulesForHsOfficeDebitor(
|
||||||
-- call grantRoleToRole(hsOfficeBankAccountReferrer(newBankAccount), hsOfficeRelationshipAgent(newDebitorRel), true);
|
OLD hs_office_debitor,
|
||||||
-- call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeBankAccountAdmin(newBankAccount), true);
|
NEW hs_office_debitor
|
||||||
-- end if;
|
)
|
||||||
|
language plpgsql as $$
|
||||||
|
|
||||||
elsif TG_OP = 'UPDATE' then
|
declare
|
||||||
|
oldPartnerRel hs_office_relationship;
|
||||||
|
newPartnerRel hs_office_relationship;
|
||||||
|
oldDebitorRel hs_office_relationship;
|
||||||
|
newDebitorRel hs_office_relationship;
|
||||||
|
oldRefundBankAccount hs_office_bankaccount;
|
||||||
|
newRefundBankAccount hs_office_bankaccount;
|
||||||
|
|
||||||
if OLD.debitorRelUuid is distinct from NEW.debitorRelUuid then
|
begin
|
||||||
|
call enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
select * into oldDebitorRel
|
SELECT partnerRel.*
|
||||||
from hs_office_relationship as r where r.relType = 'ACCOUNTING' and r.relHolderUuid = NEW.debitorRelUuid;
|
FROM hs_office_relationship AS partnerRel
|
||||||
|
JOIN hs_office_relationship AS debitorRel
|
||||||
|
ON debitorRel.relType = 'ACCOUNTING' AND debitorRel.relAnchorUuid = partnerRel.relHolderUuid
|
||||||
|
WHERE partnerRel.relType = 'PARTNER'
|
||||||
|
AND OLD.debitorRelUuid = debitorRel.uuid
|
||||||
|
INTO oldPartnerRel;
|
||||||
|
assert oldPartnerRel.uuid is not null, format('oldPartnerRel must not be null for OLD.debitorRelUuid = %s', OLD.debitorRelUuid);
|
||||||
|
|
||||||
-- call grantPermissionsToRole(
|
SELECT partnerRel.*
|
||||||
-- getRoleId(hsOfficeRelationshipOwner(newDebitorRel)),
|
FROM hs_office_relationship AS partnerRel
|
||||||
-- createPermissions(partnerUuid, array ['DELETE'])
|
JOIN hs_office_relationship AS debitorRel
|
||||||
-- );
|
ON debitorRel.relType = 'ACCOUNTING' AND debitorRel.relAnchorUuid = partnerRel.relHolderUuid
|
||||||
--
|
WHERE partnerRel.relType = 'PARTNER'
|
||||||
-- call grantPermissionsToRole(
|
AND NEW.debitorRelUuid = debitorRel.uuid
|
||||||
-- getRoleId(hsOfficeRelationshipAdmin(newDebitorRel)),
|
INTO newPartnerRel;
|
||||||
-- createPermissions(partnerUuid, array ['UPDATE'])
|
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.debitorRelUuid = %s', NEW.debitorRelUuid);
|
||||||
-- );
|
|
||||||
--
|
|
||||||
-- call grantPermissionsToRole(
|
|
||||||
-- getRoleId(hsOfficeRelationshipTenant(newDebitorRel)),
|
|
||||||
-- createPermissions(partnerUuid, array ['SELECT'])
|
|
||||||
-- );
|
|
||||||
|
|
||||||
end if;
|
SELECT *
|
||||||
|
FROM hs_office_relationship AS r
|
||||||
|
WHERE r.relType = 'ACCOUNTING' AND r.uuid = OLD.debitorRelUuid
|
||||||
|
INTO oldDebitorRel;
|
||||||
|
assert oldDebitorRel.uuid is not null, format('oldDebitorRel must not be null for OLD.debitorRelUuid = %s', OLD.debitorRelUuid);
|
||||||
|
|
||||||
if OLD.refundBankAccountUuid is distinct from NEW.refundBankAccountUuid then
|
SELECT *
|
||||||
|
FROM hs_office_relationship AS r
|
||||||
|
WHERE r.relType = 'ACCOUNTING' AND r.uuid = NEW.debitorRelUuid
|
||||||
|
INTO newDebitorRel;
|
||||||
|
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorRelUuid = %s', NEW.debitorRelUuid);
|
||||||
|
|
||||||
select * into oldBankAccount
|
SELECT *
|
||||||
from hs_office_bankaccount as b where b.uuid = OLD.refundBankAccountUuid;
|
FROM hs_office_relationship AS r
|
||||||
|
WHERE r.relType = 'ACCOUNTING' AND r.relHolderUuid = OLD.debitorRelUuid
|
||||||
|
INTO oldRefundBankAccount;
|
||||||
|
SELECT *
|
||||||
|
FROM hs_office_relationship AS r
|
||||||
|
WHERE r.relType = 'ACCOUNTING' AND r.relHolderUuid = NEW.debitorRelUuid
|
||||||
|
INTO newRefundBankAccount;
|
||||||
|
|
||||||
if oldBankAccount is not null then
|
if NEW.refundBankAccountUuid <> OLD.refundBankAccountUuid then
|
||||||
call revokeRoleFromRole(hsOfficeBankAccountReferrer(oldBankAccount), hsOfficeRelationshipAgent(oldDebitorRel), true);
|
|
||||||
call revokeRoleFromRole(hsOfficeRelationshipAgent(oldDebitorRel), hsOfficeBankAccountAdmin(oldBankAccount), true);
|
call revokeRoleFromRole(hsOfficeRelationshipAgent(oldDebitorRel), hsOfficeBankAccountAdmin(oldRefundBankAccount));
|
||||||
end if;
|
call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeBankAccountAdmin(newRefundBankAccount));
|
||||||
|
|
||||||
|
call revokeRoleFromRole(hsOfficeBankAccountReferrer(oldRefundBankAccount), hsOfficeRelationshipAgent(oldDebitorRel));
|
||||||
|
call grantRoleToRole(hsOfficeBankAccountReferrer(newRefundBankAccount), hsOfficeRelationshipAgent(newDebitorRel));
|
||||||
|
|
||||||
if newBankAccount is not null then
|
|
||||||
call grantRoleToRole(hsOfficeBankAccountReferrer(newBankAccount), hsOfficeRelationshipAgent(newDebitorRel), true);
|
|
||||||
call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeBankAccountAdmin(newBankAccount), true);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
raise exception 'invalid usage of TRIGGER';
|
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||||
return NEW;
|
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
An AFTER INSERT TRIGGER which creates the role structure for a new debitor.
|
AFTER INSERT TRIGGER to re-wire the grant structure for a new hs_office_debitor row.
|
||||||
*/
|
|
||||||
create trigger createRbacRolesForHsOfficeDebitor_Trigger
|
|
||||||
after insert
|
|
||||||
on hs_office_debitor
|
|
||||||
for each row
|
|
||||||
execute procedure hsOfficeDebitorRbacRolesTrigger();
|
|
||||||
|
|
||||||
/*
|
|
||||||
An AFTER UPDATE TRIGGER which updates the role structure of a debitor.
|
|
||||||
*/
|
|
||||||
create trigger updateRbacRolesForHsOfficeDebitor_Trigger
|
|
||||||
after update
|
|
||||||
on hs_office_debitor
|
|
||||||
for each row
|
|
||||||
execute procedure hsOfficeDebitorRbacRolesTrigger();
|
|
||||||
--//
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Creates and updates the roles and their assignments for debitor entities if partner rel changes.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
create or replace function hsOfficeDebitorPartnerRelRbacRolesTrigger()
|
create or replace function updateTriggerForHsOfficeDebitor_tf()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
declare
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
call enterTriggerForObjectUuid(NEW.uuid);
|
call updateRbacRulesForHsOfficeDebitor(OLD, NEW);
|
||||||
|
|
||||||
-- TODO
|
|
||||||
|
|
||||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
|
create trigger updateTriggerForHsOfficeDebitor_tg
|
||||||
|
after update on hs_office_debitor
|
||||||
|
for each row
|
||||||
|
execute procedure updateTriggerForHsOfficeDebitor_tf();
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs-office-debitor-rbac-INSERT:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
An AFTER UPDATE TRIGGER which creates the role structure for debitors if partner relations change.
|
Creates INSERT INTO hs_office_debitor permissions for the related global rows.
|
||||||
*/
|
*/
|
||||||
create trigger updateRbacRolesForHsOfficeDebitor_Trigger
|
do language plpgsql $$
|
||||||
after update
|
declare
|
||||||
on hs_office_partner
|
row global;
|
||||||
for each row
|
permissionUuid uuid;
|
||||||
execute procedure hsOfficeDebitorPartnerRelRbacRolesTrigger();
|
roleUuid uuid;
|
||||||
--//
|
begin
|
||||||
|
call defineContext('create INSERT INTO hs_office_debitor permissions for the related global rows');
|
||||||
|
|
||||||
|
FOR row IN SELECT * FROM global
|
||||||
|
LOOP
|
||||||
|
roleUuid := findRoleId(globalAdmin());
|
||||||
|
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_debitor');
|
||||||
|
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||||
|
END LOOP;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds hs_office_debitor INSERT permission to specified role of new global rows.
|
||||||
|
*/
|
||||||
|
create or replace function hs_office_debitor_global_insert_tf()
|
||||||
|
returns trigger
|
||||||
|
language plpgsql
|
||||||
|
strict as $$
|
||||||
|
begin
|
||||||
|
call grantPermissionToRole(
|
||||||
|
globalAdmin(),
|
||||||
|
createPermission(NEW.uuid, 'INSERT', 'hs_office_debitor'));
|
||||||
|
return NEW;
|
||||||
|
end; $$;
|
||||||
|
|
||||||
|
create trigger hs_office_debitor_global_insert_tg
|
||||||
|
after insert on global
|
||||||
|
for each row
|
||||||
|
execute procedure hs_office_debitor_global_insert_tf();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks if the user or assumed roles are allowed to insert a row to hs_office_debitor.
|
||||||
|
*/
|
||||||
|
create or replace function hs_office_debitor_insert_permission_missing_tf()
|
||||||
|
returns trigger
|
||||||
|
language plpgsql as $$
|
||||||
|
begin
|
||||||
|
raise exception '[403] insert into hs_office_debitor not allowed for current subjects % (%)',
|
||||||
|
currentSubjects(), currentSubjectsUuids();
|
||||||
|
end; $$;
|
||||||
|
|
||||||
|
create trigger hs_office_debitor_insert_permission_check_tg
|
||||||
|
before insert on hs_office_debitor
|
||||||
|
for each row
|
||||||
|
when ( not isGlobalAdmin() )
|
||||||
|
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 generateRbacIdentityViewFromProjection('hs_office_debitor', $idName$
|
|
||||||
'#' || (select partner.partnerNumber
|
|
||||||
from hs_office_partner partner
|
|
||||||
join hs_office_relationship partnerRel on partnerRel.uuid = partner.partnerRoleUUid and partnerRel.relType = 'PARTNER'
|
|
||||||
join hs_office_relationship debitorRel on debitorRel.relAnchorUuid = partnerRel.relHolderUuid and partnerRel.relType = 'ACCOUNTING'
|
|
||||||
where debitorRel.uuid = target.debitorRelUuid)
|
|
||||||
|| to_char(debitorNumberSuffix, 'fm00')
|
|
||||||
|| ':' || (select split_part(idName, ':', 2) from hs_office_relationship_iv ri where ri.uuid = target.debitorRelUuid)
|
|
||||||
$idName$);
|
|
||||||
--//
|
|
||||||
|
|
||||||
|
call generateRbacIdentityViewFromQuery('hs_office_debitor', $idName$
|
||||||
|
SELECT debitor.uuid AS uuid,
|
||||||
|
'D-' || (SELECT partner.partnerNumber
|
||||||
|
FROM hs_office_partner partner
|
||||||
|
JOIN hs_office_relationship partnerRel
|
||||||
|
ON partnerRel.uuid = partner.partnerRoleUUid AND partnerRel.relType = 'PARTNER'
|
||||||
|
JOIN hs_office_relationship debitorRel
|
||||||
|
ON debitorRel.relAnchorUuid = partnerRel.relHolderUuid AND partnerRel.relType = 'ACCOUNTING'
|
||||||
|
WHERE debitorRel.uuid = debitor.debitorRelUuid)
|
||||||
|
|| to_char(debitorNumberSuffix, 'fm00') as idName
|
||||||
|
FROM hs_office_debitor AS debitor
|
||||||
|
|
||||||
|
$idName$);
|
||||||
|
--//
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-debitor-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-debitor-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacRestrictedView('hs_office_debitor', 'target.debitorNumberSuffix',
|
call generateRbacRestrictedView('hs_office_debitor',
|
||||||
|
$orderBy$
|
||||||
|
defaultPrefix
|
||||||
|
$orderBy$,
|
||||||
$updates$
|
$updates$
|
||||||
debitorRel = new.debitorRel,
|
debitorRel = new.debitorRel,
|
||||||
billable = new.billable,
|
billable = new.billable,
|
||||||
billingContactUuid = new.billingContactUuid,
|
debitorUuid = new.debitorUuid,
|
||||||
refundBankAccountUuid = new.refundBankAccountUuid,
|
refundBankAccountUuid = new.refundBankAccountUuid,
|
||||||
vatId = new.vatId,
|
vatId = new.vatId,
|
||||||
vatCountryCode = new.vatCountryCode,
|
vatCountryCode = new.vatCountryCode,
|
||||||
vatBusiness = new.vatBusiness,
|
vatBusiness = new.vatBusiness,
|
||||||
vatreversecharge = new.vatreversecharge,
|
vatReverseCharge = new.vatReverseCharge,
|
||||||
defaultPrefix = new.defaultPrefix -- TODO: Should it be allowed to updated this value?
|
defaultPrefix = new.defaultPrefix
|
||||||
$updates$);
|
$updates$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
-- ============================================================================
|
|
||||||
--changeset hs-office-debitor-rbac-NEW-DEBITOR:1 endDelimiter:--//
|
|
||||||
-- ----------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
Creates a global permission for new-debitor and assigns it to the hostsharing admins role.
|
|
||||||
*/
|
|
||||||
do language plpgsql $$
|
|
||||||
declare
|
|
||||||
addDebitorPermissions uuid[];
|
|
||||||
globalObjectUuid uuid;
|
|
||||||
globalAdminRoleUuid uuid ;
|
|
||||||
begin
|
|
||||||
call defineContext('granting global new-debitor permission to global admin role', null, null, null);
|
|
||||||
|
|
||||||
globalAdminRoleUuid := findRoleId(globalAdmin());
|
|
||||||
globalObjectUuid := (select uuid from global);
|
|
||||||
addDebitorPermissions := createPermissions(globalObjectUuid, array ['new-debitor']);
|
|
||||||
call grantPermissionsToRole(globalAdminRoleUuid, addDebitorPermissions);
|
|
||||||
end;
|
|
||||||
$$;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Used by the trigger to prevent the add-debitor to current user respectively assumed roles.
|
|
||||||
*/
|
|
||||||
create or replace function addHsOfficeDebitorNotAllowedForCurrentSubjects()
|
|
||||||
returns trigger
|
|
||||||
language PLPGSQL
|
|
||||||
as $$
|
|
||||||
begin
|
|
||||||
raise exception '[403] new-debitor not permitted for %',
|
|
||||||
array_to_string(currentSubjects(), ';', 'null');
|
|
||||||
end; $$;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Checks if the user or assumed roles are allowed to create a new debitor.
|
|
||||||
*/
|
|
||||||
create trigger hs_office_debitor_insert_trigger
|
|
||||||
before insert
|
|
||||||
on hs_office_debitor
|
|
||||||
for each row
|
|
||||||
-- TODO.spec: who is allowed to create new debitors
|
|
||||||
when ( not hasAssumedRole() )
|
|
||||||
execute procedure addHsOfficeDebitorNotAllowedForCurrentSubjects();
|
|
||||||
--//
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user