add integration test anyUser_canCreateNewDomainSetupAsset and (hacked) grants for DOMAIN_DNS_SETUP

This commit is contained in:
Michael Hoennig 2024-07-04 17:09:32 +02:00
parent 4c54abb742
commit 3d955fbb85
4 changed files with 55 additions and 110 deletions

View File

@ -41,6 +41,7 @@ import java.util.Map;
import java.util.UUID; import java.util.UUID;
import static java.util.Collections.emptyMap; import static java.util.Collections.emptyMap;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inCaseOf;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL;
@ -51,6 +52,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.GUEST;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.REFERRER; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.REFERRER;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
@ -199,6 +201,13 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject, Properti
directlyFetchedByDependsOnColumn(), directlyFetchedByDependsOnColumn(),
NULLABLE) NULLABLE)
.switchOnColumn("type",
inCaseOf("DOMAIN_SETUP", then -> {
then.toRole(GLOBAL, GUEST).grantPermission(INSERT);
then.toRole(GLOBAL, ADMIN).grantPermission(SELECT); // FIXME: remove
})
)
.createRole(OWNER, (with) -> { .createRole(OWNER, (with) -> {
with.incomingSuperRole("bookingItem", ADMIN); with.incomingSuperRole("bookingItem", ADMIN);
with.incomingSuperRole("parentAsset", ADMIN); with.incomingSuperRole("parentAsset", ADMIN);
@ -217,8 +226,11 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject, Properti
with.outgoingSubRole("bookingItem", TENANT); with.outgoingSubRole("bookingItem", TENANT);
with.outgoingSubRole("parentAsset", TENANT); with.outgoingSubRole("parentAsset", TENANT);
with.incomingSuperRole("alarmContact", ADMIN); with.incomingSuperRole("alarmContact", ADMIN);
with.incomingSuperRole(GLOBAL, GUEST); // FIXME: remove
with.incomingSuperRole(GLOBAL, ADMIN); // FIXME: remove
with.permission(SELECT); with.permission(SELECT);
}) })
.limitDiagramTo("asset", "bookingItem", "bookingItem.debitorRel", "parentAsset", "assignedToAsset", "alarmContact", "global"); .limitDiagramTo("asset", "bookingItem", "bookingItem.debitorRel", "parentAsset", "assignedToAsset", "alarmContact", "global");
} }

View File

@ -36,9 +36,9 @@ subgraph asset["`**asset**`"]
style asset:permissions fill:#dd4901,stroke:white style asset:permissions fill:#dd4901,stroke:white
perm:asset:INSERT{{asset:INSERT}} perm:asset:INSERT{{asset:INSERT}}
perm:asset:SELECT{{asset:SELECT}}
perm:asset:DELETE{{asset:DELETE}} perm:asset:DELETE{{asset:DELETE}}
perm:asset:UPDATE{{asset:UPDATE}} perm:asset:UPDATE{{asset:UPDATE}}
perm:asset:SELECT{{asset:SELECT}}
end end
end end
@ -99,10 +99,14 @@ role:asset:AGENT ==> role:asset:TENANT
role:asset:TENANT ==> role:bookingItem:TENANT role:asset:TENANT ==> role:bookingItem:TENANT
role:asset:TENANT ==> role:parentAsset:TENANT role:asset:TENANT ==> role:parentAsset:TENANT
role:alarmContact:ADMIN ==> role:asset:TENANT role:alarmContact:ADMIN ==> role:asset:TENANT
role:global:GUEST ==> role:asset:TENANT
role:global:ADMIN ==> role:asset:TENANT
%% granting permissions to roles %% granting permissions to roles
role:global:ADMIN ==> perm:asset:INSERT role:global:ADMIN ==> perm:asset:INSERT
role:parentAsset:ADMIN ==> perm:asset:INSERT role:parentAsset:ADMIN ==> perm:asset:INSERT
role:global:GUEST ==> perm:asset:INSERT
role:global:ADMIN ==> perm:asset:SELECT
role:asset:OWNER ==> perm:asset:DELETE role:asset:OWNER ==> perm:asset:DELETE
role:asset:ADMIN ==> perm:asset:UPDATE role:asset:ADMIN ==> perm:asset:UPDATE
role:asset:TENANT ==> perm:asset:SELECT role:asset:TENANT ==> perm:asset:SELECT

View File

