Compare commits
3 Commits
d285b440ea
...
4dafa031a0
Author | SHA1 | Date | |
---|---|---|---|
|
4dafa031a0 | ||
|
ed59b877ce | ||
|
21bb9dad19 |
@ -1,9 +1,11 @@
|
|||||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.BinaryOperator;
|
import java.util.function.BinaryOperator;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.joining;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.PostgresTriggerReference.NEW;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.PostgresTriggerReference.NEW;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
|
||||||
@ -25,7 +27,6 @@ public class InsertTriggerGenerator {
|
|||||||
void generateTo(final StringWriter plPgSql) {
|
void generateTo(final StringWriter plPgSql) {
|
||||||
generateInsertGrants(plPgSql);
|
generateInsertGrants(plPgSql);
|
||||||
generateInsertPermissionChecks(plPgSql);
|
generateInsertPermissionChecks(plPgSql);
|
||||||
plPgSql.writeLn("--//");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateInsertGrants(final StringWriter plPgSql) {
|
private void generateInsertGrants(final StringWriter plPgSql) {
|
||||||
@ -53,9 +54,11 @@ public class InsertTriggerGenerator {
|
|||||||
plPgSql.writeLn("""
|
plPgSql.writeLn("""
|
||||||
-- granting INSERT permission to ${rawSubTable} ----------------------------
|
-- granting INSERT permission to ${rawSubTable} ----------------------------
|
||||||
""",
|
""",
|
||||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
with("rawSubTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()));
|
||||||
|
|
||||||
plPgSql.writeLn("""
|
if (isGrantToADifferentTable(g)) {
|
||||||
|
plPgSql.writeLn(
|
||||||
|
"""
|
||||||
/*
|
/*
|
||||||
Grants INSERT INTO ${rawSubTable} permissions to specified role of pre-existing ${rawSuperTable} rows.
|
Grants INSERT INTO ${rawSubTable} permissions to specified role of pre-existing ${rawSuperTable} rows.
|
||||||
*/
|
*/
|
||||||
@ -82,6 +85,14 @@ public class InsertTriggerGenerator {
|
|||||||
: "-- unconditional for all rows in that table"),
|
: "-- unconditional for all rows in that table"),
|
||||||
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
|
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
|
||||||
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()));
|
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()));
|
||||||
|
} else {
|
||||||
|
plPgSql.writeLn("""
|
||||||
|
-- Granting INSERT INTO hs_hosting_asset permissions to specified role of pre-existing hs_hosting_asset rows slipped,
|
||||||
|
-- because there cannot yet be any pre-existing rows in the same table yet.
|
||||||
|
""",
|
||||||
|
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
|
||||||
|
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()));
|
||||||
|
}
|
||||||
|
|
||||||
plPgSql.writeLn("""
|
plPgSql.writeLn("""
|
||||||
/**
|
/**
|
||||||
@ -150,7 +161,6 @@ public class InsertTriggerGenerator {
|
|||||||
plPgSql.writeLn("--//");
|
plPgSql.writeLn("--//");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void generateInsertPermissionChecks(final StringWriter plPgSql) {
|
private void generateInsertPermissionChecks(final StringWriter plPgSql) {
|
||||||
plPgSql.writeLn("""
|
plPgSql.writeLn("""
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
@ -177,20 +187,30 @@ public class InsertTriggerGenerator {
|
|||||||
when ( not (
|
when ( not (
|
||||||
""",
|
""",
|
||||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||||
|
plPgSql.chopEmptyLines();
|
||||||
|
|
||||||
plPgSql.indented(2, () -> {
|
plPgSql.indented(3, () -> {
|
||||||
getInsertGrants().forEach(g -> {
|
getInsertGrants().forEach(g -> {
|
||||||
final RbacView.EntityAlias superRoleEntityAlias = g.getSuperRoleDef().getEntityAlias();
|
final RbacView.EntityAlias superRoleEntityAlias = g.getSuperRoleDef().getEntityAlias();
|
||||||
|
final RbacView.EntityAlias permissionEntityAlias = g.getPermDef().entityAlias;
|
||||||
final var caseCondition = superRoleEntityAlias.isCaseDependent()
|
final var caseCondition = superRoleEntityAlias.isCaseDependent()
|
||||||
? "NEW.type = '" + superRoleEntityAlias.usingCase().value + "' and "
|
? ("NEW.type in (" + toStringList(g.getForCases()) + ") and ")
|
||||||
: "";
|
: "";
|
||||||
plPgSql.writeLn("${caseCondition}hasInsertPermission(NEW.${refColumn}, 'INSERT', '${rawSubTable}') or",
|
if ( g.getSuperRoleDef().isGlobalAdmin() ) {
|
||||||
|
plPgSql.writeLn(
|
||||||
|
"${caseCondition}isGlobalAdmin() or",
|
||||||
|
with("caseCondition", caseCondition));
|
||||||
|
} else {
|
||||||
|
plPgSql.writeLn(
|
||||||
|
"${caseCondition}hasInsertPermission(NEW.${refColumn}, '${rawSubTable}') or",
|
||||||
with("caseCondition", caseCondition),
|
with("caseCondition", caseCondition),
|
||||||
with("refColumn", superRoleEntityAlias.dependsOnColumName()),
|
with("refColumn", superRoleEntityAlias.dependsOnColumName()),
|
||||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
plPgSql.chopTail(" or\n");
|
plPgSql.chopTail(" or\n");
|
||||||
});
|
});
|
||||||
|
plPgSql.writeLn();
|
||||||
|
|
||||||
plPgSql.writeLn("""
|
plPgSql.writeLn("""
|
||||||
) )
|
) )
|
||||||
@ -200,6 +220,14 @@ public class InsertTriggerGenerator {
|
|||||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String toStringList(final Set<RbacView.CaseDef> cases) {
|
||||||
|
return cases.stream().map(c -> "'" + c.value + "'").collect(joining(", "));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isGrantToADifferentTable(final RbacView.RbacGrantDefinition g) {
|
||||||
|
return !rbacDef.getRootEntityAlias().getRawTableName().equals(g.getSuperRoleDef().getEntityAlias().getRawTableName());
|
||||||
|
}
|
||||||
|
|
||||||
private Stream<RbacView.RbacGrantDefinition> getInsertGrants() {
|
private Stream<RbacView.RbacGrantDefinition> getInsertGrants() {
|
||||||
return rbacDef.getGrantDefs().stream()
|
return rbacDef.getGrantDefs().stream()
|
||||||
.filter(g -> g.grantType() == PERM_TO_ROLE)
|
.filter(g -> g.grantType() == PERM_TO_ROLE)
|
||||||
|
@ -560,11 +560,13 @@ public class RbacView {
|
|||||||
register(this);
|
register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RbacGrantDefinition(final RbacPermissionDefinition permDef, final RbacRoleDefinition roleDef) {
|
public RbacGrantDefinition(final RbacPermissionDefinition permDef, final RbacRoleDefinition roleDef,
|
||||||
|
final CaseDef forCase) {
|
||||||
this.userDef = null;
|
this.userDef = null;
|
||||||
this.subRoleDef = null;
|
this.subRoleDef = null;
|
||||||
this.superRoleDef = roleDef;
|
this.superRoleDef = roleDef;
|
||||||
this.permDef = permDef;
|
this.permDef = permDef;
|
||||||
|
this.forCases = forCase != null ? hashSet(forCase) : null;
|
||||||
register(this);
|
register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,7 +678,8 @@ public class RbacView {
|
|||||||
final String tableName;
|
final String tableName;
|
||||||
final boolean toCreate;
|
final boolean toCreate;
|
||||||
|
|
||||||
private RbacPermissionDefinition(final EntityAlias entityAlias, final Permission permission, final String tableName, final boolean toCreate) {
|
private RbacPermissionDefinition(final EntityAlias entityAlias, final Permission permission, final String tableName,
|
||||||
|
final boolean toCreate) {
|
||||||
this.entityAlias = entityAlias;
|
this.entityAlias = entityAlias;
|
||||||
this.permission = permission;
|
this.permission = permission;
|
||||||
this.tableName = tableName;
|
this.tableName = tableName;
|
||||||
@ -788,6 +791,10 @@ public class RbacView {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "role:" + entityAlias.aliasName + role;
|
return "role:" + entityAlias.aliasName + role;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isGlobalAdmin() {
|
||||||
|
return entityAlias.isGlobal() && role == Role.ADMIN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public RbacUserReference findUserRef(final RbacUserReference.UserRole userRole) {
|
public RbacUserReference findUserRef(final RbacUserReference.UserRole userRole) {
|
||||||
@ -842,19 +849,6 @@ public class RbacView {
|
|||||||
.orElseGet(() -> new RbacPermissionDefinition(entityAlias, perm, tableName, true)); // TODO: true => toCreate
|
.orElseGet(() -> new RbacPermissionDefinition(entityAlias, perm, tableName, true)); // TODO: true => toCreate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RbacPermissionDefinition findRbacPerm(final EntityAlias entityAlias, final Permission perm) {
|
|
||||||
return findRbacPerm(entityAlias, perm, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RbacPermissionDefinition findRbacPerm(final String entityAliasName, final Permission perm, String tableName) {
|
|
||||||
return findRbacPerm(findEntityAlias(entityAliasName), perm, tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RbacPermissionDefinition findRbacPerm(final String entityAliasName, final Permission perm) {
|
|
||||||
return findRbacPerm(findEntityAlias(entityAliasName), perm);
|
|
||||||
}
|
|
||||||
|
|
||||||
private RbacGrantDefinition findOrCreateGrantDef(final RbacRoleDefinition roleDefinition, final RbacUserReference user) {
|
private RbacGrantDefinition findOrCreateGrantDef(final RbacRoleDefinition roleDefinition, final RbacUserReference user) {
|
||||||
return grantDefs.stream()
|
return grantDefs.stream()
|
||||||
.filter(g -> g.subRoleDef == roleDefinition && g.userDef == user)
|
.filter(g -> g.subRoleDef == roleDefinition && g.userDef == user)
|
||||||
@ -866,7 +860,7 @@ public class RbacView {
|
|||||||
return grantDefs.stream()
|
return grantDefs.stream()
|
||||||
.filter(g -> g.permDef == permDef && g.superRoleDef == roleDef)
|
.filter(g -> g.permDef == permDef && g.superRoleDef == roleDef)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseGet(() -> new RbacGrantDefinition(permDef, roleDef));
|
.orElseGet(() -> new RbacGrantDefinition(permDef, roleDef, processingCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
private RbacGrantDefinition findOrCreateGrantDef(
|
private RbacGrantDefinition findOrCreateGrantDef(
|
||||||
|
@ -569,14 +569,14 @@ select exists(
|
|||||||
);
|
);
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
create or replace function hasInsertPermission(objectUuid uuid, forOp RbacOp, tableName text )
|
create or replace function hasInsertPermission(objectUuid uuid, tableName text )
|
||||||
returns BOOL
|
returns BOOL
|
||||||
stable -- leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
permissionUuid uuid;
|
permissionUuid uuid;
|
||||||
begin
|
begin
|
||||||
permissionUuid = findPermissionId(objectUuid, forOp, tableName);
|
permissionUuid = findPermissionId(objectUuid, 'INSERT'::RbacOp, tableName);
|
||||||
return permissionUuid is not null;
|
return permissionUuid is not null;
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
@ -200,7 +200,7 @@ end; $$;
|
|||||||
create trigger test_package_insert_permission_check_tg
|
create trigger test_package_insert_permission_check_tg
|
||||||
before insert on test_package
|
before insert on test_package
|
||||||
for each row
|
for each row
|
||||||
when ( not hasInsertPermission(NEW.customerUuid, 'INSERT', 'test_package') )
|
when ( not hasInsertPermission(NEW.customerUuid, 'test_package') )
|
||||||
execute procedure test_package_insert_permission_missing_tf();
|
execute procedure test_package_insert_permission_missing_tf();
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ end; $$;
|
|||||||
create trigger test_domain_insert_permission_check_tg
|
create trigger test_domain_insert_permission_check_tg
|
||||||
before insert on test_domain
|
before insert on test_domain
|
||||||
for each row
|
for each row
|
||||||
when ( not hasInsertPermission(NEW.packageUuid, 'INSERT', 'test_domain') )
|
when ( not hasInsertPermission(NEW.packageUuid, 'test_domain') )
|
||||||
execute procedure test_domain_insert_permission_missing_tf();
|
execute procedure test_domain_insert_permission_missing_tf();
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ end; $$;
|
|||||||
create trigger hs_office_relation_insert_permission_check_tg
|
create trigger hs_office_relation_insert_permission_check_tg
|
||||||
before insert on hs_office_relation
|
before insert on hs_office_relation
|
||||||
for each row
|
for each row
|
||||||
when ( not hasInsertPermission(NEW.anchorUuid, 'INSERT', 'hs_office_relation') )
|
when ( not hasInsertPermission(NEW.anchorUuid, 'hs_office_relation') )
|
||||||
execute procedure hs_office_relation_insert_permission_missing_tf();
|
execute procedure hs_office_relation_insert_permission_missing_tf();
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ begin
|
|||||||
);
|
);
|
||||||
assert superRoleObjectUuid is not null, 'superRoleObjectUuid must not be null';
|
assert superRoleObjectUuid is not null, 'superRoleObjectUuid must not be null';
|
||||||
|
|
||||||
if ( not hasInsertPermission(superRoleObjectUuid, 'INSERT', 'hs_office_sepamandate') ) then
|
if ( not hasInsertPermission(superRoleObjectUuid, 'hs_office_sepamandate') ) then
|
||||||
raise exception
|
raise exception
|
||||||
'[403] insert into hs_office_sepamandate not allowed for current subjects % (%)',
|
'[403] insert into hs_office_sepamandate not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
|
@ -123,7 +123,7 @@ end; $$;
|
|||||||
create trigger hs_office_coopsharestransaction_insert_permission_check_tg
|
create trigger hs_office_coopsharestransaction_insert_permission_check_tg
|
||||||
before insert on hs_office_coopsharestransaction
|
before insert on hs_office_coopsharestransaction
|
||||||
for each row
|
for each row
|
||||||
when ( not hasInsertPermission(NEW.membershipUuid, 'INSERT', 'hs_office_coopsharestransaction') )
|
when ( not hasInsertPermission(NEW.membershipUuid, 'hs_office_coopsharestransaction') )
|
||||||
execute procedure hs_office_coopsharestransaction_insert_permission_missing_tf();
|
execute procedure hs_office_coopsharestransaction_insert_permission_missing_tf();
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ end; $$;
|
|||||||
create trigger hs_office_coopassetstransaction_insert_permission_check_tg
|
create trigger hs_office_coopassetstransaction_insert_permission_check_tg
|
||||||
before insert on hs_office_coopassetstransaction
|
before insert on hs_office_coopassetstransaction
|
||||||
for each row
|
for each row
|
||||||
when ( not hasInsertPermission(NEW.membershipUuid, 'INSERT', 'hs_office_coopassetstransaction') )
|
when ( not hasInsertPermission(NEW.membershipUuid, 'hs_office_coopassetstransaction') )
|
||||||
execute procedure hs_office_coopassetstransaction_insert_permission_missing_tf();
|
execute procedure hs_office_coopassetstransaction_insert_permission_missing_tf();
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ begin
|
|||||||
);
|
);
|
||||||
assert superRoleObjectUuid is not null, 'superRoleObjectUuid must not be null';
|
assert superRoleObjectUuid is not null, 'superRoleObjectUuid must not be null';
|
||||||
|
|
||||||
if ( not hasInsertPermission(superRoleObjectUuid, 'INSERT', 'hs_booking_item') ) then
|
if ( not hasInsertPermission(superRoleObjectUuid, 'hs_booking_item') ) then
|
||||||
raise exception
|
raise exception
|
||||||
'[403] insert into hs_booking_item not allowed for current subjects % (%)',
|
'[403] insert into hs_booking_item not allowed for current subjects % (%)',
|
||||||
currentSubjects(), currentSubjectsUuids();
|
currentSubjects(), currentSubjectsUuids();
|
||||||
|
@ -93,7 +93,7 @@ execute procedure insertTriggerForHsHostingAsset_tf();
|
|||||||
--changeset hs-hosting-asset-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
--changeset hs-hosting-asset-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
-- granting INSERT permission to hs_hosting_asset ----------------------------
|
-- granting INSERT permission to hs_booking_item ----------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Grants INSERT INTO hs_hosting_asset permissions to specified role of pre-existing hs_booking_item rows.
|
Grants INSERT INTO hs_hosting_asset permissions to specified role of pre-existing hs_booking_item rows.
|
||||||
@ -138,24 +138,8 @@ execute procedure new_hs_hosting_asset_grants_insert_to_hs_booking_item_tf();
|
|||||||
|
|
||||||
-- granting INSERT permission to hs_hosting_asset ----------------------------
|
-- granting INSERT permission to hs_hosting_asset ----------------------------
|
||||||
|
|
||||||
/*
|
-- Granting INSERT INTO hs_hosting_asset permissions to specified role of pre-existing hs_hosting_asset rows slipped,
|
||||||
Grants INSERT INTO hs_hosting_asset permissions to specified role of pre-existing hs_hosting_asset rows.
|
-- because there cannot yet be any pre-existing rows in the same table yet.
|
||||||
*/
|
|
||||||
do language plpgsql $$
|
|
||||||
declare
|
|
||||||
preExistingRow hs_hosting_asset;
|
|
||||||
begin
|
|
||||||
call defineContext('create INSERT INTO hs_hosting_asset permissions for pre-exising hs_hosting_asset rows');
|
|
||||||
|
|
||||||
FOR preExistingRow IN SELECT * FROM hs_hosting_asset
|
|
||||||
WHERE preExistingRow.type = 'MANAGED_SERVER'
|
|
||||||
LOOP
|
|
||||||
call grantPermissionToRole(
|
|
||||||
createPermission(preExistingRow.uuid, 'INSERT', 'hs_hosting_asset'),
|
|
||||||
hsBookingItemAGENT(preExistingRow));
|
|
||||||
END LOOP;
|
|
||||||
end;
|
|
||||||
$$;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Grants hs_hosting_asset INSERT permission to specified role of new hs_hosting_asset rows.
|
Grants hs_hosting_asset INSERT permission to specified role of new hs_hosting_asset rows.
|
||||||
@ -202,12 +186,12 @@ create trigger hs_hosting_asset_insert_permission_check_tg
|
|||||||
before insert on hs_hosting_asset
|
before insert on hs_hosting_asset
|
||||||
for each row
|
for each row
|
||||||
when ( not (
|
when ( not (
|
||||||
|
hasInsertPermission(NEW.bookingItemUuid, 'hs_hosting_asset') or
|
||||||
hasInsertPermission(NEW.bookingItemUuid, 'INSERT', 'hs_hosting_asset') or
|
NEW.type in ('MANAGED_WEBSPACE') and hasInsertPermission(NEW.parentAssetUuid, 'hs_hosting_asset')
|
||||||
NEW.type = 'MANAGED_SERVER' and hasInsertPermission(NEW.parentAssetUuid, 'INSERT', 'hs_hosting_asset') ) )
|
) )
|
||||||
execute procedure hs_hosting_asset_insert_permission_missing_tf();
|
execute procedure hs_hosting_asset_insert_permission_missing_tf();
|
||||||
--//
|
--//
|
||||||
--//
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-hosting-asset-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-hosting-asset-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
|
Loading…
Reference in New Issue
Block a user