fix(authorization): system principal regretion
This commit is contained in:
@@ -851,7 +851,7 @@ WHERE table_name = 'rules'
|
|||||||
|
|
||||||
### Authorization Functions
|
### Authorization Functions
|
||||||
|
|
||||||
**`is_allowed(user_id, org_id, activity, view)`**: Main authorization decision. Returns BOOLEAN. Evaluates local rules, cross-org rules, user rules, and global rules; defaults to deny.
|
**`is_allowed(user_id, org_id, activity, view)`**: Main authorization decision. Returns BOOLEAN. Evaluates local rules, cross-org rules, user rules, and global rules; defaults to deny. Cache writes are silently skipped in read-only transactions so this function is safe to call from both read-write and read-only contexts (e.g. PostgREST GET requests).
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SELECT morbac.is_allowed(user_uuid, org_uuid, 'read', 'documents');
|
SELECT morbac.is_allowed(user_uuid, org_uuid, 'read', 'documents');
|
||||||
|
|||||||
@@ -32,10 +32,11 @@ DECLARE
|
|||||||
v_rule RECORD;
|
v_rule RECORD;
|
||||||
v_max_prohibition_priority INTEGER := NULL;
|
v_max_prohibition_priority INTEGER := NULL;
|
||||||
v_max_permission_priority INTEGER := NULL;
|
v_max_permission_priority INTEGER := NULL;
|
||||||
v_is_system_principal BOOLEAN := FALSE;
|
v_is_system_principal BOOLEAN;
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT TRUE INTO v_is_system_principal
|
v_is_system_principal := EXISTS (
|
||||||
FROM morbac.system_principals WHERE user_id = p_user_id;
|
SELECT 1 FROM morbac.system_principals WHERE user_id = p_user_id
|
||||||
|
);
|
||||||
|
|
||||||
-- STEPS 1-3.5: Prohibitions — skipped entirely for system principals
|
-- STEPS 1-3.5: Prohibitions — skipped entirely for system principals
|
||||||
IF NOT v_is_system_principal THEN
|
IF NOT v_is_system_principal THEN
|
||||||
@@ -244,6 +245,7 @@ BEGIN
|
|||||||
|
|
||||||
v_computed_result := morbac.is_allowed_nocache(p_user_id, p_org_id, p_activity, p_view);
|
v_computed_result := morbac.is_allowed_nocache(p_user_id, p_org_id, p_activity, p_view);
|
||||||
|
|
||||||
|
BEGIN
|
||||||
INSERT INTO morbac.auth_cache (user_id, org_id, activity, view, allowed, expires_at)
|
INSERT INTO morbac.auth_cache (user_id, org_id, activity, view, allowed, expires_at)
|
||||||
VALUES (
|
VALUES (
|
||||||
p_user_id,
|
p_user_id,
|
||||||
@@ -257,6 +259,9 @@ BEGIN
|
|||||||
SET allowed = v_computed_result,
|
SET allowed = v_computed_result,
|
||||||
computed_at = CURRENT_TIMESTAMP,
|
computed_at = CURRENT_TIMESTAMP,
|
||||||
expires_at = CURRENT_TIMESTAMP + make_interval(secs => morbac.get_config('cache_ttl_seconds')::integer);
|
expires_at = CURRENT_TIMESTAMP + make_interval(secs => morbac.get_config('cache_ttl_seconds')::integer);
|
||||||
|
EXCEPTION WHEN read_only_sql_transaction THEN
|
||||||
|
NULL;
|
||||||
|
END;
|
||||||
|
|
||||||
RETURN v_computed_result;
|
RETURN v_computed_result;
|
||||||
END;
|
END;
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
-- 8. Cannot create delegations involving a system principal
|
-- 8. Cannot create delegations involving a system principal
|
||||||
-- 9. Cannot add a targeted global_rules prohibition for a system principal
|
-- 9. Cannot add a targeted global_rules prohibition for a system principal
|
||||||
-- 10. Cannot modify or delete existing global_rules for a system principal
|
-- 10. Cannot modify or delete existing global_rules for a system principal
|
||||||
|
-- 11. Prohibitions apply to regular users (system principal bypass is not global)
|
||||||
|
-- 12. is_allowed() works correctly in read-only transactions
|
||||||
--
|
--
|
||||||
-- Prerequisites: 00_setup.sql -> 13_global_rules.sql
|
-- Prerequisites: 00_setup.sql -> 13_global_rules.sql
|
||||||
-- =============================================================================
|
-- =============================================================================
|
||||||
@@ -289,5 +291,54 @@ EXCEPTION
|
|||||||
END;
|
END;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- Section 11: Prohibitions apply to regular users, not just system principals
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
\echo ''
|
||||||
|
\echo '--- 11. Prohibitions apply to regular users ---'
|
||||||
|
|
||||||
|
INSERT INTO morbac.global_rules (user_id, activity, view, context_id, modality, priority)
|
||||||
|
VALUES (
|
||||||
|
NULL,
|
||||||
|
'delete', 'documents',
|
||||||
|
(SELECT id FROM morbac.contexts WHERE name = 'always'),
|
||||||
|
'prohibition', 100
|
||||||
|
);
|
||||||
|
|
||||||
|
SELECT morbac.t('Dave deletes GlobalTech documents [blanket prohibition must apply to non-system users]',
|
||||||
|
morbac.is_allowed_nocache(
|
||||||
|
'30000000-0000-0000-0000-000000000004'::uuid,
|
||||||
|
'10000000-0000-0000-0000-000000000001'::uuid,
|
||||||
|
'delete', 'documents'
|
||||||
|
), FALSE);
|
||||||
|
|
||||||
|
SELECT morbac.t('System principal deletes GlobalTech documents [prohibition still bypassed]',
|
||||||
|
morbac.is_allowed_nocache(
|
||||||
|
'40000000-0000-0000-0000-000000000001'::uuid,
|
||||||
|
'10000000-0000-0000-0000-000000000001'::uuid,
|
||||||
|
'delete', 'documents'
|
||||||
|
), TRUE);
|
||||||
|
|
||||||
|
DELETE FROM morbac.global_rules
|
||||||
|
WHERE user_id IS NULL AND activity = 'delete' AND view = 'documents';
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- Section 12: is_allowed() works in read-only transactions
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
\echo ''
|
||||||
|
\echo '--- 12. is_allowed() in read-only transactions ---'
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
SET TRANSACTION READ ONLY;
|
||||||
|
|
||||||
|
SELECT morbac.t('is_allowed() returns correct result in read-only transaction',
|
||||||
|
morbac.is_allowed(
|
||||||
|
'30000000-0000-0000-0000-000000000004'::uuid,
|
||||||
|
'10000000-0000-0000-0000-000000000001'::uuid,
|
||||||
|
'read', 'public_data'
|
||||||
|
), TRUE);
|
||||||
|
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
\echo ''
|
\echo ''
|
||||||
\echo '=== System Principals Tests Completed ==='
|
\echo '=== System Principals Tests Completed ==='
|
||||||
|
|||||||
Reference in New Issue
Block a user