@ -75,6 +75,8 @@ begin
hsHostingAssetTENANT(NEW), hsHostingAssetTENANT(NEW),
permissions => array['SELECT'], permissions => array['SELECT'],
incomingSuperRoles => array[ incomingSuperRoles => array[
globalADMIN(),
globalGUEST(),
hsHostingAssetAGENT(NEW), hsHostingAssetAGENT(NEW),
hsOfficeContactADMIN(newAlarmContact)], hsOfficeContactADMIN(newAlarmContact)],
outgoingSubRoles => array[ outgoingSubRoles => array[
@ -82,6 +84,13 @@ begin
hsHostingAssetTENANT(newParentAsset)] hsHostingAssetTENANT(newParentAsset)]
); );
IF NEW.type = 'DOMAIN_SETUP' THEN
END IF;
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), globalAdmin());
call leaveTriggerForObjectUuid(NEW.uuid); call leaveTriggerForObjectUuid(NEW.uuid);
end; $$; end; $$;
@ -147,114 +156,6 @@ execute procedure updateTriggerForHsHostingAsset_tf();
--// --//
-- ============================================================================
--changeset hs-hosting-asset-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
-- granting INSERT permission to global ----------------------------
/*
Grants INSERT INTO hs_hosting_asset permissions to specified role of pre-existing global rows.
*/
do language plpgsql $$
declare
row global;
begin
call defineContext('create INSERT INTO hs_hosting_asset permissions for pre-exising global rows');
FOR row IN SELECT * FROM global
-- unconditional for all rows in that table
LOOP
call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', 'hs_hosting_asset'),
globalADMIN());
END LOOP;
end;
$$;
/**
Grants hs_hosting_asset INSERT permission to specified role of new global rows.
*/
create or replace function new_hs_hosting_asset_grants_insert_to_global_tf()
returns trigger
language plpgsql
strict as $$
begin
-- unconditional for all rows in that table
call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'hs_hosting_asset'),
globalADMIN());
-- end.
return NEW;
end; $$;
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
create trigger z_new_hs_hosting_asset_grants_insert_to_global_tg
after insert on global
for each row
execute procedure new_hs_hosting_asset_grants_insert_to_global_tf();
-- 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,
-- because there cannot yet be any pre-existing rows in the same table yet.
/**
Grants hs_hosting_asset INSERT permission to specified role of new hs_hosting_asset rows.
*/
create or replace function new_hs_hosting_asset_grants_insert_to_hs_hosting_asset_tf()
returns trigger
language plpgsql
strict as $$
begin
-- unconditional for all rows in that table
call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', 'hs_hosting_asset'),
hsHostingAssetADMIN(NEW));
-- end.
return NEW;
end; $$;
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
create trigger z_new_hs_hosting_asset_grants_insert_to_hs_hosting_asset_tg
after insert on hs_hosting_asset
for each row
execute procedure new_hs_hosting_asset_grants_insert_to_hs_hosting_asset_tf();
-- ============================================================================
--changeset hs_hosting_asset-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/**
Checks if the user respectively the assumed roles are allowed to insert a row to hs_hosting_asset.
*/
create or replace function hs_hosting_asset_insert_permission_check_tf()
returns trigger
language plpgsql as $$
declare
superObjectUuid uuid;
begin
-- check INSERT INSERT if global ADMIN
if isGlobalAdmin() then
return NEW;
end if;
-- check INSERT permission via direct foreign key: NEW.parentAssetUuid
if hasInsertPermission(NEW.parentAssetUuid, 'hs_hosting_asset') then
return NEW;
end if;
raise exception '[403] insert into hs_hosting_asset values(%) not allowed for current subjects % (%)',
NEW, currentSubjects(), currentSubjectsUuids();
end; $$;
create trigger hs_hosting_asset_insert_permission_check_tg
before insert on hs_hosting_asset
for each row
execute procedure hs_hosting_asset_insert_permission_check_tf();
--//
-- ============================================================================ -- ============================================================================
--changeset hs-hosting-asset-rbac-IDENTITY-VIEW:1 endDelimiter:--// --changeset hs-hosting-asset-rbac-IDENTITY-VIEW:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------

View File

@ -27,6 +27,7 @@ import java.util.Map;
import static java.util.Map.entry; import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SETUP;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf; import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
@ -153,12 +154,39 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
null)); null));
} }
private void assertThatAssetIsPersisted(final HsHostingAssetEntity saved) { @Test
attempt(em, () -> { public void anyUser_canCreateNewDomainSetupAsset() {
// given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var assetCount = assetRepo.count();
// when
context("person-SmithPeter@example.com");
final var result = attempt(em, () -> {
final var newAsset = HsHostingAssetEntity.builder()
.caption("some new domain setup")
.type(DOMAIN_SETUP)
.identifier("example.org")
.build();
return toCleanup(assetRepo.save(newAsset));
});
// then
result.assertSuccessful();
assertThat(result.returnedValue()).isNotNull().extracting(HsHostingAssetEntity::getUuid).isNotNull();
assertThat(result.returnedValue().isLoaded()).isFalse();
context("superuser-alex@hostsharing.net");
assertThatAssetIsPersisted(result.returnedValue());
assertThat(assetRepo.count()).isEqualTo(assetCount + 1);
}
private void assertThatAssetIsPersisted(final HsHostingAssetEntity saved) {
final var context =
attempt(em, () -> {
final var found = assetRepo.findByUuid(saved.getUuid()); final var found = assetRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().map(HsHostingAssetEntity::toString).get().isEqualTo(saved.toString()); assertThat(found).isNotEmpty().map(HsHostingAssetEntity::toString).get().isEqualTo(saved.toString());
}); });
} }
} }