Files
gestion-certificats2/app/public/index.php
google-labs-jules[bot] 5d0990b1d6 feat: Demande du mot de passe admin et du ROOT_DOMAIN à l'initialisation
Modifie le processus d'initialisation de l'application :
- Lors du premier lancement, un formulaire vous demande maintenant de saisir le mot de passe souhaité pour le compte administrateur initial et le ROOT_DOMAIN à utiliser pour le certificat CA.
- Ces informations sont temporairement stockées en session.
- Le script `create_root_cert.sh` a été modifié pour accepter le ROOT_DOMAIN en argument et l'utilise pour générer le CN du certificat racine.
- Le mot de passe fourni est utilisé pour créer le premier utilisateur administrateur.
- Les variables de session contenant ces informations sont nettoyées après la fin du processus d'initialisation.

Cela améliore la sécurité en évitant un mot de passe par défaut codé en dur et permet une configuration flexible du domaine du certificat racine dès le départ.
2025-06-15 09:34:10 +00:00

196 lines
10 KiB
PHP

<?php
// Démarrer la session PHP
session_start();
// Inclusion des fichiers fondamentaux
require_once __DIR__ . '/../src/Core/Autoloader.php';
require_once __DIR__ . '/../src/Core/Router.php';
require_once __DIR__ . '/../src/Core/Database.php';
require_once __DIR__ . '/../src/config/app.php'; // Charge les constantes d'application
// Enregistrement de l'autoloader pour charger les classes automatiquement
\App\Core\Autoloader::register();
// Importation des classes à utiliser
use App\Core\Database;
use App\Core\Router;
use App\Services\AuthService;
use App\Services\LanguageService;
use App\Services\LogService;
use App\Utils\DarkMode;
// Initialisation de la connexion à la base de données
try {
Database::connect(DB_HOST, DB_NAME, DB_USER, DB_PASSWORD);
} catch (PDOException $e) {
// En cas d'erreur de connexion, logguer et afficher un message générique
error_log("Database connection error: " . $e->getMessage());
die("Une erreur est survenue lors de la connexion à la base de données. Veuillez réessayer plus tard.");
}
// Initialisation des services principaux
$dbInstance = Database::getInstance(); // Récupère l'instance PDO
$authService = new AuthService($dbInstance);
$logService = new LogService(APP_LOG_PATH);
$langService = new LanguageService(APP_ROOT_DIR . '/src/Lang/');
// ----------------------------------------------------
// Gestion de la Langue et du Mode Sombre via URL ou Session
// ----------------------------------------------------
// Traitement du changement de langue
if (isset($_GET['lang'])) {
$langService->setLanguage($_GET['lang']);
// Redirige pour nettoyer le paramètre GET de l'URL
header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?'));
exit();
}
$currentLang = $langService->getLanguage();
$translations = $langService->getTranslations(); // Charge les traductions pour la langue actuelle
// Traitement du mode sombre
DarkMode::init(); // Initialise le mode sombre si ce n'est pas déjà fait
if (isset($_GET['dark_mode'])) {
DarkMode::toggle($_GET['dark_mode']);
// Redirige pour nettoyer le paramètre GET de l'URL
header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?'));
exit();
}
// ----------------------------------------------------
// Log de chaque requête entrante (pour le débogage/audit)
// ----------------------------------------------------
$logService->log('info', 'Requête reçue: ' . $_SERVER['REQUEST_METHOD'] . ' ' . $_SERVER['REQUEST_URI'], $authService->getUserId(), $_SERVER['REMOTE_ADDR']);
// ----------------------------------------------------
// Processus d'initialisation de l'application au premier lancement
// Crée le Root CA et le premier compte administrateur si non existants.
// ----------------------------------------------------
$stmt = $dbInstance->query("SELECT COUNT(*) FROM users");
$userCount = $stmt->fetchColumn();
// Vérifier l'existence du certificat root
$rootCertExists = file_exists(ROOT_CA_PATH . '/certs/ca.cert.pem');
if ($userCount === 0 || !$rootCertExists) {
// Début de la logique de formulaire et de session pour l'initialisation
if (!isset($_SESSION['init_admin_password'], $_SESSION['init_root_domain'])) {
if (isset($_POST['admin_password'], $_POST['root_domain']) && !empty($_POST['admin_password']) && !empty($_POST['root_domain'])) {
$_SESSION['init_admin_password'] = $_POST['admin_password'];
$_SESSION['init_root_domain'] = $_POST['root_domain'];
header('Location: ' . $_SERVER['PHP_SELF']);
exit();
} else {
// Afficher le formulaire d'initialisation
echo "<!DOCTYPE html><html lang=\"fr\"><head><meta charset=\"UTF-8\"><title>Initialisation Requise</title><link rel=\"stylesheet\" href=\"/css/style.css\"></head><body>";
echo "<div class=\"container\">";
echo "<h1>Initialisation de l'Application Requise</h1>";
echo "<p>Veuillez fournir les informations suivantes pour la configuration initiale :</p>";
echo "<form method=\"POST\" action=\"" . htmlspecialchars($_SERVER['PHP_SELF']) . "\">";
echo "<div><label for=\"admin_password\">Mot de passe administrateur initial :</label><input type=\"password\" id=\"admin_password\" name=\"admin_password\" required></div>";
echo "<div><label for=\"root_domain\">Domaine racine (ROOT_DOMAIN) pour le certificat CA :</label><input type=\"text\" id=\"root_domain\" name=\"root_domain\" required><small>Exemple: exemple.com</small></div>";
echo "<button type=\"submit\">Configurer</button>";
echo "</form>";
echo "</div></body></html>";
exit();
}
}
// Si nous arrivons ici, les données de session sont définies. Procéder à l'initialisation.
echo "<!DOCTYPE html><html lang=\"fr\"><head><meta charset=\"UTF-8\"><title>Initialisation en cours</title><link rel=\"stylesheet\" href=\"/css/style.css\"></head><body>";
echo "<div class=\"container\"><h1>Initialisation de l'Application</h1>";
echo "<p>Configuration en cours avec les informations fournies...</p>";
// Création du certificat Root CA si non existant
if (!$rootCertExists) {
echo "<p>Création du certificat Root CA en cours...</p>";
$logService->log('info', 'Lancement de la création du certificat Root CA pour le domaine: ' . $_SESSION['init_root_domain'], null, $_SERVER['REMOTE_ADDR']);
// Exécution du script shell de création de certificat root avec le domaine racine
$command = escapeshellcmd(SCRIPTS_PATH . '/create_root_cert.sh ' . escapeshellarg($_SESSION['init_root_domain']));
$output = shell_exec($command . ' 2>&1');
$logService->log('info', "Résultat création Root CA: " . $output, null, $_SERVER['REMOTE_ADDR']);
if (file_exists(ROOT_CA_PATH . '/certs/ca.cert.pem')) {
echo "<p>Certificat Root CA créé avec succès pour le domaine " . htmlspecialchars($_SESSION['init_root_domain']) . ".</p>";
// Extraire la date d'expiration du certificat créé pour l'enregistrer en BDD
$certInfo = shell_exec("openssl x509 -in " . escapeshellarg(ROOT_CA_PATH . '/certs/ca.cert.pem') . " -noout -enddate 2>/dev/null | cut -d= -f2");
$expirationTimestamp = strtotime($certInfo);
$expirationDate = $expirationTimestamp ? date('Y-m-d H:i:s', $expirationTimestamp) : (new DateTime('+10 years'))->format('Y-m-d H:i:s');
// Enregistrer le certificat root dans la base de données
$stmt = $dbInstance->prepare("INSERT INTO certificates (name, type, common_name, expiration_date) VALUES (?, ?, ?, ?)");
$stmt->execute(['ca.cert.pem', 'root', $_SESSION['init_root_domain'], $expirationDate]);
} else {
echo "<p style=\"color: red;\">Erreur lors de la création du certificat Root CA. Veuillez vérifier les logs PHP et Docker.</p>";
echo "<pre>" . htmlspecialchars($output) . "</pre>";
// Nettoyer les variables de session en cas d'erreur pour permettre une nouvelle tentative
unset($_SESSION['init_admin_password']);
unset($_SESSION['init_root_domain']);
echo "<p><a href=\"" . htmlspecialchars($_SERVER['PHP_SELF']) . "\">Réessayer</a></p>";
// Arrête l'exécution pour que l'utilisateur puisse voir l'erreur
exit();
}
}
// Création du premier compte administrateur si non existant
if ($userCount === 0) {
echo "<p>Création du premier compte administrateur...</p>";
$adminUsername = 'admin';
// Utiliser le mot de passe fourni via le formulaire et stocké en session
$adminPasswordPlain = $_SESSION['init_admin_password'];
$adminPasswordHashed = password_hash($adminPasswordPlain, PASSWORD_DEFAULT);
$stmt = $dbInstance->prepare("INSERT INTO users (username, password, role) VALUES (?, ?, ?)");
$stmt->execute([$adminUsername, $adminPasswordHashed, 'admin']);
$userId = $dbInstance->lastInsertId(); // Récupérer l'ID de l'utilisateur créé
$logService->log('info', "Compte administrateur '$adminUsername' créé.", $userId, $_SERVER['REMOTE_ADDR']);
echo "<p>Compte administrateur 'admin' créé avec succès. Le mot de passe a été défini comme vous l'avez fourni. Veuillez le conserver précieusement.</p>";
}
// Nettoyer les variables de session d'initialisation après une initialisation réussie
unset($_SESSION['init_admin_password']);
unset($_SESSION['init_root_domain']);
echo "<p>Initialisation terminée. Redirection vers la page de connexion dans 5 secondes...</p>";
echo "</div></body></html>";
// Redirection automatique après l'initialisation
header('Refresh: 5; URL=/login');
exit();
}
// ----------------------------------------------------
// Fin du processus d'initialisation
// ----------------------------------------------------
// ----------------------------------------------------
// Configuration du routeur de l'application
// ----------------------------------------------------
$router = new Router();
// Routes publiques (accessibles sans authentification)
$router->addRoute('GET', '/', 'HomeController@index');
$router->addRoute('GET', '/login', 'AuthController@showLoginForm');
$router->addRoute('POST', '/login', 'AuthController@login');
// Routes protégées (nécessitent une authentification)
// Le dernier paramètre 'true' indique que la route nécessite une authentification
$router->addRoute('GET', '/dashboard', 'DashboardController@index', true);
$router->addRoute('GET', '/certificates', 'CertificateController@index', true);
$router->addRoute('GET', '/certificates/create', 'CertificateController@showCreateForm', true);
$router->addRoute('POST', '/certificates/create', 'CertificateController@create', true);
$router->addRoute('POST', '/certificates/revoke', 'CertificateController@revoke', true);
$router->addRoute('GET', '/perimeters', 'PerimeterController@index', true);
$router->addRoute('GET', '/perimeters/create', 'PerimeterController@showCreateForm', true);
$router->addRoute('POST', '/perimeters/create', 'PerimeterController@create', true);
$router->addRoute('GET', '/users', 'UserController@index', true);
$router->addRoute('GET', '/users/create', 'UserController@showCreateForm', true);
$router->addRoute('POST', '/users/create', 'UserController@create', true);
$router->addRoute('POST', '/users/delete', 'UserController@delete', true);
$router->addRoute('GET', '/logout', 'AuthController@logout', true);
// Exécuter le routage
$router->dispatch();