make EMail-Addresses visible to webspace agent by granting asset:AGENT to assignedToAsset:AGENT

This commit is contained in:
Michael Hoennig 2024-08-14 12:30:46 +02:00
parent dfb123dd00
commit e9b6ca3d9c
10 changed files with 69 additions and 61 deletions

View File

@ -123,26 +123,20 @@ select
from one_path;
commit transaction;
select * from
(
select uuid, roleidname as name from rbacrole_ev
union all
select uuid, p.optablename || ':' || p.objectuuid || ':' || p.op as name from rbacpermission p
) united
where uuid in (
'4157915c-a09b-490c-9430-00005fcfbb4f',
'046f2da0-66d5-4e6a-af17-d41fba617b30',
'6239ca11-5224-401d-9780-1af7f5cbf35a',
'70004958-39c7-4d32-8ba6-d78145f3ad32',
'7065fbc1-c605-4da3-97dd-f40fe1b90b4c',
'd551551b-b1dd-414a-a0ed-a07712f15e62',
'f1f0fc3e-020a-48fe-b9c1-ac495cc21fdf',
'63ad71f3-214c-411e-8b0b-a859e54af770',
'561bbe75-b8f2-4e4b-86ac-02a72ab9a6e8',
'379e99b3-b53f-421d-a53e-2e81c464fbf2',
'5cb1ecb2-7962-47e0-b8bf-67974da45208'
);
with grants as (
select uuid
from rbacgrants
where descendantuuid in (
select uuid
from rbacrole
where objectuuid in (
select uuid
from hs_hosting_asset
-- where type = 'DOMAIN_MBOX_SETUP'
-- and identifier = 'example.org|MBOX'
where type = 'EMAIL_ADDRESS'
and identifier='test@example.org'
))
)
select * from rbacgrants_ev gev where exists ( select uuid from grants where gev.uuid = grants.uuid );

View File

@ -185,6 +185,7 @@ public class HsHostingAssetEntity implements HsHostingAsset {
with.permission(UPDATE);
})
.createSubRole(AGENT, (with) -> {
with.incomingSuperRole("assignedToAsset", AGENT); // TODO.spec: or ADMIN?
with.outgoingSubRole("assignedToAsset", TENANT);
with.outgoingSubRole("alarmContact", REFERRER);
})
@ -192,9 +193,6 @@ public class HsHostingAssetEntity implements HsHostingAsset {
with.outgoingSubRole("bookingItem", TENANT);
with.outgoingSubRole("parentAsset", TENANT);
with.incomingSuperRole("alarmContact", ADMIN);
})
.createSubRole(REFERRER, (with) -> {
with.incomingSuperRole("assignedToAsset", AGENT);
with.permission(SELECT);
})

View File

