1
0

fix-domain-setup-rbac-grant-problems (#88)

Co-authored-by: Michael Hoennig <michael@hoennig.de>
Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/88
Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
Michael Hoennig
2024-08-15 10:38:43 +02:00
parent 0763511edd
commit 2138b3eed0
25 changed files with 317 additions and 86 deletions

View File

@ -1,11 +1,10 @@
--liquibase formatted sql
-- ============================================================================
-- RAISE-FUNCTIONS
--changeset RAISE-FUNCTIONS:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Like RAISE EXCEPTION ... just as an expression instead of a statement.
Like `RAISE EXCEPTION` ... just as an expression instead of a statement.
*/
create or replace function raiseException(msg text)
returns varchar
@ -14,3 +13,19 @@ begin
raise exception using message = msg;
end; $$;
--//
-- ============================================================================
--changeset ASSERT-FUNCTIONS:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Like `ASSERT` but as an expression instead of a statement.
*/
create or replace function assertTrue(expectedTrue boolean, msg text)
returns boolean
language plpgsql as $$
begin
assert expectedTrue, msg;
return expectedTrue;
end; $$;
--//

View File

@ -177,26 +177,35 @@ begin
sql := format($sql$
create or replace view %1$s_rv as
with accessible_%1$s_uuids as (
-- TODO.perf: this CTE query makes RBAC-SELECT-permission-queries so slow (~500ms), any idea how to optimize?
-- My guess is, that the depth of role-grants causes the problem.
with recursive grants as (
select descendantUuid, ascendantUuid, 1 as level
from RbacGrants
where assumed
and ascendantUuid = any (currentSubjectsuUids())
union all
select g.descendantUuid, g.ascendantUuid, level + 1 as level
from RbacGrants g
inner join grants on grants.descendantUuid = g.ascendantUuid
where g.assumed and level<10
)
select distinct perm.objectUuid as objectUuid
from grants
join RbacPermission perm on grants.descendantUuid = perm.uuid
join RbacObject obj on obj.uuid = perm.objectUuid
where obj.objectTable = '%1$s' -- 'SELECT' permission is included in all other permissions
limit 8001
with recursive
recursive_grants as
(select distinct rbacgrants.descendantuuid,
rbacgrants.ascendantuuid,
1 as level,
true
from rbacgrants
where rbacgrants.assumed
and (rbacgrants.ascendantuuid = any (currentsubjectsuuids()))
union all
select distinct g.descendantuuid,
g.ascendantuuid,
grants.level + 1 as level,
assertTrue(grants.level < 22, 'too many grant-levels: ' || grants.level)
from rbacgrants g
join recursive_grants grants on grants.descendantuuid = g.ascendantuuid
where g.assumed),
grant_count AS (
SELECT COUNT(*) AS grant_count FROM recursive_grants
),
count_check as (select assertTrue((select count(*) as grant_count from recursive_grants) < 400000,
'too many grants for current subjects: ' || (select count(*) as grant_count from recursive_grants))
as valid)
select distinct perm.objectuuid
from recursive_grants
join rbacpermission perm on recursive_grants.descendantuuid = perm.uuid
join rbacobject obj on obj.uuid = perm.objectuuid
join count_check cc on cc.valid
where obj.objectTable = '%1$s' -- 'SELECT' permission is included in all other permissions
)
select target.*
from %1$s as target

View File

@ -48,7 +48,7 @@ role:global:ADMIN -.-> role:debitorRel:OWNER
role:debitorRel:OWNER -.-> role:debitorRel:ADMIN
role:debitorRel:ADMIN -.-> role:debitorRel:AGENT
role:debitorRel:AGENT -.-> role:debitorRel:TENANT
role:debitorRel:AGENT ==> role:project:OWNER
role:debitorRel:AGENT ==>|XX| role:project:OWNER
role:project:OWNER ==> role:project:ADMIN
role:project:ADMIN ==> role:project:AGENT
role:project:AGENT ==> role:project:TENANT

View File

@ -49,7 +49,7 @@ begin
perform createRoleWithGrants(
hsBookingProjectOWNER(NEW),
incomingSuperRoles => array[hsOfficeRelationAGENT(newDebitorRel)]
incomingSuperRoles => array[hsOfficeRelationAGENT(newDebitorRel, unassumed())]
);
perform createRoleWithGrants(

View File

@ -49,6 +49,7 @@ subgraph assignedToAsset["`**assignedToAsset**`"]
subgraph assignedToAsset:roles[ ]
style assignedToAsset:roles fill:#99bcdb,stroke:white
role:assignedToAsset:AGENT[[assignedToAsset:AGENT]]
role:assignedToAsset:TENANT[[assignedToAsset:TENANT]]
end
end
@ -97,6 +98,7 @@ 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

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)]

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; $$;
--//