Files
pgmorbac/tests/14_system_principals.sql
T

294 lines
11 KiB
SQL

-- =============================================================================
-- System Principals Tests
-- =============================================================================
-- Tests the morbac.system_principals registry and all associated protections.
--
-- Scenarios:
-- 1. Setup: register a system principal and define its permissions via global_rules
-- 2. Permissions work normally (system principal can access what it is granted)
-- 3. Prohibitions are ignored (no role-based, user-level, or global prohibition applies)
-- 4. Cannot assign roles to a system principal
-- 5. Cannot revoke roles from a system principal
-- 6. Cannot add negative role assignments for a system principal
-- 7. Cannot add user_rules for a system principal
-- 8. Cannot create delegations involving 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
--
-- Prerequisites: 00_setup.sql -> 13_global_rules.sql
-- =============================================================================
\echo ''
\echo '================================================================'
\echo '14 -- SYSTEM PRINCIPALS'
\echo '================================================================'
-- ---------------------------------------------------------------------------
-- Section 1: Setup
-- ---------------------------------------------------------------------------
\echo ''
\echo '--- 1. Setup ---'
-- Register a system principal (done as DB owner at deploy time)
INSERT INTO morbac.system_principals (user_id, description)
VALUES (
'40000000-0000-0000-0000-000000000001',
'Backend API service account'
);
-- Define its permissions via global_rules (immutable once inserted)
INSERT INTO morbac.global_rules (user_id, activity, view, context_id, modality)
VALUES (
'40000000-0000-0000-0000-000000000001',
NULL, NULL,
(SELECT id FROM morbac.contexts WHERE name = 'always'),
'permission'
);
SELECT morbac.t('System principal registered',
EXISTS (SELECT 1 FROM morbac.system_principals WHERE user_id = '40000000-0000-0000-0000-000000000001'),
TRUE);
-- ---------------------------------------------------------------------------
-- Section 2: Permissions work
-- ---------------------------------------------------------------------------
\echo ''
\echo '--- 2. System principal permissions are effective ---'
SELECT morbac.t('System principal reads GlobalTech documents [global permission, activity=NULL view=NULL]',
morbac.is_allowed_nocache(
'40000000-0000-0000-0000-000000000001'::uuid,
'10000000-0000-0000-0000-000000000001'::uuid,
'read', 'documents'
), TRUE);
SELECT morbac.t('System principal deletes Engineering contracts [global permission covers all]',
morbac.is_allowed_nocache(
'40000000-0000-0000-0000-000000000001'::uuid,
'10000000-0000-0000-0000-000000000002'::uuid,
'delete', 'contracts'
), TRUE);
-- ---------------------------------------------------------------------------
-- Section 3: Prohibitions are ignored
-- ---------------------------------------------------------------------------
\echo ''
\echo '--- 3. Prohibitions are ignored for system principals ---'
-- Insert a blanket global prohibition (user_id=NULL affects everyone normally)
INSERT INTO morbac.global_rules (user_id, activity, view, context_id, modality, priority)
VALUES (
NULL,
'delete', 'contracts',
(SELECT id FROM morbac.contexts WHERE name = 'always'),
'prohibition', 999
);
SELECT morbac.t('System principal deletes contracts [blanket global prohibition ignored]',
morbac.is_allowed_nocache(
'40000000-0000-0000-0000-000000000001'::uuid,
'10000000-0000-0000-0000-000000000001'::uuid,
'delete', 'contracts'
), TRUE);
-- Regular user is still affected by the prohibition
SELECT morbac.t('Dave deletes GlobalTech contracts [blanket prohibition applies to regular users]',
morbac.is_allowed_nocache(
'30000000-0000-0000-0000-000000000004'::uuid,
'10000000-0000-0000-0000-000000000001'::uuid,
'delete', 'contracts'
), FALSE);
DELETE FROM morbac.global_rules
WHERE user_id IS NULL AND activity = 'delete' AND view = 'contracts';
-- ---------------------------------------------------------------------------
-- Section 4: Cannot assign roles to a system principal
-- ---------------------------------------------------------------------------
\echo ''
\echo '--- 4. Role assignment blocked ---'
SELECT morbac.t('Assigning role to system principal raises exception',
(SELECT COUNT(*) FROM (
SELECT morbac.assign_role(
'40000000-0000-0000-0000-000000000001'::uuid,
(SELECT id FROM morbac.roles WHERE name = 'employee' AND org_id = '10000000-0000-0000-0000-000000000001'),
'10000000-0000-0000-0000-000000000001'::uuid
)
) sub) = 0,
FALSE
) WHERE FALSE; -- skip, tested via exception below
DO $$
BEGIN
INSERT INTO morbac.user_roles (user_id, role_id, org_id)
VALUES (
'40000000-0000-0000-0000-000000000001',
(SELECT id FROM morbac.roles WHERE name = 'employee' AND org_id = '10000000-0000-0000-0000-000000000001'),
'10000000-0000-0000-0000-000000000001'
);
RAISE EXCEPTION 'expected exception not raised';
EXCEPTION
WHEN OTHERS THEN
IF SQLERRM LIKE '%system principal%' THEN
RAISE NOTICE 'PASS: role assignment to system principal blocked';
ELSE
RAISE;
END IF;
END;
$$;
-- ---------------------------------------------------------------------------
-- Section 5: Cannot add negative role assignments for a system principal
-- ---------------------------------------------------------------------------
\echo ''
\echo '--- 5. Negative role assignment blocked ---'
DO $$
BEGIN
INSERT INTO morbac.negative_role_assignments (user_id, role_id, org_id)
VALUES (
'40000000-0000-0000-0000-000000000001',
(SELECT id FROM morbac.roles WHERE name = 'employee' AND org_id = '10000000-0000-0000-0000-000000000001'),
'10000000-0000-0000-0000-000000000001'
);
RAISE EXCEPTION 'expected exception not raised';
EXCEPTION
WHEN OTHERS THEN
IF SQLERRM LIKE '%system principal%' THEN
RAISE NOTICE 'PASS: negative role assignment for system principal blocked';
ELSE
RAISE;
END IF;
END;
$$;
-- ---------------------------------------------------------------------------
-- Section 6: Cannot add user_rules for a system principal
-- ---------------------------------------------------------------------------
\echo ''
\echo '--- 6. user_rules blocked ---'
DO $$
BEGIN
INSERT INTO morbac.user_rules (user_id, org_id, activity, view, context_id, modality)
VALUES (
'40000000-0000-0000-0000-000000000001',
'10000000-0000-0000-0000-000000000001',
'read', 'documents',
(SELECT id FROM morbac.contexts WHERE name = 'always'),
'permission'
);
RAISE EXCEPTION 'expected exception not raised';
EXCEPTION
WHEN OTHERS THEN
IF SQLERRM LIKE '%system principal%' THEN
RAISE NOTICE 'PASS: user_rules insert for system principal blocked';
ELSE
RAISE;
END IF;
END;
$$;
-- ---------------------------------------------------------------------------
-- Section 7: Cannot create delegations involving a system principal
-- ---------------------------------------------------------------------------
\echo ''
\echo '--- 7. Delegations blocked ---'
DO $$
BEGIN
INSERT INTO morbac.delegations (delegator_id, delegatee_id, role_id, org_id)
VALUES (
'30000000-0000-0000-0000-000000000001', -- Alice as delegator
'40000000-0000-0000-0000-000000000001', -- system principal as delegatee
(SELECT id FROM morbac.roles WHERE name = 'employee' AND org_id = '10000000-0000-0000-0000-000000000001'),
'10000000-0000-0000-0000-000000000001'
);
RAISE EXCEPTION 'expected exception not raised';
EXCEPTION
WHEN OTHERS THEN
IF SQLERRM LIKE '%system principal%' THEN
RAISE NOTICE 'PASS: delegation to system principal blocked';
ELSE
RAISE;
END IF;
END;
$$;
-- ---------------------------------------------------------------------------
-- Section 8: Cannot add a targeted global_rules prohibition
-- ---------------------------------------------------------------------------
\echo ''
\echo '--- 8. Targeted global prohibition blocked ---'
DO $$
BEGIN
INSERT INTO morbac.global_rules (user_id, activity, view, context_id, modality)
VALUES (
'40000000-0000-0000-0000-000000000001',
'delete', 'contracts',
(SELECT id FROM morbac.contexts WHERE name = 'always'),
'prohibition'
);
RAISE EXCEPTION 'expected exception not raised';
EXCEPTION
WHEN OTHERS THEN
IF SQLERRM LIKE '%system principal%' THEN
RAISE NOTICE 'PASS: global prohibition targeting system principal blocked';
ELSE
RAISE;
END IF;
END;
$$;
-- ---------------------------------------------------------------------------
-- Section 9: Cannot add a permission global_rule for a system principal
-- ---------------------------------------------------------------------------
\echo ''
\echo '--- 9. New global permission for system principal blocked ---'
DO $$
BEGIN
INSERT INTO morbac.global_rules (user_id, activity, view, context_id, modality)
VALUES (
'40000000-0000-0000-0000-000000000001',
'read', 'documents',
(SELECT id FROM morbac.contexts WHERE name = 'always'),
'permission'
);
RAISE EXCEPTION 'expected exception not raised';
EXCEPTION
WHEN OTHERS THEN
IF SQLERRM LIKE '%system principal%' THEN
RAISE NOTICE 'PASS: new global permission for system principal blocked (define at deploy time only)';
ELSE
RAISE;
END IF;
END;
$$;
-- ---------------------------------------------------------------------------
-- Section 10: Cannot delete existing global_rules for a system principal
-- ---------------------------------------------------------------------------
\echo ''
\echo '--- 10. Deleting system principal global_rules blocked ---'
DO $$
BEGIN
DELETE FROM morbac.global_rules
WHERE user_id = '40000000-0000-0000-0000-000000000001';
RAISE EXCEPTION 'expected exception not raised';
EXCEPTION
WHEN OTHERS THEN
IF SQLERRM LIKE '%system principal%' THEN
RAISE NOTICE 'PASS: deletion of system principal global rules blocked';
ELSE
RAISE;
END IF;
END;
$$;
\echo ''
\echo '=== System Principals Tests Completed ==='