mirror of
https://github.com/tips-of-mine/gestion-certificats2.git
synced 2025-06-28 03:38:43 +02:00
![google-labs-jules[bot]](/assets/img/avatar_default.png)
1. **`intermediate_cert_name` unique constraint violation**: When creating a perimeter, the intermediate certificate name (`intermediate_cert_name`) stored in the `functional_perimeters` table was always `"intermediate.cert.pem"`. This caused a duplicate error if a unique constraint existed on this column. * Fixed in `PerimeterController.php` by using `$perimeterName . "_intermediate.cert.pem"` as the value for `intermediate_cert_name`, ensuring uniqueness. The physical file name remains `intermediate.cert.pem` in the perimeter's subdirectory. 2. **`Undefined variable $userRole` warning**: On the page listing perimeters (`app/src/Views/perimeters/index.php`), the `$userRole` variable was not defined by the controller. * Fixed in `PerimeterController.php` (method `index()`) by initializing `$userRole = $this->authService->getUserRole();`. 3. **SQL error `Unknown column 'common_name'` during initialization**: During the application initialization process (if no user or root certificate exists), an attempt to insert into the `certificates` table included a `common_name` column that does not exist. * Fixed in `app/public/index.php` by removing the `common_name` column and its value from the insert query for the root certificate. These corrections improve the robustness of perimeter creation and make the application initialization process more reliable.
225 lines
13 KiB
PHP
225 lines
13 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'];
|
|
$logService->log('debug', 'Initialisation - POST data received: admin_password_present=' . !empty($_POST['admin_password']) . ', root_domain=' . ($_POST['root_domain'] ?? 'not_set_or_empty'));
|
|
$logService->log('debug', 'Initialisation - Session variables SET: init_admin_password_present=' . !empty($_SESSION['init_admin_password']) . ', init_root_domain=' . ($_SESSION['init_root_domain'] ?? 'not_set_or_empty'));
|
|
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']);
|
|
|
|
$logService->log('debug', 'Initialisation - About to call create_root_cert.sh. Value of $_SESSION[\'init_root_domain\']: ' . ($_SESSION['init_root_domain'] ?? 'NOT SET OR EMPTY'));
|
|
if (empty($_SESSION['init_root_domain'])) {
|
|
$logService->log('error', 'Initialisation - CRITICAL: $_SESSION[\'init_root_domain\'] is empty or not set right before calling create_root_cert.sh. Forcing display of error and form again.');
|
|
// Code to re-display form or a clear error message, then exit.
|
|
// This is to prevent the script from being called with an empty argument.
|
|
echo "<p style='color: red;'><strong>Erreur Critique:</strong> La variable de session pour le domaine racine est vide avant d'appeler le script de création. Veuillez réessayer.</p>";
|
|
// Minimal form for resubmission:
|
|
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>";
|
|
// Optionally, unset session variables to force re-entry of CAS 1.2 logic fully.
|
|
unset($_SESSION['init_admin_password']);
|
|
unset($_SESSION['init_root_domain']);
|
|
exit();
|
|
}
|
|
|
|
// 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, expiration_date) VALUES (?, ?, ?)");
|
|
$stmt->execute(['ca.cert.pem', 'root', $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']);
|
|
|
|
// Fermer la session pour s'assurer que les unsets sont sauvegardés avant toute sortie ou redirection.
|
|
session_write_close();
|
|
|
|
echo "<p>Initialisation terminée. Redirection vers la page de connexion dans 5 secondes...</p>";
|
|
// Redirection JavaScript après 5 secondes
|
|
echo "<script type='text/javascript'>setTimeout(function() { window.location.href = '/login'; }, 5000);</script>";
|
|
echo "</div></body></html>";
|
|
// header('Refresh: 5; URL=/login'); // Ancienne méthode de redirection commentée
|
|
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', '/certificates/download', 'CertificateController@download', 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('POST', '/users/toggle-admin', 'UserController@toggleAdminRole', true);
|
|
$router->addRoute('GET', '/users/edit-password/{id}', 'UserController@showEditPasswordForm', true); // Nouvelle route GET
|
|
$router->addRoute('POST', '/users/update-password', 'UserController@updatePassword', true); // Nouvelle route POST
|
|
$router->addRoute('GET', '/logout', 'AuthController@logout', true);
|
|
|
|
// Exécuter le routage
|
|
$router->dispatch();
|