move Parter+Debitor person+contact to related Relationsship #20
@ -16,11 +16,11 @@ import org.hibernate.annotations.GenericGenerator;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
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.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
|
||||
@ -108,7 +108,7 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
||||
public static RbacView rbac() {
|
||||
return rbacViewFor("debitor", HsOfficeDebitorEntity.class)
|
||||
.withIdentityView(SQL.query("""
|
||||
SELECT debitor.uuid,
|
||||
SELECT debitor.uuid AS uuid,
|
||||
'D-' || (SELECT partner.partnerNumber
|
||||
FROM hs_office_partner partner
|
||||
JOIN hs_office_relationship partnerRel
|
||||
@ -116,9 +116,10 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
||||
JOIN hs_office_relationship debitorRel
|
||||
ON debitorRel.relAnchorUuid = partnerRel.relHolderUuid AND partnerRel.relType = 'ACCOUNTING'
|
||||
WHERE debitorRel.uuid = debitor.debitorRelUuid)
|
||||
|| to_char(debitorNumberSuffix, 'fm00')
|
||||
from hs_office_debitor as debitor
|
||||
|| to_char(debitorNumberSuffix, 'fm00') as idName
|
||||
FROM hs_office_debitor AS debitor
|
||||
"""))
|
||||
.withRestrictedViewOrderBy(SQL.projection("defaultPrefix"))
|
||||
.withUpdatableColumns(
|
||||
"debitorRel",
|
||||
"billable",
|
||||
@ -129,13 +130,13 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
||||
"vatBusiness",
|
||||
"vatReverseCharge",
|
||||
"defaultPrefix" /* TODO: do we want that updatable? */)
|
||||
.createPermission(custom("new-debitor")).grantedTo("global", ADMIN)
|
||||
.toRole("global", ADMIN).grantPermission("debitor", INSERT)
|
||||
|
||||
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationshipEntity.class,
|
||||
fetchedBySql("""
|
||||
SELECT *
|
||||
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"))
|
||||
.createPermission(DELETE).grantedTo("debitorRel", OWNER)
|
||||
@ -143,21 +144,27 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
||||
.createPermission(SELECT).grantedTo("debitorRel", TENANT)
|
||||
|
||||
.importEntityAlias("refundBankAccount", HsOfficeBankAccountEntity.class,
|
||||
dependsOnColumn("refundBankAccountUuid"), fetchedBySql("""
|
||||
dependsOnColumn("refundBankAccountUuid"),
|
||||
fetchedBySql("""
|
||||
SELECT *
|
||||
FROM hs_office_relationship AS r
|
||||
WHERE r.relType = 'ACCOUNTING' AND r.relHolderUuid = ${REF}.debitorRelUuid
|
||||
""")
|
||||
"""),
|
||||
NULLABLE
|
||||
)
|
||||
.toRole("refundBankAccount", ADMIN).grantRole("debitorRel", AGENT)
|
||||
.toRole("debitorRel", AGENT).grantRole("refundBankAccount", REFERRER)
|
||||
|
||||
.importEntityAlias("partnerRel", HsOfficeRelationshipEntity.class,
|
||||
dependsOnColumn("partnerRelUuid"), fetchedBySql("""
|
||||
SELECT *
|
||||
FROM hs_office_relationship AS partnerRel
|
||||
WHERE ${debitorRel}.relAnchorUuid = partnerRel.relHolderUuid
|
||||
""")
|
||||
dependsOnColumn("debitorRelUuid"),
|
||||
fetchedBySql("""
|
||||
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 ${REF}.debitorRelUuid = debitorRel.uuid
|
||||
""")
|
||||
)
|
||||
.toRole("partnerRel", ADMIN).grantRole("debitorRel", ADMIN)
|
||||
.toRole("partnerRel", AGENT).grantRole("debitorRel", AGENT)
|
||||
@ -169,6 +176,6 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
||||
}
|
||||
|
||||
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",
|
||||
"birthday",
|
||||
"dateOfDeath")
|
||||
.createPermission(custom("new-partner-details")).grantedTo("global", ADMIN)
|
||||
.toRole("global", ADMIN).grantPermission("partner-details", INSERT)
|
||||
|
||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationshipEntity.class,
|
||||
fetchedBySql("""
|
||||
|
@ -27,7 +27,6 @@ import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.*;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
@ -105,7 +104,7 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
|
||||
"partnerRoleUuid",
|
||||
"personUuid",
|
||||
"contactUuid")
|
||||
.createPermission(custom("new-partner")).grantedTo("global", ADMIN)
|
||||
.toRole("global", ADMIN).grantPermission("partner", INSERT) // FIXME: global -> partnerRel.relAnchor?
|
||||
|
||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationshipEntity.class,
|
||||
fetchedBySql("SELECT * FROM hs_office_relationship AS r WHERE r.uuid = ${ref}.partnerRoleUuid"),
|
||||
|
@ -55,7 +55,7 @@ public class InsertTriggerGenerator {
|
||||
LOOP
|
||||
roleUuid := findRoleId(${rawSuperRoleDescriptor});
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', '${rawSubTableName}');
|
||||
call grantPermissionToRole(roleUuid, permissionUuid);
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
@ -32,6 +32,7 @@ import java.util.stream.Stream;
|
||||
import static java.lang.reflect.Modifier.isStatic;
|
||||
import static java.util.Arrays.stream;
|
||||
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.SQL.autoFetched;
|
||||
import static org.apache.commons.lang3.StringUtils.uncapitalize;
|
||||
@ -141,35 +142,42 @@ public class RbacView {
|
||||
if (rootEntityAliasProxy != null) {
|
||||
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;
|
||||
}
|
||||
|
||||
public RbacView importSubEntityAlias(
|
||||
final String aliasName, final Class<? extends HasUuid> entityClass,
|
||||
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;
|
||||
}
|
||||
|
||||
public RbacView importEntityAlias(
|
||||
final String aliasName, final Class<? extends HasUuid> entityClass,
|
||||
final Column dependsOnColum, final SQL fetchSql) {
|
||||
importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum, false);
|
||||
importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum, false, NOT_NULL);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RbacView importEntityAlias(
|
||||
final String aliasName, final Class<? extends HasUuid> entityClass,
|
||||
final Column dependsOnColum) {
|
||||
importEntityAliasImpl(aliasName, entityClass, autoFetched(), dependsOnColum, false);
|
||||
importEntityAliasImpl(aliasName, entityClass, autoFetched(), dependsOnColum, false, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
private EntityAlias importEntityAliasImpl(
|
||||
final String aliasName, final Class<? extends HasUuid> entityClass,
|
||||
final SQL fetchSql, final Column dependsOnColum, boolean asSubEntity) {
|
||||
final var entityAlias = new EntityAlias(aliasName, entityClass, fetchSql, dependsOnColum, asSubEntity);
|
||||
final SQL fetchSql, final Column dependsOnColum, boolean asSubEntity, final Nullable nullable) {
|
||||
final var entityAlias = new EntityAlias(aliasName, entityClass, fetchSql, dependsOnColum, asSubEntity, nullable);
|
||||
entityAliases.put(aliasName, entityAlias);
|
||||
try {
|
||||
importAsAlias(aliasName, rbacDefinition(entityClass), asSubEntity);
|
||||
@ -281,6 +289,7 @@ public class RbacView {
|
||||
return RbacView.this;
|
||||
}
|
||||
|
||||
// TODO: switch order or parameters for more natural readability
|
||||
public RbacView grantPermission(final String entityAliasName, final Permission perm) {
|
||||
final var entityAlias = findEntityAlias(entityAliasName);
|
||||
final var forTable = entityAlias.getRawTableName();
|
||||
@ -290,6 +299,11 @@ public class RbacView {
|
||||
|
||||
}
|
||||
|
||||
public enum Nullable {
|
||||
NOT_NULL, // DEFAULT
|
||||
NULLABLE
|
||||
}
|
||||
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
public class RbacGrantDefinition {
|
||||
@ -560,14 +574,14 @@ public class RbacView {
|
||||
.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) {
|
||||
this(aliasName, null, null, null, false);
|
||||
this(aliasName, null, null, null, false, null);
|
||||
}
|
||||
|
||||
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() {
|
||||
@ -646,20 +660,15 @@ public class RbacView {
|
||||
}
|
||||
}
|
||||
|
||||
public record Permission(String permission) {
|
||||
|
||||
public static final Permission INSERT = new Permission("INSERT");
|
||||
public static final Permission DELETE = new Permission("DELETE");
|
||||
public static final Permission UPDATE = new Permission("UPDATE");
|
||||
public static final Permission SELECT = new Permission("SELECT");
|
||||
|
||||
public static Permission custom(final String permission) {
|
||||
return new Permission(permission);
|
||||
}
|
||||
public enum Permission {
|
||||
INSERT,
|
||||
DELETE,
|
||||
UPDATE,
|
||||
SELECT;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ":" + permission;
|
||||
return ":" + name();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,8 +37,11 @@ public class RbacViewPostgresGenerator {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return plPgSql.toString();
|
||||
}
|
||||
return plPgSql.toString()
|
||||
.replace("\n\n\n", "\n\n")
|
||||
.replace("-- ====", "\n-- ====")
|
||||
.replace("\n\n--//", "\n--//");
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void generateToChangeLog(final Path outputPath) {
|
||||
|
@ -82,6 +82,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
plPgSql.writeLn("begin");
|
||||
plPgSql.indented(() -> {
|
||||
plPgSql.writeLn("call enterTriggerForObjectUuid(NEW.uuid);");
|
||||
plPgSql.writeLn();
|
||||
generateCreateRolesAndGrantsAfterInsert(plPgSql);
|
||||
plPgSql.ensureSingleEmptyLine();
|
||||
plPgSql.writeLn("call leaveTriggerForObjectUuid(NEW.uuid);");
|
||||
@ -109,7 +110,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
|
||||
plPgSql.chopEmptyLines();
|
||||
plPgSql.indented(() -> {
|
||||
updatableEntityAliases()
|
||||
referencedEntityAliases()
|
||||
.forEach((ea) -> {
|
||||
plPgSql.writeLn(entityRefVar(OLD, ea) + " " + ea.getRawTableName() + ";");
|
||||
plPgSql.writeLn(entityRefVar(NEW, ea) + " " + ea.getRawTableName() + ";");
|
||||
@ -120,6 +121,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
plPgSql.writeLn("begin");
|
||||
plPgSql.indented(() -> {
|
||||
plPgSql.writeLn("call enterTriggerForObjectUuid(NEW.uuid);");
|
||||
plPgSql.writeLn();
|
||||
generateUpdateRolesAndGrantsAfterUpdate(plPgSql);
|
||||
plPgSql.ensureSingleEmptyLine();
|
||||
plPgSql.writeLn("call leaveTriggerForObjectUuid(NEW.uuid);");
|
||||
@ -134,9 +136,10 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
|
||||
private void generateCreateRolesAndGrantsAfterInsert(final StringWriter plPgSql) {
|
||||
referencedEntityAliases()
|
||||
.forEach((ea) -> plPgSql.writeLn(
|
||||
ea.fetchSql().sql + " into " + entityRefVar(NEW, ea) + ";",
|
||||
with("ref", NEW.name())));
|
||||
.forEach((ea) -> {
|
||||
generateFetchedVars(plPgSql, ea, NEW);
|
||||
plPgSql.writeLn();
|
||||
});
|
||||
|
||||
createRolesWithGrantsSql(plPgSql, OWNER);
|
||||
createRolesWithGrantsSql(plPgSql, ADMIN);
|
||||
@ -165,14 +168,11 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
private void generateUpdateRolesAndGrantsAfterUpdate(final StringWriter plPgSql) {
|
||||
plPgSql.ensureSingleEmptyLine();
|
||||
|
||||
updatableEntityAliases()
|
||||
referencedEntityAliases()
|
||||
.forEach((ea) -> {
|
||||
plPgSql.writeLn(
|
||||
ea.fetchSql().sql + " into " + entityRefVar(OLD, ea) + ";",
|
||||
with("ref", OLD.name()));
|
||||
plPgSql.writeLn(
|
||||
ea.fetchSql().sql + " into " + entityRefVar(NEW, ea) + ";",
|
||||
with("ref", NEW.name()));
|
||||
generateFetchedVars(plPgSql, ea, OLD);
|
||||
generateFetchedVars(plPgSql, ea, NEW);
|
||||
plPgSql.writeLn();
|
||||
});
|
||||
|
||||
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) {
|
||||
return rbacDef.getUpdatableColumns().contains(c);
|
||||
}
|
||||
@ -256,7 +273,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
.replace("${entityRef}", rbacDef.isRootEntityAlias(permDef.entityAlias)
|
||||
? ref.name()
|
||||
: refVarName(ref, permDef.entityAlias))
|
||||
.replace("${perm}", permDef.permission.permission());
|
||||
.replace("${perm}", permDef.permission.name());
|
||||
}
|
||||
|
||||
private String refVarName(final PostgresTriggerReference ref, final RbacView.EntityAlias entityAlias) {
|
||||
@ -333,7 +350,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
final var arrayElements = permissionGrantsForRole.stream()
|
||||
.map(RbacView.RbacGrantDefinition::getPermDef)
|
||||
.map(RbacPermissionDefinition::getPermission)
|
||||
.map(RbacView.Permission::permission)
|
||||
.map(RbacView.Permission::name)
|
||||
.map(p -> "'" + p + "'")
|
||||
.sorted()
|
||||
.toList();
|
||||
|
@ -103,8 +103,8 @@ public class StringWriter {
|
||||
text = matcher.replaceAll(varDef.value());
|
||||
});
|
||||
return text;
|
||||
} catch (Exception exc) {
|
||||
throw exc;
|
||||
} catch (final RuntimeException 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 $$
|
||||
begin
|
||||
perform assertReferenceType('roleId (ascendant)', roleUuid, 'RbacRole');
|
||||
@ -622,10 +622,10 @@ begin
|
||||
end;
|
||||
$$;
|
||||
|
||||
create or replace procedure grantPermissionToRole(roleDesc RbacRoleDescriptor, permissionUuid uuid)
|
||||
create or replace procedure grantPermissionToRole(permissionUuid uuid, roleDesc RbacRoleDescriptor)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
call grantPermissionToRole(findRoleId(roleDesc), permissionUuid);
|
||||
call grantPermissionToRole(permissionUuid, findRoleId(roleDesc));
|
||||
end;
|
||||
$$;
|
||||
|
||||
@ -671,6 +671,11 @@ declare
|
||||
superRoleId uuid;
|
||||
subRoleId uuid;
|
||||
begin
|
||||
-- FIXME: maybe separate method grantRoleToRoleIfNotNull(...)?
|
||||
if superRole.objectUuid is null or subRole.objectuuid is null then
|
||||
return;
|
||||
end if;
|
||||
|
||||
superRoleId := findRoleId(superRole);
|
||||
subRoleId := findRoleId(subRole);
|
||||
|
||||
|
@ -160,7 +160,7 @@ do language plpgsql $$
|
||||
LOOP
|
||||
roleUuid := findRoleId(testCustomerAdmin(row));
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'test_package');
|
||||
call grantPermissionToRole(roleUuid, permissionUuid);
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
@ -174,8 +174,8 @@ create or replace function test_package_test_customer_insert_tf()
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
testCustomerAdmin(NEW),
|
||||
createPermission(NEW.uuid, 'INSERT', 'test_package'));
|
||||
createPermission(NEW.uuid, 'INSERT', 'test_package'),
|
||||
testCustomerAdmin(NEW));
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
|
@ -159,7 +159,7 @@ do language plpgsql $$
|
||||
LOOP
|
||||
roleUuid := findRoleId(testPackageAdmin(row));
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'test_domain');
|
||||
call grantPermissionToRole(roleUuid, permissionUuid);
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
@ -173,8 +173,8 @@ create or replace function test_domain_test_package_insert_tf()
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
testPackageAdmin(NEW),
|
||||
createPermission(NEW.uuid, 'INSERT', 'test_domain'));
|
||||
createPermission(NEW.uuid, 'INSERT', 'test_domain'),
|
||||
testPackageAdmin(NEW));
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
|
@ -94,7 +94,7 @@ do language plpgsql $$
|
||||
LOOP
|
||||
roleUuid := findRoleId(globalGuest());
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_person');
|
||||
call grantPermissionToRole(roleUuid, permissionUuid);
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
@ -108,8 +108,8 @@ create or replace function hs_office_person_global_insert_tf()
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
globalGuest(),
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_person'));
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_person'),
|
||||
globalGuest());
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
|
@ -106,7 +106,7 @@ do language plpgsql $$
|
||||
call createHsOfficeRelationshipTestData('Third OHG', 'ACCOUNTING', 'Third OHG', 'third 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');
|
||||
end;
|
||||
$$;
|
||||
|
@ -94,7 +94,7 @@ do language plpgsql $$
|
||||
LOOP
|
||||
roleUuid := findRoleId(globalGuest());
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_bankaccount');
|
||||
call grantPermissionToRole(roleUuid, permissionUuid);
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
@ -108,8 +108,8 @@ create or replace function hs_office_bankaccount_global_insert_tf()
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
globalGuest(),
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_bankaccount'));
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_bankaccount'),
|
||||
globalGuest());
|
||||
return NEW;
|
||||
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
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph partnerRelationship[hsOfficeRelationship:PARTNER]
|
||||
subgraph debitorRel.anchorPerson["`**debitorRel.anchorPerson**`"]
|
||||
direction TB
|
||||
style partnerRelationship fill:#eee
|
||||
|
||||
role:partnerRelationship.owner[relationship.owner]
|
||||
--> role:partnerRelationship.admin[relationship.admin]
|
||||
--> role:partnerRelationship.agent[relationship.agent]
|
||||
--> role:partnerRelationship.tenant[relationship.tenant]
|
||||
style debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
partnerPersonAdmin>e.g. partnerPerson.admin] --> role:partnerRelationship.agent
|
||||
otherPersonAdmin>e.g. operationalPerson.admin] --> role:partnerRelationship.tenant
|
||||
role:partnerRelationship.tenant --> partnerPersonReferrer>e.g. partnerPerson.referrer]
|
||||
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 internal[ ]
|
||||
subgraph debitorRel.holderPerson["`**debitorRel.holderPerson**`"]
|
||||
direction TB
|
||||
style internal fill:#fff
|
||||
style debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph refundBankAccount
|
||||
direction TB
|
||||
style refundBankAccount fill:#eee
|
||||
|
||||
role:refundBankAccount.owner[bankAccount.owner]
|
||||
--> role:refundBankAccount.admin[bankAccount.admin]
|
||||
--> role:refundBankAccount.referrer[bankAccount.referrer]
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
-- This code generated was by RbacViewPostgresGenerator at 2024-03-12T16:22:27.348469700.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--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()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
create or replace procedure buildRbacSystemForHsOfficeDebitor(
|
||||
NEW hs_office_debitor
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
debitorUuid uuid;
|
||||
|
||||
oldDebitorRel hs_office_relationship;
|
||||
newDebitorRel hs_office_relationship;
|
||||
|
||||
newPartnerRel hs_office_relationship;
|
||||
|
||||
newBankAccount hs_office_bankaccount;
|
||||
oldBankAccount hs_office_bankaccount;
|
||||
newPartnerRel hs_office_relationship;
|
||||
newDebitorRel hs_office_relationship;
|
||||
newRefundBankAccount hs_office_bankaccount;
|
||||
|
||||
begin
|
||||
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
|
||||
from hs_office_relationship as r where r.relType = 'ACCOUNTING' and r.relHolderUuid = NEW.debitorRelUuid;
|
||||
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 newPartnerRel
|
||||
from hs_office_relationship as partnerRel
|
||||
where newDebitorRel.relAnchorUuid = partnerRel.relHolderUuid;
|
||||
SELECT *
|
||||
FROM hs_office_relationship AS r
|
||||
WHERE r.relType = 'ACCOUNTING' AND r.relHolderUuid = NEW.debitorRelUuid
|
||||
INTO newRefundBankAccount;
|
||||
|
||||
select * into newBankAccount
|
||||
from hs_office_bankaccount as b where b.uuid = NEW.refundBankAccountUuid;
|
||||
call grantRoleToRole(hsOfficeBankAccountReferrer(newRefundBankAccount), hsOfficeRelationshipAgent(newDebitorRel));
|
||||
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)),
|
||||
createPermissions(partnerUuid, array ['DELETE'])
|
||||
);
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_debitor row.
|
||||
*/
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeRelationshipAdmin(newDebitorRel), 'fail'),
|
||||
createPermissions(partnerUuid, array ['UPDATE'])
|
||||
);
|
||||
create or replace function insertTriggerForHsOfficeDebitor_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForHsOfficeDebitor(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeRelationshipTenant(newDebitorRel), 'fail'),
|
||||
createPermissions(partnerUuid, array ['SELECT'])
|
||||
);
|
||||
create trigger insertTriggerForHsOfficeDebitor_tg
|
||||
after insert on hs_office_debitor
|
||||
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);
|
||||
--
|
||||
-- call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeRelationshipAgent(newPartnerRel), true);
|
||||
-- call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRel), hsOfficeRelationshipAgent(newDebitorRel), true);
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-rbac-update-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
-- Grants to and from refundBankAccount
|
||||
/*
|
||||
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
|
||||
*/
|
||||
|
||||
-- if newBankAccount is not null then
|
||||
-- call grantRoleToRole(hsOfficeBankAccountReferrer(newBankAccount), hsOfficeRelationshipAgent(newDebitorRel), true);
|
||||
-- call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeBankAccountAdmin(newBankAccount), true);
|
||||
-- end if;
|
||||
create or replace procedure updateRbacRulesForHsOfficeDebitor(
|
||||
OLD hs_office_debitor,
|
||||
NEW hs_office_debitor
|
||||
)
|
||||
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
|
||||
from hs_office_relationship as r where r.relType = 'ACCOUNTING' and r.relHolderUuid = NEW.debitorRelUuid;
|
||||
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 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(
|
||||
-- getRoleId(hsOfficeRelationshipOwner(newDebitorRel)),
|
||||
-- createPermissions(partnerUuid, array ['DELETE'])
|
||||
-- );
|
||||
--
|
||||
-- call grantPermissionsToRole(
|
||||
-- getRoleId(hsOfficeRelationshipAdmin(newDebitorRel)),
|
||||
-- createPermissions(partnerUuid, array ['UPDATE'])
|
||||
-- );
|
||||
--
|
||||
-- call grantPermissionsToRole(
|
||||
-- getRoleId(hsOfficeRelationshipTenant(newDebitorRel)),
|
||||
-- createPermissions(partnerUuid, array ['SELECT'])
|
||||
-- );
|
||||
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);
|
||||
|
||||
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
|
||||
from hs_office_bankaccount as b where b.uuid = OLD.refundBankAccountUuid;
|
||||
SELECT *
|
||||
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
|
||||
call revokeRoleFromRole(hsOfficeBankAccountReferrer(oldBankAccount), hsOfficeRelationshipAgent(oldDebitorRel), true);
|
||||
call revokeRoleFromRole(hsOfficeRelationshipAgent(oldDebitorRel), hsOfficeBankAccountAdmin(oldBankAccount), true);
|
||||
end if;
|
||||
if NEW.refundBankAccountUuid <> OLD.refundBankAccountUuid then
|
||||
|
||||
call revokeRoleFromRole(hsOfficeRelationshipAgent(oldDebitorRel), hsOfficeBankAccountAdmin(oldRefundBankAccount));
|
||||
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;
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
An AFTER INSERT TRIGGER which creates the role structure for a new debitor.
|
||||
*/
|
||||
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.
|
||||
AFTER INSERT TRIGGER to re-wire the grant structure for a new hs_office_debitor row.
|
||||
*/
|
||||
|
||||
create or replace function hsOfficeDebitorPartnerRelRbacRolesTrigger()
|
||||
create or replace function updateTriggerForHsOfficeDebitor_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
declare
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
-- TODO
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
call updateRbacRulesForHsOfficeDebitor(OLD, NEW);
|
||||
return NEW;
|
||||
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
|
||||
after update
|
||||
on hs_office_partner
|
||||
for each row
|
||||
execute procedure hsOfficeDebitorPartnerRelRbacRolesTrigger();
|
||||
--//
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
permissionUuid uuid;
|
||||
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:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
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:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('hs_office_debitor', 'target.debitorNumberSuffix',
|
||||
call generateRbacRestrictedView('hs_office_debitor',
|
||||
$orderBy$
|
||||
defaultPrefix
|
||||
$orderBy$,
|
||||
$updates$
|
||||
debitorRel = new.debitorRel,
|
||||
debitorRel = new.debitorRel,
|
||||
billable = new.billable,
|
||||
billingContactUuid = new.billingContactUuid,
|
||||
debitorUuid = new.debitorUuid,
|
||||
refundBankAccountUuid = new.refundBankAccountUuid,
|
||||
vatId = new.vatId,
|
||||
vatCountryCode = new.vatCountryCode,
|
||||
vatBusiness = new.vatBusiness,
|
||||
vatreversecharge = new.vatreversecharge,
|
||||
defaultPrefix = new.defaultPrefix -- TODO: Should it be allowed to updated this value?
|
||||
vatReverseCharge = new.vatReverseCharge,
|
||||
defaultPrefix = new.defaultPrefix
|
||||
$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