espace-paie-odentas/scripts/verify-rls-policies.sql

172 lines
5.2 KiB
SQL

-- Script de vérification des politiques RLS
-- Date : 16 octobre 2025
-- Objectif : Vérifier que les politiques RLS sont correctement configurées
-- 1. Vérifier que RLS est activé sur les tables critiques
SELECT
schemaname,
tablename,
rowsecurity AS "RLS Activé"
FROM pg_tables
WHERE schemaname = 'public'
AND tablename IN ('cddu_contracts', 'payslips', 'organizations', 'organization_members')
ORDER BY tablename;
-- 2. Lister toutes les politiques existantes
SELECT
schemaname,
tablename,
policyname AS "Nom de la politique",
permissive AS "Permissive",
roles AS "Rôles",
cmd AS "Commande",
qual AS "Condition WHERE"
FROM pg_policies
WHERE schemaname = 'public'
AND tablename IN ('cddu_contracts', 'payslips', 'organizations', 'organization_members')
ORDER BY tablename, policyname;
-- 3. Vérifier les politiques manquantes critiques
-- Ces politiques doivent exister pour sécuriser l'accès
-- Pour cddu_contracts :
-- - Une politique SELECT pour les clients (accès uniquement à leur org)
-- - Une politique UPDATE pour les clients (modification uniquement leur org)
-- - Une politique INSERT pour les clients (création uniquement dans leur org)
-- - Une politique pour service_role (accès global staff)
-- Pour payslips :
-- - Une politique SELECT pour les clients (accès uniquement à leur org)
-- - Une politique pour service_role (accès global staff)
-- 4. Test de sécurité : Essayer d'accéder à toutes les lignes (doit être filtré par RLS)
-- ⚠️ À exécuter en tant qu'utilisateur authenticated (pas service_role)
-- SELECT COUNT(*) FROM cddu_contracts; -- Doit retourner uniquement les contrats de l'org de l'utilisateur
-- SELECT COUNT(*) FROM payslips; -- Doit retourner uniquement les paies de l'org de l'utilisateur
-- 5. Recommandations de politiques à créer si absentes :
/*
-- Politique SELECT pour cddu_contracts (clients)
CREATE POLICY "clients_select_own_org_contracts"
ON public.cddu_contracts
FOR SELECT
TO authenticated
USING (
org_id IN (
SELECT org_id
FROM public.organization_members
WHERE user_id = auth.uid()
)
);
-- Politique UPDATE pour cddu_contracts (clients)
CREATE POLICY "clients_update_own_org_contracts"
ON public.cddu_contracts
FOR UPDATE
TO authenticated
USING (
org_id IN (
SELECT org_id
FROM public.organization_members
WHERE user_id = auth.uid()
)
);
-- Politique INSERT pour cddu_contracts (clients)
CREATE POLICY "clients_insert_own_org_contracts"
ON public.cddu_contracts
FOR INSERT
TO authenticated
WITH CHECK (
org_id IN (
SELECT org_id
FROM public.organization_members
WHERE user_id = auth.uid()
)
);
-- Politique DELETE pour cddu_contracts (clients)
CREATE POLICY "clients_delete_own_org_contracts"
ON public.cddu_contracts
FOR DELETE
TO authenticated
USING (
org_id IN (
SELECT org_id
FROM public.organization_members
WHERE user_id = auth.uid()
)
);
-- Politique ALL pour service_role (staff avec admin client)
CREATE POLICY "service_role_all_access_contracts"
ON public.cddu_contracts
FOR ALL
TO service_role
USING (true)
WITH CHECK (true);
-- Politique SELECT pour payslips (clients)
CREATE POLICY "clients_select_own_org_payslips"
ON public.payslips
FOR SELECT
TO authenticated
USING (
organization_id IN (
SELECT org_id
FROM public.organization_members
WHERE user_id = auth.uid()
)
);
-- Politique ALL pour service_role (staff)
CREATE POLICY "service_role_all_access_payslips"
ON public.payslips
FOR ALL
TO service_role
USING (true)
WITH CHECK (true);
*/
-- 6. Vérifier les index pour performance
SELECT
schemaname,
tablename,
indexname,
indexdef
FROM pg_indexes
WHERE schemaname = 'public'
AND tablename IN ('cddu_contracts', 'payslips', 'organization_members')
AND (indexdef LIKE '%org_id%' OR indexdef LIKE '%organization_id%' OR indexdef LIKE '%user_id%')
ORDER BY tablename, indexname;
-- ✅ Résultat de la vérification (16 octobre 2025) :
--
-- cddu_contracts:
-- ✅ cddu_contracts_org_id_contract_number_key (UNIQUE sur org_id + contract_number)
-- ✅ cddu_contracts_org_idx (INDEX sur org_id)
--
-- payslips:
-- ✅ idx_payslips_org_month (INDEX sur organization_id + period_month)
-- ✅ idx_payslips_organization_id (INDEX sur organization_id)
--
-- organization_members:
-- ✅ organization_members_pkey (UNIQUE PRIMARY KEY sur org_id + user_id)
-- ✅ idx_members_org (INDEX sur org_id)
-- ✅ idx_members_user (INDEX sur user_id)
-- ✅ idx_om_org_revoked (INDEX sur org_id + revoked)
-- ✅ idx_om_org_user (INDEX sur org_id + user_id)
-- ✅ idx_om_user (INDEX sur user_id)
-- ✅ idx_org_members_org (INDEX sur org_id)
-- ✅ idx_org_members_org_revoked (INDEX sur org_id + revoked)
-- ✅ idx_org_members_user (INDEX sur user_id)
-- ✅ idx_organization_members_org_user (INDEX sur org_id + user_id)
--
-- VERDICT : ✅ EXCELLENT
-- Tous les index nécessaires sont présents et correctement configurés.
-- Les performances des requêtes RLS seront optimales.
--
-- Note: Il y a plusieurs index redondants sur organization_members,
-- ce qui peut légèrement impacter les performances d'écriture mais garantit
-- des performances de lecture optimales pour toutes les requêtes possibles.