@ -215,7 +215,7 @@ public class RbacGrantsDiagramService {
@NotNull
private static String cleanId(final String idName) {
return idName.replaceAll("@.*", "")
.replace("[", "").replace("]", "").replace("(", "").replace(")", "").replace(",", "").replace(">", ":");
.replace("[", "").replace("]", "").replace("(", "").replace(")", "").replace(",", "").replace(">", ":").replace("|", "_");
}

View File

@ -30,7 +30,6 @@ subgraph asset["`**asset**`"]
role:asset:ADMIN[[asset:ADMIN]]
role:asset:AGENT[[asset:AGENT]]
role:asset:TENANT[[asset:TENANT]]
role:asset:REFERRER[[asset:REFERRER]]
end
subgraph asset:permissions[ ]
@ -50,8 +49,8 @@ subgraph assignedToAsset["`**assignedToAsset**`"]
subgraph assignedToAsset:roles[ ]
style assignedToAsset:roles fill:#99bcdb,stroke:white
role:assignedToAsset:TENANT[[assignedToAsset:TENANT]]
role:assignedToAsset:AGENT[[assignedToAsset:AGENT]]
role:assignedToAsset:TENANT[[assignedToAsset:TENANT]]
end
end
@ -99,14 +98,13 @@ role:asset:OWNER ==> role:asset:ADMIN
role:bookingItem:AGENT ==> role:asset:ADMIN
role:parentAsset:AGENT ==> role:asset:ADMIN
role:asset:ADMIN ==> role:asset:AGENT
role:assignedToAsset:AGENT ==> role:asset:AGENT
role:asset:AGENT ==> role:assignedToAsset:TENANT
role:asset:AGENT ==> role:alarmContact:REFERRER
role:asset:AGENT ==> role:asset:TENANT
role:asset:TENANT ==> role:bookingItem:TENANT
role:asset:TENANT ==> role:parentAsset:TENANT
role:alarmContact:ADMIN ==> role:asset:TENANT
role:asset:TENANT ==> role:asset:REFERRER
role:assignedToAsset:AGENT ==> role:asset:REFERRER
%% granting permissions to roles
role:global:ADMIN ==> perm:asset:INSERT
@ -114,6 +112,6 @@ role:parentAsset:ADMIN ==> perm:asset:INSERT
role:global:GUEST ==> perm:asset:INSERT
role:asset:OWNER ==> perm:asset:DELETE
role:asset:ADMIN ==> perm:asset:UPDATE
role:asset:REFERRER ==> perm:asset:SELECT
role:asset:TENANT ==> perm:asset:SELECT
```

View File

@ -67,7 +67,9 @@ begin
perform createRoleWithGrants(
hsHostingAssetAGENT(NEW),
incomingSuperRoles => array[hsHostingAssetADMIN(NEW)],
incomingSuperRoles => array[
hsHostingAssetADMIN(NEW),
hsHostingAssetAGENT(newAssignedToAsset)],
outgoingSubRoles => array[
hsHostingAssetTENANT(newAssignedToAsset),
hsOfficeContactREFERRER(newAlarmContact)]
@ -75,6 +77,7 @@ begin
perform createRoleWithGrants(
hsHostingAssetTENANT(NEW),
permissions => array['SELECT'],
incomingSuperRoles => array[
hsHostingAssetAGENT(NEW),
hsOfficeContactADMIN(newAlarmContact)],
@ -83,14 +86,6 @@ begin
hsHostingAssetTENANT(newParentAsset)]
);
perform createRoleWithGrants(
hsHostingAssetREFERRER(NEW),
permissions => array['SELECT'],
incomingSuperRoles => array[
hsHostingAssetAGENT(newAssignedToAsset),
hsHostingAssetTENANT(NEW)]
);
IF NEW.type = 'DOMAIN_SETUP' THEN
END IF;

View File

@ -23,6 +23,7 @@ declare
managedServerUuid uuid;
managedWebspaceUuid uuid;
webUnixUserUuid uuid;
mboxUnixUserUuid uuid;
domainSetupUuid uuid;
domainMBoxSetupUuid uuid;
mariaDbInstanceUuid uuid;
@ -71,6 +72,7 @@ begin
select uuid_generate_v4() into managedServerUuid;
select uuid_generate_v4() into managedWebspaceUuid;
select uuid_generate_v4() into webUnixUserUuid;
select uuid_generate_v4() into mboxUnixUserUuid;
select uuid_generate_v4() into domainSetupUuid;
select uuid_generate_v4() into domainMBoxSetupUuid;
select uuid_generate_v4() into mariaDbInstanceUuid;
@ -94,11 +96,12 @@ begin
(uuid_generate_v4(), null, 'PGSQL_DATABASE', pgSqlUserUuid, pgSqlInstanceUuid, defaultPrefix || '01_web', 'some default Postgresql database','{ "encryption": "utf8", "collation": "utf8"}'::jsonb ),
(uuid_generate_v4(), null, 'EMAIL_ALIAS', managedWebspaceUuid, null, defaultPrefix || '01-web', 'some E-Mail-Alias', '{ "target": [ "office@example.org", "archive@example.com" ] }'::jsonb),
(webUnixUserUuid, null, 'UNIX_USER', managedWebspaceUuid, null, defaultPrefix || '01-web', 'some UnixUser for Website', '{ "SSD-soft-quota": "128", "SSD-hard-quota": "256", "HDD-soft-quota": "512", "HDD-hard-quota": "1024"}'::jsonb),
(mboxUnixUserUuid, null, 'UNIX_USER', managedWebspaceUuid, null, defaultPrefix || '01-mbox', 'some UnixUser for E-Mail', '{ "SSD-soft-quota": "128", "SSD-hard-quota": "256", "HDD-soft-quota": "512", "HDD-hard-quota": "1024"}'::jsonb),
(domainSetupUuid, null, 'DOMAIN_SETUP', null, null, defaultPrefix || '.example.org', 'some Domain-Setup', '{}'::jsonb),
(uuid_generate_v4(), null, 'DOMAIN_DNS_SETUP', domainSetupUuid, null, defaultPrefix || '.example.org|DNS', 'some Domain-DNS-Setup', '{}'::jsonb),
(uuid_generate_v4(), null, 'DOMAIN_HTTP_SETUP', domainSetupUuid, webUnixUserUuid, defaultPrefix || '.example.org|HTTP', 'some Domain-HTTP-Setup', '{ "option-htdocsfallback": true, "use-fcgiphpbin": "/usr/lib/cgi-bin/php", "validsubdomainnames": "*"}'::jsonb),
(uuid_generate_v4(), null, 'DOMAIN_SMTP_SETUP', domainSetupUuid, managedWebspaceUuid, defaultPrefix || '.example.org|DNS', 'some Domain-SMPT-Setup', '{}'::jsonb),
(domainMBoxSetupUuid, null, 'DOMAIN_MBOX_SETUP', domainSetupUuid, managedWebspaceUuid, defaultPrefix || '.example.org|DNS', 'some Domain-MBOX-Setup', '{}'::jsonb),
(uuid_generate_v4(), null, 'DOMAIN_SMTP_SETUP', domainSetupUuid, managedWebspaceUuid, defaultPrefix || '.example.org|SMTP', 'some Domain-SMTP-Setup', '{}'::jsonb),
(domainMBoxSetupUuid, null, 'DOMAIN_MBOX_SETUP', domainSetupUuid, managedWebspaceUuid, defaultPrefix || '.example.org|MBOX', 'some Domain-MBOX-Setup', '{}'::jsonb),
(uuid_generate_v4(), null, 'EMAIL_ADDRESS', domainMBoxSetupUuid, null, 'test@' || defaultPrefix || '.example.org', 'some E-Mail-Address', '{}'::jsonb);
end; $$;
--//

View File

@ -324,10 +324,12 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
assertThat(givenHostingAsset.getBookingItem().getResources().get("Multi"))
.as("precondition failed")
.isEqualTo(1);
final var preExistingUnixUserCount = assetRepo.findAllByCriteria(null, givenHostingAsset.getUuid(), UNIX_USER).size();
final var UNIX_USER_PER_MULTI_OPTION = 25;
jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
for (int n = 0; n < 25; ++n) {
for (int n = 0; n < UNIX_USER_PER_MULTI_OPTION -preExistingUnixUserCount+1; ++n) {
toCleanup(assetRepo.save(
HsHostingAssetEntity.builder()
.type(UNIX_USER)

View File

@ -6,6 +6,7 @@ import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
import net.hostsharing.hsadminng.mapper.Array;
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
@ -28,6 +29,7 @@ import java.util.Map;
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.DOMAIN_SETUP;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.EMAIL_ADDRESS;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
@ -125,8 +127,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
"hs_hosting_asset#fir00:ADMIN",
"hs_hosting_asset#fir00:AGENT",
"hs_hosting_asset#fir00:OWNER",
"hs_hosting_asset#fir00:TENANT",
"hs_hosting_asset#fir00:REFERRER"));
"hs_hosting_asset#fir00:TENANT"));
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll()))
.containsExactlyInAnyOrder(fromFormatted(
initialGrantNames,
@ -153,10 +154,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
"{ grant role:hs_booking_item#fir01:TENANT to role:hs_hosting_asset#fir00:TENANT by system and assume }",
"{ grant role:hs_hosting_asset#fir00:TENANT to role:hs_hosting_asset#fir00:AGENT by system and assume }",
"{ grant role:hs_hosting_asset#vm1011:TENANT to role:hs_hosting_asset#fir00:TENANT by system and assume }",
// referrer
"{ grant perm:hs_hosting_asset#fir00:SELECT to role:hs_hosting_asset#fir00:REFERRER by system and assume }",
"{ grant role:hs_hosting_asset#fir00:REFERRER to role:hs_hosting_asset#fir00:TENANT by system and assume }",
"{ grant perm:hs_hosting_asset#fir00:SELECT to role:hs_hosting_asset#fir00:TENANT by system and assume }",
null));
}
@ -199,7 +197,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
}
@Nested
class FindByDebitorUuid {
class FindAssets {
@Test
public void globalAdmin_withoutAssumedRole_canViewArbitraryAssetsOfAllDebitors() {
@ -218,7 +216,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
}
@Test
public void normalUser_canViewOnlyRelatedAsset() {
public void normalUser_canViewOnlyRelatedAssets() {
// given:
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT");
final var projectUuid = projectRepo.findByCaption("D-1000111 default project").stream()
@ -235,7 +233,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
}
@Test
public void normalUser_canFilterAssetsRelatedToParentAsset() {
public void managedServerAgent_canFindAssetsRelatedToManagedServer() {
// given
context("superuser-alex@hostsharing.net");
final var parentAssetUuid = assetRepo.findByIdentifier("vm1012").stream()
@ -253,6 +251,32 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
"HsHostingAssetEntity(MARIADB_INSTANCE, vm1012.MariaDB.default, some default MariaDB instance, MANAGED_SERVER:vm1012)",
"HsHostingAssetEntity(PGSQL_INSTANCE, vm1012.Postgresql.default, some default Postgresql instance, MANAGED_SERVER:vm1012)");
}
@Test
public void managedServerAgent_canFindRelatedEmailAddresses() {
// given
context("superuser-alex@hostsharing.net");
// FIXME: remove
// final var parentAssetUuid = assetRepo.findByIdentifier("vm1012").stream()
// .filter(ha -> ha.getType() == MANAGED_SERVER)
// .findAny().orElseThrow().getUuid();
// when
// context("superuser-alex@hostsharing.net", "hs_hosting_asset#vm1012:AGENT");
context("superuser-alex@hostsharing.net", "hs_hosting_asset#sec01:AGENT");
// FIXME: cleanup
// context("superuser-alex@hostsharing.net", "hs_hosting_asset#sec.example.org|MBOX:AGENT");
// context("superuser-alex@hostsharing.net", "hs_booking_project#D-1000212-D-1000212defaultproject:AGENT");
generateRbacDiagramForCurrentSubjects(RbacGrantsDiagramService.Include.ALL_NON_TEST_ENTITY_RELATED, "should-contain-email-addresses");
final var result = assetRepo.findAllByCriteria(null, null, EMAIL_ADDRESS);
// then
exactlyTheseAssetsAreReturned(
result,
"HsHostingAssetEntity(EMAIL_ADDRESS, test@sec.example.org, some E-Mail-Address, DOMAIN_MBOX_SETUP:sec.example.org|MBOX)");
}
}
@Nested

View File

@ -928,17 +928,11 @@ public class ImportHostingAssets extends ImportOfficeData {
assumeThatWeAreImportingControlledTestData();
final var haCount = jpaAttempt.transacted(() -> {
context(rbacSuperuser);
// final var roles = em.createNativeQuery("select * from rbacrole_ev where roleidname like 'hs_office_relation%with-DEBITOR%'").getResultList();
final var roles = em.createNativeQuery("select * from rbacrole_ev where roleidname like 'hs_booking_project#D-10003%'").getResultList();
//context(rbacSuperuser, "hs_booking_project#D-1000300-mimdefaultproject:ADMIN");
context(rbacSuperuser, "hs_booking_project#D-1000300-mimdefaultproject:AGENT");
final var result = em.createNativeQuery("select * from hs_hosting_asset where type='EMAIL_ADDRESS'")
.getResultList();
return (Integer) em.createNativeQuery("select count(*) from hs_hosting_asset where type='EMAIL_ADDRESS'", Integer.class)
return (Integer) em.createNativeQuery("select count(*) from hs_hosting_asset_rv where type='EMAIL_ADDRESS'", Integer.class)
.getSingleResult();
}).assertSuccessful().returnedValue();
assertThat(haCount).isEqualTo(71);
assertThat(haCount).isEqualTo(68);
}
// ============================================================================================