5633969d98
Carte Leaflet (annuaire Éducation nationale) + API PHP/MySQL : fiche établissement (effectifs, IPS, population INSEE, DPE ADEME), GED documents/photos, commentaires par groupe, gestion utilisateurs et politique de mots de passe. Imports opendata (effectifs, IPS, population, DPE, IRIS). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
133 lines
5.5 KiB
PHP
133 lines
5.5 KiB
PHP
<?php
|
|
/**
|
|
* Gestion des administrateurs (super-admin uniquement).
|
|
* GET → liste des utilisateurs + périmètres + email
|
|
* POST {username, password, role?, email?} → crée un utilisateur (role « perimeter »
|
|
* par défaut ; « member » = simple commentateur ;
|
|
* mot de passe soumis à la politique, must_change=1)
|
|
* POST ?action=password {id, password}→ réinitialise un mot de passe (politique, must_change)
|
|
* POST ?action=email {id, email} → met à jour l'e-mail d'un compte
|
|
* POST ?action=scope {user_id, com, depc} → ajoute une commune au périmètre
|
|
* DELETE ?id=N → supprime un admin
|
|
* DELETE ?action=scope&id=N → retire une commune d'un périmètre
|
|
*/
|
|
declare(strict_types=1);
|
|
require __DIR__ . '/db.php';
|
|
|
|
try {
|
|
$me = require_super();
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
$action = $_GET['action'] ?? '';
|
|
|
|
if ($method === 'GET') {
|
|
$users = db()->query('SELECT id, username, role, email, must_change, created_at FROM users ORDER BY role DESC, username')->fetchAll();
|
|
$scopes = db()->query('SELECT id, user_id, com, depc FROM user_scopes ORDER BY com')->fetchAll();
|
|
$byUser = [];
|
|
foreach ($scopes as $s) {
|
|
$byUser[(int) $s['user_id']][] = ['id' => (int) $s['id'], 'com' => $s['com'], 'depc' => $s['depc']];
|
|
}
|
|
foreach ($users as &$u) {
|
|
$u['id'] = (int) $u['id'];
|
|
$u['must_change'] = (int) $u['must_change'];
|
|
$u['scopes'] = $byUser[$u['id']] ?? [];
|
|
}
|
|
json_out($users);
|
|
}
|
|
|
|
// Mise à jour de l'e-mail d'un compte.
|
|
if ($method === 'POST' && $action === 'email') {
|
|
$b = body_json();
|
|
$id = (int) ($b['id'] ?? 0);
|
|
$email = trim((string) ($b['email'] ?? ''));
|
|
if ($id <= 0) {
|
|
json_error('id requis.');
|
|
}
|
|
if ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
json_error('Adresse e-mail invalide.');
|
|
}
|
|
db()->prepare('UPDATE users SET email = ? WHERE id = ?')->execute([$email !== '' ? $email : null, $id]);
|
|
json_out(['ok' => true]);
|
|
}
|
|
|
|
if ($method === 'POST' && $action === 'scope') {
|
|
$b = body_json();
|
|
$uid = (int) ($b['user_id'] ?? 0);
|
|
$com = trim((string) ($b['com'] ?? ''));
|
|
$depc = trim((string) ($b['depc'] ?? ''));
|
|
if ($uid <= 0 || $com === '' || $depc === '') {
|
|
json_error('user_id, com et depc requis.');
|
|
}
|
|
db()->prepare('INSERT IGNORE INTO user_scopes (user_id, com, depc) VALUES (?, ?, ?)')
|
|
->execute([$uid, $com, $depc]);
|
|
json_out(['ok' => true]);
|
|
}
|
|
|
|
if ($method === 'POST' && $action === 'password') {
|
|
$b = body_json();
|
|
$id = (int) ($b['id'] ?? 0);
|
|
$pwd = (string) ($b['password'] ?? '');
|
|
if ($id <= 0) {
|
|
json_error('id requis.');
|
|
}
|
|
if ($err = password_policy_check($pwd)) {
|
|
json_error($err);
|
|
}
|
|
// Mot de passe posé par l'admin → l'utilisateur devra le changer à sa connexion.
|
|
db()->prepare('UPDATE users SET password_hash = ?, must_change = 1, failed_attempts = 0, locked_until = NULL WHERE id = ?')
|
|
->execute([password_hash($pwd, PASSWORD_DEFAULT), $id]);
|
|
json_out(['ok' => true]);
|
|
}
|
|
|
|
if ($method === 'POST') {
|
|
$b = body_json();
|
|
$username = trim((string) ($b['username'] ?? ''));
|
|
$pwd = (string) ($b['password'] ?? '');
|
|
$email = trim((string) ($b['email'] ?? ''));
|
|
$roleIn = (string) ($b['role'] ?? 'perimeter');
|
|
$role = in_array($roleIn, ['super', 'perimeter', 'member'], true) ? $roleIn : 'perimeter';
|
|
if ($username === '') {
|
|
json_error('Identifiant requis.');
|
|
}
|
|
if ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
json_error('Adresse e-mail invalide.');
|
|
}
|
|
if ($err = password_policy_check($pwd)) {
|
|
json_error($err);
|
|
}
|
|
$exists = db()->prepare('SELECT 1 FROM users WHERE username = ?');
|
|
$exists->execute([$username]);
|
|
if ($exists->fetchColumn()) {
|
|
json_error('Cet identifiant existe déjà.');
|
|
}
|
|
// Mot de passe initial posé par l'admin → changement forcé à la 1re connexion.
|
|
db()->prepare('INSERT INTO users (username, password_hash, role, email, must_change) VALUES (?, ?, ?, ?, 1)')
|
|
->execute([$username, password_hash($pwd, PASSWORD_DEFAULT), $role, $email !== '' ? $email : null]);
|
|
json_out(['id' => (int) db()->lastInsertId(), 'username' => $username, 'role' => $role], 201);
|
|
}
|
|
|
|
if ($method === 'DELETE' && $action === 'scope') {
|
|
$id = (int) ($_GET['id'] ?? 0);
|
|
if ($id <= 0) {
|
|
json_error('id requis.');
|
|
}
|
|
db()->prepare('DELETE FROM user_scopes WHERE id = ?')->execute([$id]);
|
|
json_out(['deleted' => $id]);
|
|
}
|
|
|
|
if ($method === 'DELETE') {
|
|
$id = (int) ($_GET['id'] ?? 0);
|
|
if ($id <= 0) {
|
|
json_error('id requis.');
|
|
}
|
|
if ($id === (int) $me['id']) {
|
|
json_error('Vous ne pouvez pas supprimer votre propre compte.');
|
|
}
|
|
db()->prepare('DELETE FROM users WHERE id = ?')->execute([$id]);
|
|
json_out(['deleted' => $id]);
|
|
}
|
|
|
|
json_error('Méthode non supportée.', 405);
|
|
} catch (Throwable $e) {
|
|
json_error('Erreur : ' . $e->getMessage(), 500);
|
|
}
|