HR-ATS-Portal/backend/migrations/manual/005_tasks_rbac_restrict.sql

62 lines
2.5 KiB
SQL

-- 005_tasks_rbac_restrict.sql
-- Manual one-shot: restrict task CREATION in the permission database to
-- system_administrator / hr_administrator / recruiter. 004 attached the full
-- tasks_management bundle (all 8 tags) to six roles; here hiring_manager,
-- department_head and ceo swap it for a view-only bundle so the permission DB
-- itself says who may create — the tasks service additionally enforces the
-- creator-role check at request time. Idempotent; auto-applied at startup by
-- alembic_setup.run_manual_sql().
-- =============================================================================
-- 1. View-only bundle (tasks.view, tasks.export)
-- =============================================================================
INSERT INTO app.permissions (name, description, permission_tags, is_system, created_at, updated_at, is_active, is_deleted)
SELECT
'tasks_viewer',
'Recruiting task list: read-only access',
(
SELECT COALESCE(jsonb_agg(id ORDER BY id), '[]'::jsonb)
FROM app.permission_tags
WHERE is_deleted = false
AND tag_name IN ('tasks.view', 'tasks.export')
),
true,
NOW(),
NOW(),
true,
false
WHERE NOT EXISTS (
SELECT 1 FROM app.permissions WHERE name = 'tasks_viewer'
);
-- =============================================================================
-- 2. Remove the full tasks_management bundle from the non-creator roles
-- (jsonb arrays hold numbers, so `-` text removal does not apply — rebuild)
-- =============================================================================
UPDATE app.roles r
SET permissions = (
SELECT COALESCE(jsonb_agg(elem), '[]'::jsonb)
FROM jsonb_array_elements(COALESCE(r.permissions, '[]'::jsonb)) elem
WHERE elem <> to_jsonb(p.id)
),
updated_at = NOW()
FROM app.permissions p
WHERE p.name = 'tasks_management'
AND r.role_name IN ('hiring_manager', 'department_head', 'ceo')
AND COALESCE(r.permissions, '[]'::jsonb) @> jsonb_build_array(p.id);
-- =============================================================================
-- 3. Attach the view-only bundle to those roles
-- =============================================================================
UPDATE app.roles r
SET permissions = COALESCE(r.permissions, '[]'::jsonb) || jsonb_build_array(p.id),
updated_at = NOW()
FROM app.permissions p
WHERE p.name = 'tasks_viewer'
AND r.role_name IN (
'hiring_manager',
'department_head',
'ceo'
)
AND NOT (COALESCE(r.permissions, '[]'::jsonb) @> jsonb_build_array(p.id));