chore(sql): compte de visite « Juré » + dump d'authentification versionné

Ajoute sql/create_admin_jure.sql, script idempotent créant/réinitialisant
le compte de démonstration destiné aux personnes qui consultent le site
(rôle Admin). Aucune instruction USE : la base cible vient du paramètre
-d de la connexion, avec un garde-fou qui arrête le script si les tables
attendues sont absentes.

Copie aussi sql/data_sentinel_auth.sql (déjà présent dans le dump livré
sous RENDU/02_Dump_SQL/) : le README de ce dépôt le référençait déjà,
mais le dossier sql/ n'existait pas encore ici.

Documente le compte dans le tableau des comptes de démo du README.
This commit is contained in:
2026-08-15 13:28:23 +02:00
parent fd4c085ee4
commit e6afc4f1fa
3 changed files with 212 additions and 6 deletions
+88
View File
@@ -0,0 +1,88 @@
-- ============================================================
-- DATA SENTINEL — Création / réinitialisation du compte « Juré »
-- Auteur : COYAUD Anthony
-- Version : 1.1 — Août 2026
--
-- Compte Admin destiné aux personnes qui consultent l'application
-- (évaluateurs, jury, démonstration).
--
-- identifiant : Juré
-- mail : JURE@NEXA.com
-- mot de passe : 123456
-- rôle : Admin
--
-- Script idempotent : il peut être rejoué sur une base déjà déployée
-- sans dupliquer le compte ni toucher aux autres utilisateurs.
-- Prérequis : data_sentinel_auth.sql déjà exécuté ([USER] + JOURNAL_AUDIT).
--
-- Pas d'instruction USE : la base cible vient du paramètre -d de la
-- connexion, et le garde-fou ci-dessous interrompt le script si ce
-- n'est pas la bonne. Tout tient dans un seul lot (aucun GO), sans
-- quoi le RETURN du garde-fou n'empêcherait pas la suite de tourner.
--
-- Exécution :
-- sqlcmd -S <serveur> -d <base> -U <user> -P <mdp> -C -b -f 65001 \
-- -i sql/create_admin_jure.sql
-- ============================================================
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @base NVARCHAR(128) = DB_NAME();
IF OBJECT_ID('[USER]', 'U') IS NULL OR OBJECT_ID('JOURNAL_AUDIT', 'U') IS NULL
BEGIN
RAISERROR(
'ARRET : base incorrecte (%s). [USER] ou JOURNAL_AUDIT est introuvable. Reconnectez-vous sur la base Data Sentinel (option -d).',
16, 1, @base);
RETURN;
END
-- Hachage bcrypt (coût 12) du mot de passe de démonstration.
-- Généré avec passlib.CryptContext(schemes=["bcrypt"]) — même librairie que auth.py.
DECLARE @username NVARCHAR(100) = N'Juré';
DECLARE @email NVARCHAR(200) = N'JURE@NEXA.com';
DECLARE @password_hash NVARCHAR(255) = N'$2b$12$nnWMOCjSiUq4rAyPGbC3W.HGdsvWKu9kEfLst6zBIEIcsgP97W94m';
BEGIN TRY
BEGIN TRANSACTION;
IF EXISTS (SELECT 1 FROM [USER] WHERE username = @username)
BEGIN
UPDATE [USER]
SET email = @email,
password_hash = @password_hash,
role = N'Admin',
actif = 1
WHERE username = @username;
INSERT INTO JOURNAL_AUDIT (id_user, username, action, detail)
SELECT id_user, username, 'RESET_PASSWORD', 'Compte de visite reinitialise (script SQL)'
FROM [USER] WHERE username = @username;
PRINT 'Compte "Jure" deja present -> mis a jour.';
END
ELSE
BEGIN
INSERT INTO [USER] (username, email, password_hash, role, actif)
VALUES (@username, @email, @password_hash, N'Admin', 1);
INSERT INTO JOURNAL_AUDIT (id_user, username, action, detail)
SELECT id_user, username, 'CREATE_USER', 'Compte de visite cree (script SQL)'
FROM [USER] WHERE username = @username;
PRINT 'Compte "Jure" cree.';
END
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
PRINT 'ECHEC : ' + ERROR_MESSAGE();
THROW;
END CATCH
-- Vérification
SELECT id_user, username, email, role, actif, created_at, last_login
FROM [USER]
WHERE username = N'Juré';
+105
View File
@@ -0,0 +1,105 @@
-- ============================================================
-- DATA SENTINEL — Script d'authentification SQL Server
-- Tables [USER] + JOURNAL_AUDIT + comptes de démonstration
-- Auteur : COYAUD Anthony
-- Version : 1.1 — Juin 2026
-- À exécuter APRÈS data_sentinel_init.sql (même base DataSentinel)
-- ============================================================
--
-- Ce script crée la couche de sécurité référencée par l'API
-- (main.py / auth.py) :
-- - [USER] : comptes applicatifs (RBAC : Admin / Superviseur / Consultant)
-- - JOURNAL_AUDIT : journal d'audit (connexions + actions d'administration)
--
-- Les mots de passe sont stockés hachés en bcrypt (passlib[bcrypt]).
-- Les hachages ci-dessous correspondent aux comptes de démonstration
-- documentés dans le README (à régénérer en production).
-- ============================================================
USE DataSentinel;
GO
-- ============================================================
-- SUPPRESSION (ordre inverse des dépendances)
-- ============================================================
IF OBJECT_ID('JOURNAL_AUDIT', 'U') IS NOT NULL DROP TABLE JOURNAL_AUDIT;
IF OBJECT_ID('[USER]', 'U') IS NOT NULL DROP TABLE [USER];
GO
-- ============================================================
-- 1. TABLE [USER] — comptes applicatifs
-- ([USER] entre crochets car USER est un mot réservé SQL Server)
-- ============================================================
CREATE TABLE [USER] (
id_user INT NOT NULL IDENTITY(1,1),
username NVARCHAR(100) NOT NULL,
email NVARCHAR(200) NULL,
password_hash NVARCHAR(255) NOT NULL, -- bcrypt
role NVARCHAR(20) NOT NULL, -- Admin | Superviseur | Consultant
actif BIT NOT NULL DEFAULT 1,
created_at DATETIME2 NOT NULL DEFAULT SYSDATETIME(),
last_login DATETIME2 NULL,
CONSTRAINT PK_USER PRIMARY KEY (id_user),
CONSTRAINT UQ_USER_NAME UNIQUE (username),
CONSTRAINT CK_USER_ROLE CHECK (role IN ('Admin', 'Superviseur', 'Consultant'))
);
GO
CREATE INDEX IX_USER_USERNAME ON [USER] (username);
GO
-- ============================================================
-- 2. TABLE JOURNAL_AUDIT — journal d'audit applicatif
-- Alimenté à chaque login + action d'administration.
-- username/id_user nullables (anonymisation RGPD : droit à l'oubli).
-- ============================================================
CREATE TABLE JOURNAL_AUDIT (
id_audit INT NOT NULL IDENTITY(1,1),
id_user INT NULL,
username NVARCHAR(100) NULL,
action NVARCHAR(50) NOT NULL, -- LOGIN | CREATE_USER | UPDATE_USER | DELETE_USER | RESET_PASSWORD
detail NVARCHAR(500) NULL,
ip NVARCHAR(50) NULL,
date_action DATETIME2 NOT NULL DEFAULT SYSDATETIME(),
CONSTRAINT PK_JOURNAL_AUDIT PRIMARY KEY (id_audit)
);
GO
CREATE INDEX IX_AUDIT_DATE ON JOURNAL_AUDIT (date_action DESC);
GO
-- ============================================================
-- 3. COMPTES DE DÉMONSTRATION
-- ⚠️ Mots de passe en clair (à usage de recette / soutenance) :
-- Juré / 123456 → rôle Admin (compte de visite / évaluation)
-- admin / Admin2026! → rôle Admin
-- superviseur / Super2026! → rôle Superviseur
-- consultant / Conseil2026! → rôle Consultant
-- Les hachages bcrypt ci-dessous sont fonctionnels tels quels.
-- ============================================================
INSERT INTO [USER] (username, email, password_hash, role, actif) VALUES
(N'Juré', 'JURE@NEXA.com',
'$2b$12$nnWMOCjSiUq4rAyPGbC3W.HGdsvWKu9kEfLst6zBIEIcsgP97W94m', 'Admin', 1),
('admin', 'admin@xefi-fictif.fr',
'$2b$12$XJobnqM0cHwekv7UYWXUfuxVjMKLZI6VLzpDvRzDdLJgnYHLRNRCy', 'Admin', 1),
('superviseur', 'superviseur@xefi-fictif.fr',
'$2b$12$gMVg2j6wngZZ2KXH2jF6HuvlcAkGIJsbZ05JEQdDYNnIu7fDxOXri', 'Superviseur', 1),
('consultant', 'consultant@xefi-fictif.fr',
'$2b$12$s4Gl3UDq56HOw/GdjeHCrOFjXN/QrV1OEj3wmHhf3T8mFVfijJkty', 'Consultant', 1);
GO
-- Entrée d'audit initiale (création du jeu de comptes)
INSERT INTO JOURNAL_AUDIT (id_user, username, action, detail)
SELECT id_user, username, 'CREATE_USER', 'Compte de démonstration (seed)'
FROM [USER];
GO
-- ============================================================
-- 4. VÉRIFICATIONS
-- ============================================================
SELECT 'USER' AS [Table], COUNT(*) AS [Lignes] FROM [USER]
UNION ALL SELECT 'JOURNAL_AUDIT', COUNT(*) FROM JOURNAL_AUDIT;
GO
SELECT id_user, username, email, role, actif, created_at FROM [USER] ORDER BY id_user;
GO