Base de travail V7.8 reprise du répertoire de travail
Commit technique : reproduit à l'identique l'état non commité de la copie de travail (sécurisation V7.8, CSP à nonce, Session, migration des droits) afin que le travail d'ergonomie qui suit soit isolable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
201
database/migration_v7_8_securite_acces.sql
Normal file
201
database/migration_v7_8_securite_acces.sql
Normal file
@@ -0,0 +1,201 @@
|
||||
-- ============================================================================
|
||||
-- PTA V7.8 — Sécurisation : les règles d'accès descendent en base
|
||||
-- ============================================================================
|
||||
-- À exécuter UNE SEULE FOIS sur une base PTA V7.7 existante :
|
||||
-- SOURCE database/migration_v7_8_securite_acces.sql;
|
||||
--
|
||||
-- Objectif : plus aucune règle de périmètre ni de droit n'est reconstruite en
|
||||
-- PHP. Le contrôleur pose une question à la base, la base répond oui ou non.
|
||||
-- Toute évolution des droits se fait désormais en SQL, sans redéploiement.
|
||||
-- ============================================================================
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 1. MATRICE DES DROITS : rôle -> pages et rôle -> permissions
|
||||
-- ----------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS acces_role_page (
|
||||
role ENUM('AGENT', 'RESPONSABLE_STRUCTURE', 'SERVICE_ENFANCE') NOT NULL,
|
||||
page VARCHAR(50) NOT NULL,
|
||||
ordre_affichage SMALLINT UNSIGNED NOT NULL DEFAULT 100,
|
||||
|
||||
PRIMARY KEY (role, page)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS acces_role_permission (
|
||||
role ENUM('AGENT', 'RESPONSABLE_STRUCTURE', 'SERVICE_ENFANCE') NOT NULL,
|
||||
permission VARCHAR(50) NOT NULL,
|
||||
autorise BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
||||
PRIMARY KEY (role, permission)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Pages autorisées — reprise à l'identique des droits V7.7.
|
||||
INSERT INTO acces_role_page (role, page, ordre_affichage) VALUES
|
||||
('AGENT', 'agents', 10),
|
||||
('AGENT', 'structures', 20),
|
||||
|
||||
('RESPONSABLE_STRUCTURE', 'planning', 10),
|
||||
('RESPONSABLE_STRUCTURE', 'structures', 20),
|
||||
('RESPONSABLE_STRUCTURE', 'agents', 30),
|
||||
('RESPONSABLE_STRUCTURE', 'coverage', 40),
|
||||
|
||||
('SERVICE_ENFANCE', 'planning', 10),
|
||||
('SERVICE_ENFANCE', 'pending', 20),
|
||||
('SERVICE_ENFANCE', 'coverage', 30),
|
||||
('SERVICE_ENFANCE', 'structures', 40),
|
||||
('SERVICE_ENFANCE', 'agents', 50),
|
||||
('SERVICE_ENFANCE', 'annual', 60),
|
||||
('SERVICE_ENFANCE', 'pta', 70),
|
||||
('SERVICE_ENFANCE', 'teams', 80),
|
||||
('SERVICE_ENFANCE', 'vacations', 90),
|
||||
('SERVICE_ENFANCE', 'administration', 100)
|
||||
ON DUPLICATE KEY UPDATE ordre_affichage = VALUES(ordre_affichage);
|
||||
|
||||
-- Permissions fonctionnelles — reprise à l'identique des droits V7.7.
|
||||
INSERT INTO acces_role_permission (role, permission, autorise) VALUES
|
||||
('AGENT', 'read_only', TRUE),
|
||||
('AGENT', 'can_edit_draft', FALSE),
|
||||
('AGENT', 'can_edit_cross_structure', FALSE),
|
||||
('AGENT', 'can_validate', FALSE),
|
||||
('AGENT', 'can_reopen', FALSE),
|
||||
('AGENT', 'can_use_templates', FALSE),
|
||||
('AGENT', 'can_copy_full_week', FALSE),
|
||||
('AGENT', 'can_view_pending', FALSE),
|
||||
('AGENT', 'can_manage_coverage', FALSE),
|
||||
('AGENT', 'can_manage_agents', FALSE),
|
||||
('AGENT', 'can_manage_structures', FALSE),
|
||||
('AGENT', 'can_manage_vacations', FALSE),
|
||||
('AGENT', 'can_manage_teams', FALSE),
|
||||
('AGENT', 'can_manage_pta', FALSE),
|
||||
('AGENT', 'can_forecast_next_year', FALSE),
|
||||
|
||||
('RESPONSABLE_STRUCTURE', 'read_only', FALSE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_edit_draft', TRUE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_edit_cross_structure', FALSE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_validate', FALSE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_reopen', TRUE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_use_templates', FALSE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_copy_full_week', FALSE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_view_pending', FALSE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_manage_coverage', FALSE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_manage_agents', FALSE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_manage_structures', FALSE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_manage_vacations', FALSE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_manage_teams', FALSE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_manage_pta', FALSE),
|
||||
('RESPONSABLE_STRUCTURE', 'can_forecast_next_year', FALSE),
|
||||
|
||||
('SERVICE_ENFANCE', 'read_only', FALSE),
|
||||
('SERVICE_ENFANCE', 'can_edit_draft', TRUE),
|
||||
('SERVICE_ENFANCE', 'can_edit_cross_structure', TRUE),
|
||||
('SERVICE_ENFANCE', 'can_validate', TRUE),
|
||||
('SERVICE_ENFANCE', 'can_reopen', TRUE),
|
||||
('SERVICE_ENFANCE', 'can_use_templates', TRUE),
|
||||
('SERVICE_ENFANCE', 'can_copy_full_week', TRUE),
|
||||
('SERVICE_ENFANCE', 'can_view_pending', TRUE),
|
||||
('SERVICE_ENFANCE', 'can_manage_coverage', TRUE),
|
||||
('SERVICE_ENFANCE', 'can_manage_agents', TRUE),
|
||||
('SERVICE_ENFANCE', 'can_manage_structures', TRUE),
|
||||
('SERVICE_ENFANCE', 'can_manage_vacations', TRUE),
|
||||
('SERVICE_ENFANCE', 'can_manage_teams', TRUE),
|
||||
('SERVICE_ENFANCE', 'can_manage_pta', TRUE),
|
||||
('SERVICE_ENFANCE', 'can_forecast_next_year', TRUE)
|
||||
ON DUPLICATE KEY UPDATE autorise = VALUES(autorise);
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 2. VUES DE DROITS
|
||||
-- ----------------------------------------------------------------------------
|
||||
CREATE OR REPLACE VIEW v_acces_role_page AS
|
||||
SELECT role, page, ordre_affichage
|
||||
FROM acces_role_page;
|
||||
|
||||
CREATE OR REPLACE VIEW v_acces_role_permission AS
|
||||
SELECT role, permission, autorise
|
||||
FROM acces_role_permission;
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 3. VUES D'IDENTITÉ
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- Identité complète d'un agent actif : sert à valider la sélection de rôle et
|
||||
-- à construire le bandeau de profil. Un agent inactif n'apparaît jamais ici,
|
||||
-- il ne peut donc pas être choisi comme identité.
|
||||
CREATE OR REPLACE VIEW v_acces_identite_agent AS
|
||||
SELECT
|
||||
a.id_agent,
|
||||
a.matricule,
|
||||
a.nom,
|
||||
a.prenom,
|
||||
a.id_structure,
|
||||
s.nom AS structure_nom,
|
||||
s.code AS structure_code
|
||||
FROM agent a
|
||||
LEFT JOIN structure s
|
||||
ON s.id_structure = a.id_structure
|
||||
AND s.actif = TRUE
|
||||
WHERE a.actif = TRUE;
|
||||
|
||||
-- Lieux d'affectation sélectionnables par un responsable de structure.
|
||||
CREATE OR REPLACE VIEW v_acces_identite_structure AS
|
||||
SELECT
|
||||
s.id_structure,
|
||||
s.code,
|
||||
s.nom,
|
||||
s.type_affectation
|
||||
FROM structure s
|
||||
WHERE s.actif = TRUE;
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 4. VUES DE PÉRIMÈTRE
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- Quels agents un lieu d'affectation a-t-il le droit de consulter ?
|
||||
-- Deux origines : le rattachement principal, ou une planification effective
|
||||
-- sur ce lieu. C'est la règle exacte que le PHP reconstruisait à la main.
|
||||
CREATE OR REPLACE VIEW v_acces_agent_par_structure AS
|
||||
SELECT DISTINCT
|
||||
a.id_agent,
|
||||
a.id_structure AS id_structure_autorisee,
|
||||
'RATTACHEMENT' AS origine
|
||||
FROM agent a
|
||||
WHERE a.actif = TRUE
|
||||
AND a.id_structure IS NOT NULL
|
||||
UNION
|
||||
SELECT DISTINCT
|
||||
a.id_agent,
|
||||
p.id_structure AS id_structure_autorisee,
|
||||
'PLANIFICATION' AS origine
|
||||
FROM agent a
|
||||
INNER JOIN planning p ON p.id_agent = a.id_agent
|
||||
WHERE a.actif = TRUE;
|
||||
|
||||
-- Périmètre d'un créneau : à quel lieu et à quel planning appartient-il ?
|
||||
-- Utilisé avant toute modification ou suppression d'affectation.
|
||||
CREATE OR REPLACE VIEW v_acces_perimetre_creneau AS
|
||||
SELECT
|
||||
c.id_creneau,
|
||||
c.id_planning,
|
||||
p.id_structure,
|
||||
p.id_agent,
|
||||
p.statut AS statut_planning,
|
||||
s.nom AS structure_nom
|
||||
FROM creneau_horaire c
|
||||
INNER JOIN planning p ON p.id_planning = c.id_planning
|
||||
INNER JOIN structure s ON s.id_structure = p.id_structure;
|
||||
|
||||
-- Périmètre d'un planning : utilisé avant validation ou réouverture.
|
||||
CREATE OR REPLACE VIEW v_acces_perimetre_planning AS
|
||||
SELECT
|
||||
p.id_planning,
|
||||
p.id_structure,
|
||||
p.id_agent,
|
||||
p.statut AS statut_planning,
|
||||
s.nom AS structure_nom,
|
||||
a.nom AS agent_nom,
|
||||
a.prenom AS agent_prenom
|
||||
FROM planning p
|
||||
INNER JOIN structure s ON s.id_structure = p.id_structure
|
||||
INNER JOIN agent a ON a.id_agent = p.id_agent;
|
||||
|
||||
-- ============================================================================
|
||||
-- Vérification recommandée après import :
|
||||
-- SELECT role, COUNT(*) FROM acces_role_page GROUP BY role;
|
||||
-- SELECT * FROM v_acces_agent_par_structure LIMIT 10;
|
||||
-- ============================================================================
|
||||
Reference in New Issue
Block a user