mirror of
https://github.com/tips-of-mine/gestion-certificats2.git
synced 2025-06-28 12:48:42 +02:00
feat: Ajout de la fonctionnalité de modification de rôle utilisateur
J'ai implémenté la possibilité pour les administrateurs de changer le rôle des utilisateurs entre 'user' et 'admin' directement depuis la page de liste des utilisateurs. Changements apportés : - Ajout d'une méthode `toggleAdminRole` dans `UserController.php` pour gérer la logique de changement de rôle. - Intégration de vérifications de sécurité pour empêcher la modification du rôle de l'admin principal, de votre propre rôle, ou la suppression du dernier rôle admin. - Ajout d'une route POST `/users/toggle-admin` pour cette nouvelle fonctionnalité. - Modification de la vue `app/src/Views/users/index.php` pour afficher les boutons de changement de rôle ("Passer Admin" / "Retirer Admin") avec une confirmation JavaScript. - Mise à jour du fichier de langue `fr.json` avec les nouvelles chaînes de caractères nécessaires. - Journalisation des actions de modification de rôle. Il est recommandé de tester manuellement cette fonctionnalité pour s'assurer qu'elle fonctionne comme prévu dans tous les scénarios.
This commit is contained in:
@ -215,6 +215,7 @@ $router->addRoute('GET', '/users', 'UserController@index', true);
|
|||||||
$router->addRoute('GET', '/users/create', 'UserController@showCreateForm', true);
|
$router->addRoute('GET', '/users/create', 'UserController@showCreateForm', true);
|
||||||
$router->addRoute('POST', '/users/create', 'UserController@create', true);
|
$router->addRoute('POST', '/users/create', 'UserController@create', true);
|
||||||
$router->addRoute('POST', '/users/delete', 'UserController@delete', true);
|
$router->addRoute('POST', '/users/delete', 'UserController@delete', true);
|
||||||
|
$router->addRoute('POST', '/users/toggle-admin', 'UserController@toggleAdminRole', true);
|
||||||
$router->addRoute('GET', '/logout', 'AuthController@logout', true);
|
$router->addRoute('GET', '/logout', 'AuthController@logout', true);
|
||||||
|
|
||||||
// Exécuter le routage
|
// Exécuter le routage
|
||||||
|
@ -7,6 +7,7 @@ use App\Services\AuthService;
|
|||||||
use App\Services\LogService;
|
use App\Services\LogService;
|
||||||
use App\Services\LanguageService;
|
use App\Services\LanguageService;
|
||||||
use App\Utils\DarkMode;
|
use App\Utils\DarkMode;
|
||||||
|
use \PDOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contrôleur pour la gestion des utilisateurs.
|
* Contrôleur pour la gestion des utilisateurs.
|
||||||
@ -210,4 +211,76 @@ class UserController
|
|||||||
header('Location: /users');
|
header('Location: /users');
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifie le rôle d'un utilisateur (admin/user).
|
||||||
|
*/
|
||||||
|
public function toggleAdminRole()
|
||||||
|
{
|
||||||
|
$this->requireAdmin();
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
|
header('Location: /users');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$userIdToModify = $_POST['user_id'] ?? null;
|
||||||
|
$ipAddress = $_SERVER['REMOTE_ADDR'];
|
||||||
|
$adminUserId = $this->authService->getUserId();
|
||||||
|
|
||||||
|
if (empty($userIdToModify)) {
|
||||||
|
$_SESSION['error'] = $this->langService->__('user_role_error_id_missing'); // Nouvelle chaîne de langue
|
||||||
|
header('Location: /users');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Récupérer les informations de l'utilisateur à modifier
|
||||||
|
$stmt = $this->db->prepare("SELECT username, role FROM users WHERE id = ?");
|
||||||
|
$stmt->execute([$userIdToModify]);
|
||||||
|
$userToModify = $stmt->fetch();
|
||||||
|
|
||||||
|
if (!$userToModify) {
|
||||||
|
$_SESSION['error'] = $this->langService->__('user_not_found'); // Nouvelle chaîne de langue (ou existante)
|
||||||
|
header('Location: /users');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empêcher la modification du rôle de l'utilisateur "admin" (ou un nom spécifique)
|
||||||
|
// ou de son propre rôle si c'est l'admin connecté
|
||||||
|
if ($userToModify['username'] === 'admin' || $userIdToModify == $adminUserId) {
|
||||||
|
$_SESSION['error'] = $this->langService->__('cannot_change_admin_role'); // Nouvelle chaîne de langue
|
||||||
|
$this->logService->log('warning', "Tentative de modification du rôle de l'administrateur principal ou de soi-même par l'admin ID: {$adminUserId}.", $adminUserId, $ipAddress);
|
||||||
|
header('Location: /users');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$newRole = ($userToModify['role'] === 'admin') ? 'user' : 'admin';
|
||||||
|
|
||||||
|
// Si on retire le rôle admin, vérifier qu'il en reste au moins un autre
|
||||||
|
if ($newRole === 'user' && $userToModify['role'] === 'admin') {
|
||||||
|
$stmt = $this->db->query("SELECT COUNT(*) FROM users WHERE role = 'admin'");
|
||||||
|
$adminCount = $stmt->fetchColumn();
|
||||||
|
if ($adminCount <= 1) {
|
||||||
|
$_SESSION['error'] = $this->langService->__('cannot_remove_last_admin_role'); // Nouvelle chaîne de langue
|
||||||
|
$this->logService->log('warning', "Tentative de suppression du dernier rôle admin par l'admin ID: {$adminUserId}.", $adminUserId, $ipAddress);
|
||||||
|
header('Location: /users');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$stmt = $this->db->prepare("UPDATE users SET role = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$newRole, $userIdToModify]);
|
||||||
|
|
||||||
|
$this->logService->log('info', "Rôle de l'utilisateur '{$userToModify['username']}' (ID: {$userIdToModify}) changé en '{$newRole}' par l'administrateur ID: {$adminUserId}.", $adminUserId, $ipAddress);
|
||||||
|
$_SESSION['success'] = $this->langService->__('user_role_updated_success', ['username' => htmlspecialchars($userToModify['username']), 'role' => htmlspecialchars($newRole)]); // Nouvelle chaîne de langue
|
||||||
|
} catch (\PDOException $e) {
|
||||||
|
error_log("Erreur lors du changement de rôle de l'utilisateur: " . $e->getMessage());
|
||||||
|
$_SESSION['error'] = $this->langService->__('user_role_update_error_db'); // Nouvelle chaîne de langue
|
||||||
|
$this->logService->log('error', "Échec changement de rôle pour utilisateur ID: {$userIdToModify}: " . $e->getMessage(), $adminUserId, $ipAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
header('Location: /users');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,5 +80,15 @@
|
|||||||
"user_delete_success": "Utilisateur '{username}' supprimé avec succès.",
|
"user_delete_success": "Utilisateur '{username}' supprimé avec succès.",
|
||||||
"user_delete_error_not_found": "Utilisateur introuvable pour la suppression.",
|
"user_delete_error_not_found": "Utilisateur introuvable pour la suppression.",
|
||||||
"user_delete_error_db": "Erreur lors de la suppression de l'utilisateur dans la base de données.",
|
"user_delete_error_db": "Erreur lors de la suppression de l'utilisateur dans la base de données.",
|
||||||
"self_delete_not_allowed": "Vous ne pouvez pas vous supprimer vous-même."
|
"self_delete_not_allowed": "Vous ne pouvez pas vous supprimer vous-même.",
|
||||||
|
"user_role_error_id_missing": "ID utilisateur manquant pour la modification du rôle.",
|
||||||
|
"user_not_found": "Utilisateur non trouvé.",
|
||||||
|
"cannot_change_admin_role": "Le rôle de l'administrateur principal ou son propre rôle ne peut être modifié.",
|
||||||
|
"cannot_remove_last_admin_role": "Impossible de retirer le statut d'administrateur au dernier administrateur.",
|
||||||
|
"user_role_updated_success": "Le rôle de l'utilisateur '{username}' a été changé en '{role}' avec succès.",
|
||||||
|
"user_role_update_error_db": "Erreur de base de données lors de la mise à jour du rôle de l'utilisateur.",
|
||||||
|
"confirm_toggle_admin_role": "Êtes-vous sûr de vouloir modifier le rôle de cet utilisateur ?",
|
||||||
|
"remove_admin_status": "Retirer Admin",
|
||||||
|
"pass_to_admin": "Passer Admin",
|
||||||
|
"cannot_change_main_admin_role": "Rôle non modifiable"
|
||||||
}
|
}
|
||||||
|
@ -36,13 +36,26 @@ require_once APP_ROOT_DIR . '/src/Views/shared/header.php';
|
|||||||
<td><?= htmlspecialchars($user['username']) ?></td>
|
<td><?= htmlspecialchars($user['username']) ?></td>
|
||||||
<td><?= htmlspecialchars($translations[$user['role']] ?? $user['role']) ?></td>
|
<td><?= htmlspecialchars($translations[$user['role']] ?? $user['role']) ?></td>
|
||||||
<td><?= htmlspecialchars((new DateTime($user['created_at']))->format('Y-m-d H:i:s')) ?></td>
|
<td><?= htmlspecialchars((new DateTime($user['created_at']))->format('Y-m-d H:i:s')) ?></td>
|
||||||
<td>
|
<td class="actions-cell"> <!-- Ajout d'une classe pour styliser si besoin -->
|
||||||
<?php if ($user['id'] !== $authService->getUserId()): // Impossible de supprimer son propre compte ?>
|
<?php if ($user['username'] !== 'admin' && $user['id'] !== $authService->getUserId()): ?>
|
||||||
|
<form action="/users/toggle-admin" method="post" class="inline-form" onsubmit="return confirm('<?= htmlspecialchars($translations['confirm_toggle_admin_role'] ?? 'Êtes-vous sûr de vouloir modifier le rôle de cet utilisateur ?') ?>');">
|
||||||
|
<input type="hidden" name="user_id" value="<?= htmlspecialchars($user['id']) ?>">
|
||||||
|
<?php if ($user['role'] === 'admin'): ?>
|
||||||
|
<button type="submit" class="button warning-button"><?= htmlspecialchars($translations['remove_admin_status'] ?? 'Retirer Admin') ?></button>
|
||||||
|
<?php else: ?>
|
||||||
|
<button type="submit" class="button primary-button"><?= htmlspecialchars($translations['pass_to_admin'] ?? 'Passer Admin') ?></button>
|
||||||
|
<?php endif; ?>
|
||||||
|
</form>
|
||||||
|
<?php elseif ($user['username'] === 'admin'): ?>
|
||||||
|
<em><?= htmlspecialchars($translations['cannot_change_main_admin_role'] ?? 'Rôle non modifiable') ?></em>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ($user['id'] !== $authService->getUserId() && $user['username'] !== 'admin'): // Condition existante pour la suppression, légèrement ajustée pour être sûr que 'admin' n'est pas supprimable non plus via cette interface ?>
|
||||||
<form action="/users/delete" method="post" class="inline-form" onsubmit="return confirm('<?= htmlspecialchars($translations['confirm_delete_user']) ?>');">
|
<form action="/users/delete" method="post" class="inline-form" onsubmit="return confirm('<?= htmlspecialchars($translations['confirm_delete_user']) ?>');">
|
||||||
<input type="hidden" name="user_id" value="<?= htmlspecialchars($user['id']) ?>">
|
<input type="hidden" name="user_id" value="<?= htmlspecialchars($user['id']) ?>">
|
||||||
<button type="submit" class="button danger-button"><?= htmlspecialchars($translations['delete_user']) ?></button>
|
<button type="submit" class="button danger-button"><?= htmlspecialchars($translations['delete_user']) ?></button>
|
||||||
</form>
|
</form>
|
||||||
<?php else: ?>
|
<?php elseif ($user['id'] === $authService->getUserId() && $user['username'] !== 'admin'): // Permet à l'admin de voir "non modifiable" pour lui meme, mais pas "auto suppression interdite" si c'est admin ?>
|
||||||
<em><?= htmlspecialchars($translations['self_delete_not_allowed']) ?></em>
|
<em><?= htmlspecialchars($translations['self_delete_not_allowed']) ?></em>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
|
Reference in New Issue
Block a user