mirror of
https://github.com/JMP-MS/ASPIC.git
synced 2026-10-27 16:07:10 +00:00
131 lines
5.9 KiB
PHP
131 lines
5.9 KiB
PHP
<?php
|
|
/**
|
|
* ASPIC — API d'authentification (aspic.php)
|
|
* ---------------------------------------------------------------------------
|
|
* ⚠️ Authentification centralisée via MIRADOR (30 août 2026, voir journal de
|
|
* développement). L'identifiant n'est plus USR_Code (3 caractères) mais
|
|
* MIR_Email. La vérification se fait contre MIR_Users, dans la base MIRADOR
|
|
* (voir getRouterConnection() dans db.php), qui indique en retour la base de
|
|
* travail propre à cet utilisateur (MIR_ServeurHost / MIR_ServeurPort /
|
|
* MIR_BaseNom) ainsi que son code court (MIR_Code, qui reprend le rôle
|
|
* jusqu'ici tenu par USR_Code — REA_CodeUser/OPE_CodeUser, jointure avec
|
|
* ASP_Users de la base cible pour les préférences/avatar).
|
|
*
|
|
* ASP_Users.USR_MDP n'est plus consulté ni comparé : le mot de passe est
|
|
* désormais vérifié une seule fois, ici, contre MIR_MDPHash (hash bcrypt,
|
|
* password_verify()) — la colonne USR_MDP peut être retirée de chaque base
|
|
* (ASPIC, MS-DEV, MS-TST...) quand Jean-Marc le souhaite, elle est devenue
|
|
* un vestige.
|
|
*
|
|
* Requête attendue : POST, corps JSON { "identifiant": "...", "motdepasse": "..." }
|
|
* (identifiant = adresse mail, MIR_Email).
|
|
*
|
|
* Réponses :
|
|
* 200 { "success": true, "user": { "USR_Code": "...", "USR_Nom": "..." } }
|
|
* 200 { "success": false } (identifiants incorrects)
|
|
* 400 { "success": false, "error": "..." } (requête mal formée)
|
|
* 405 { "success": false, "error": "Méthode non autorisée" } (autre que POST)
|
|
* 500 { "success": false, "error": "..." } (connexion base impossible)
|
|
*
|
|
* Session utilisateur (voir journal, sections 14-15, mise à jour le 30 août
|
|
* 2026 pour MIRADOR) : en cas d'identification réussie, une session PHP
|
|
* native est ouverte avec $_SESSION['USR_Code'] (= MIR_Code) et les
|
|
* coordonnées de la base de travail cible ($_SESSION['ASPIC_DB_HOST'] /
|
|
* ['ASPIC_DB_PORT'] / ['ASPIC_DB_NAME']) — lues ensuite par getDbConnection()
|
|
* (db.php) à chaque appel de contacts.php / professions.php / statuts.php /
|
|
* realisations.php / preferences.php, sans qu'aucun de ces fichiers n'ait
|
|
* besoin d'être modifié : c'est getDbConnection() seule qui route désormais
|
|
* vers la bonne base selon la session en cours. `session_start()` doit
|
|
* rester la toute première instruction de ce fichier, avant tout
|
|
* `header()`/`echo` — sinon PHP refuse d'envoyer les cookies de session.
|
|
*/
|
|
|
|
session_start();
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
require __DIR__ . '/db.php';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(405);
|
|
echo json_encode(['success' => false, 'error' => 'Méthode non autorisée']);
|
|
exit;
|
|
}
|
|
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
$identifiant = isset($data['identifiant']) ? trim((string) $data['identifiant']) : '';
|
|
$motdepasse = isset($data['motdepasse']) ? (string) $data['motdepasse'] : '';
|
|
|
|
if ($identifiant === '' || $motdepasse === '') {
|
|
http_response_code(400);
|
|
echo json_encode(['success' => false, 'error' => 'Identifiant et mot de passe sont obligatoires.']);
|
|
exit;
|
|
}
|
|
|
|
try {
|
|
$pdoRouter = getRouterConnection();
|
|
} catch (PDOException $e) {
|
|
http_response_code(500);
|
|
echo json_encode(['success' => false, 'error' => 'Connexion à MIRADOR impossible']);
|
|
exit;
|
|
}
|
|
|
|
// Comparaison directe sur l'email : la collation utf8mb4_0900_ai_ci déjà en
|
|
// place sur MIRADOR (comme sur les autres bases ASPIC) est nativement
|
|
// insensible à la casse et aux accents, pas besoin d'UPPER() ici.
|
|
$stmt = $pdoRouter->prepare(
|
|
'SELECT MIR_Code, MIR_MDPHash, MIR_ServeurHost, MIR_ServeurPort, MIR_BaseNom
|
|
FROM MIR_Users WHERE MIR_Email = ? AND MIR_Actif = 1'
|
|
);
|
|
$stmt->execute([$identifiant]);
|
|
$routage = $stmt->fetch();
|
|
|
|
// Hash factice comparé même quand l'email est inconnu (password_verify()
|
|
// tourne alors quand même) : évite qu'une différence de temps de réponse
|
|
// laisse deviner qu'une adresse n'existe pas dans MIRADOR. Valeur sans
|
|
// signification, générée une fois pour toutes, jamais utilisée comme vrai
|
|
// mot de passe.
|
|
const HASH_FACTICE = '$2y$12$wni9cLq0BKttPzU0xAPM9uX/HMzu9UJhlOMj32H6/wLmkjlNfZ1cm';
|
|
$hashAVerifier = $routage['MIR_MDPHash'] ?? HASH_FACTICE;
|
|
|
|
if (!$routage || !password_verify($motdepasse, $hashAVerifier)) {
|
|
// Message volontairement générique : ne pas révéler si c'est l'identifiant
|
|
// ou le mot de passe qui est en cause. Le compteur d'essais / la sortie au
|
|
// 3e échec sont gérés côté front, pas ici (voir en-tête de ce fichier).
|
|
echo json_encode(['success' => false]);
|
|
exit;
|
|
}
|
|
|
|
// Coordonnées de la base de travail propre à cet utilisateur : posées en
|
|
// session pour que getDbConnection() (db.php) route tous les prochains
|
|
// appels de CETTE session vers la bonne base, sans qu'il faille les
|
|
// repasser en paramètre à chaque endpoint.
|
|
$_SESSION['USR_Code'] = $routage['MIR_Code'];
|
|
$_SESSION['ASPIC_DB_HOST'] = $routage['MIR_ServeurHost'];
|
|
$_SESSION['ASPIC_DB_PORT'] = (int) $routage['MIR_ServeurPort'];
|
|
$_SESSION['ASPIC_DB_NAME'] = $routage['MIR_BaseNom'];
|
|
|
|
// Nom affiché : toujours porté par ASP_Users de la base cible (MIRADOR ne
|
|
// connaît que l'email/code/mot de passe/routage, pas le nom complet). Un
|
|
// échec de connexion à cette base cible est remonté explicitement — plutôt
|
|
// que de laisser entrer un utilisateur dans une base injoignable, ce qui
|
|
// ferait échouer silencieusement tous les écrans suivants.
|
|
try {
|
|
$pdoCible = getDbConnection();
|
|
} catch (PDOException $e) {
|
|
session_unset();
|
|
http_response_code(500);
|
|
echo json_encode(['success' => false, 'error' => 'Connexion à la base de travail impossible']);
|
|
exit;
|
|
}
|
|
|
|
$stmtNom = $pdoCible->prepare('SELECT USR_Nom FROM ASP_Users WHERE USR_Code = ?');
|
|
$stmtNom->execute([$routage['MIR_Code']]);
|
|
$nom = $stmtNom->fetchColumn();
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'user' => [
|
|
'USR_Code' => $routage['MIR_Code'],
|
|
'USR_Nom' => $nom !== false ? $nom : null,
|
|
],
|
|
]);
|