525 lines
20 KiB
PHP
525 lines
20 KiB
PHP
<?php
|
|
require_once '../includes/config.php';
|
|
require_once '../includes/auth.php';
|
|
|
|
// Vérification de l'authentification
|
|
if (!Auth::check()) {
|
|
header('Location: login.php');
|
|
exit;
|
|
}
|
|
|
|
// Vérification des privilèges administrateur (premier utilisateur uniquement)
|
|
if (!Auth::isAdmin()) {
|
|
header('Location: index.php');
|
|
exit;
|
|
}
|
|
|
|
$success = '';
|
|
$error = '';
|
|
|
|
// Traitement de l'ajout ou modification d'un utilisateur
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|
try {
|
|
$config = Config::load();
|
|
|
|
// Traitement selon l'action
|
|
switch ($_POST['action']) {
|
|
case 'add':
|
|
// Validation
|
|
$userId = trim($_POST['user_id'] ?? '');
|
|
$password = $_POST['password'] ?? '';
|
|
$confirmPassword = $_POST['confirm_password'] ?? '';
|
|
$comment = trim($_POST['comment'] ?? '');
|
|
$role = $_POST['role'] ?? 'editor';
|
|
|
|
if (strlen($userId) < 3) {
|
|
throw new Exception('L\'identifiant doit faire au moins 3 caractères');
|
|
}
|
|
|
|
if (strlen($password) < 8) {
|
|
throw new Exception('Le mot de passe doit faire au moins 8 caractères');
|
|
}
|
|
|
|
if ($password !== $confirmPassword) {
|
|
throw new Exception('Les mots de passe ne correspondent pas');
|
|
}
|
|
|
|
// Vérification de l'unicité de l'identifiant
|
|
foreach ($config['users'] as $user) {
|
|
if ($user['id'] === $userId) {
|
|
throw new Exception('Cet identifiant est déjà utilisé');
|
|
}
|
|
}
|
|
|
|
// Ajout de l'utilisateur
|
|
$config['users'][] = [
|
|
'id' => $userId,
|
|
'password' => password_hash($password, PASSWORD_DEFAULT),
|
|
'role' => $role,
|
|
'comment' => $comment
|
|
];
|
|
|
|
$success = 'Utilisateur ajouté avec succès';
|
|
break;
|
|
|
|
case 'edit':
|
|
// Validation
|
|
$userId = trim($_POST['user_id'] ?? '');
|
|
$newUserId = trim($_POST['new_user_id'] ?? '');
|
|
$password = $_POST['password'] ?? '';
|
|
$comment = trim($_POST['comment'] ?? '');
|
|
$role = $_POST['role'] ?? 'editor';
|
|
|
|
if ($newUserId && strlen($newUserId) < 3) {
|
|
throw new Exception('Le nouvel identifiant doit faire au moins 3 caractères');
|
|
}
|
|
|
|
if ($password && strlen($password) < 8) {
|
|
throw new Exception('Le mot de passe doit faire au moins 8 caractères');
|
|
}
|
|
|
|
// Recherche de l'utilisateur à modifier
|
|
$userFound = false;
|
|
foreach ($config['users'] as &$user) {
|
|
if ($user['id'] === $userId) {
|
|
// Vérification que le premier compte ne perde pas ses privilèges admin
|
|
if ($user === reset($config['users']) && $role !== 'admin') {
|
|
throw new Exception('Le premier compte doit conserver le rôle d\'administrateur');
|
|
}
|
|
|
|
// Mise à jour des informations
|
|
if ($newUserId && $newUserId !== $userId) {
|
|
// Vérification de l'unicité du nouvel identifiant
|
|
foreach ($config['users'] as $existingUser) {
|
|
if ($existingUser['id'] === $newUserId) {
|
|
throw new Exception('Ce nouvel identifiant est déjà utilisé');
|
|
}
|
|
}
|
|
$user['id'] = $newUserId;
|
|
}
|
|
|
|
if ($password) {
|
|
$user['password'] = password_hash($password, PASSWORD_DEFAULT);
|
|
}
|
|
|
|
$user['comment'] = $comment;
|
|
$user['role'] = $role;
|
|
$userFound = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$userFound) {
|
|
throw new Exception('Utilisateur non trouvé');
|
|
}
|
|
|
|
$success = 'Utilisateur modifié avec succès';
|
|
break;
|
|
|
|
case 'delete':
|
|
// Validation
|
|
$userId = trim($_POST['user_id'] ?? '');
|
|
|
|
// Empêcher la suppression du premier utilisateur
|
|
if ($userId === reset($config['users'])['id']) {
|
|
throw new Exception('Le compte administrateur principal ne peut pas être supprimé');
|
|
}
|
|
|
|
// Recherche et suppression de l'utilisateur
|
|
$userIndex = -1;
|
|
foreach ($config['users'] as $index => $user) {
|
|
if ($user['id'] === $userId) {
|
|
$userIndex = $index;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($userIndex === -1) {
|
|
throw new Exception('Utilisateur non trouvé');
|
|
}
|
|
|
|
array_splice($config['users'], $userIndex, 1);
|
|
$success = 'Utilisateur supprimé avec succès';
|
|
break;
|
|
}
|
|
|
|
// Sauvegarde de la configuration
|
|
Config::save($config);
|
|
|
|
} catch (Exception $e) {
|
|
$error = $e->getMessage();
|
|
}
|
|
}
|
|
|
|
// Chargement de la configuration
|
|
$config = Config::load();
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Gestion des utilisateurs - Administration</title>
|
|
<?php if (file_exists(__DIR__ . '/../assets/images/site/favicon.png')): ?>
|
|
<link rel="icon" type="image/png" href="../assets/images/site/favicon.png">
|
|
<?php endif; ?>
|
|
<link rel="stylesheet" href="../assets/css/main.css">
|
|
</head>
|
|
<body>
|
|
<nav class="admin-nav">
|
|
<div class="nav-brand">
|
|
<?php if (!empty($config['site']['logo'])): ?>
|
|
<img src="<?= htmlspecialchars('../' . $config['site']['logo']) ?>"
|
|
alt="<?= htmlspecialchars($config['site']['name']) ?>">
|
|
<?php endif; ?>
|
|
<span>Administration</span>
|
|
</div>
|
|
<div class="nav-menu">
|
|
<a href="index.php" class="button tooltip" data-tooltip="Retour">
|
|
<i class="fas fa-arrow-left"></i>
|
|
</a>
|
|
</div>
|
|
</nav>
|
|
|
|
<main class="admin-main">
|
|
<h1>Gestion des utilisateurs</h1>
|
|
|
|
<?php if ($success): ?>
|
|
<div class="success-message"><?= htmlspecialchars($success) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($error): ?>
|
|
<div class="error-message"><?= htmlspecialchars($error) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Liste des utilisateurs existants -->
|
|
<section class="users-section">
|
|
<h2>Utilisateurs existants</h2>
|
|
<div class="users-list">
|
|
<?php foreach ($config['users'] as $index => $user): ?>
|
|
<div class="user-item <?= $index === 0 ? 'admin-user' : '' ?>">
|
|
<div class="user-info">
|
|
<h3><?= htmlspecialchars($user['id']) ?></h3>
|
|
<p class="user-role">
|
|
Rôle : <span><?= htmlspecialchars($user['role'] ?? 'editor') ?></span>
|
|
</p>
|
|
<?php if (!empty($user['comment'])): ?>
|
|
<p class="user-comment"><?= htmlspecialchars($user['comment']) ?></p>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div class="user-actions">
|
|
<button type="button" class="button tooltip edit-user" data-tooltip="Modifier" data-user-id="<?= htmlspecialchars($user['id']) ?>" data-user-comment="<?= htmlspecialchars($user['comment'] ?? '') ?>" data-user-role="<?= htmlspecialchars($user['role'] ?? 'editor') ?>">
|
|
<i class="fas fa-edit"></i>
|
|
</button>
|
|
<?php if ($index !== 0): ?>
|
|
<button type="button" class="button tooltip delete-user" data-tooltip="Supprimer" data-user-id="<?= htmlspecialchars($user['id']) ?>">
|
|
<i class="fas fa-trash-alt"></i>
|
|
</button>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<button type="button" id="addUserBtn" class="button tooltip" data-tooltip="Ajouter un utilisateur">
|
|
<i class="fas fa-user-plus"></i>
|
|
<span class="tooltip-text">Ajouter un utilisateur</span>
|
|
</button>
|
|
</section>
|
|
|
|
<!-- Formulaire d'ajout d'utilisateur (modal) -->
|
|
<div id="addUserModal" class="modal">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h2>Ajouter un utilisateur</h2>
|
|
</div>
|
|
<form method="POST" id="addUserForm">
|
|
<input type="hidden" name="action" value="add">
|
|
|
|
<div class="form-group">
|
|
<label for="user_id">Identifiant</label>
|
|
<input type="text" id="user_id" name="user_id" required minlength="3">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="password">Mot de passe</label>
|
|
<input type="password" id="password" name="password" required minlength="8">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="confirm_password">Confirmation du mot de passe</label>
|
|
<input type="password" id="confirm_password" name="confirm_password" required>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="role">Rôle</label>
|
|
<select id="role" name="role">
|
|
<option value="editor">Éditeur</option>
|
|
<option value="admin">Administrateur</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="comment">Commentaire (optionnel)</label>
|
|
<textarea id="comment" name="comment" rows="3"></textarea>
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<button type="button" class="button dark cancel-btn">Annuler</button>
|
|
<button type="submit" class="button">Ajouter</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Formulaire d'édition d'utilisateur (modal) -->
|
|
<div id="editUserModal" class="modal">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h2>Modifier un utilisateur</h2>
|
|
</div>
|
|
<form method="POST" id="editUserForm">
|
|
<input type="hidden" name="action" value="edit">
|
|
<input type="hidden" id="edit_user_id" name="user_id">
|
|
|
|
<div class="form-group">
|
|
<label for="new_user_id">Nouvel identifiant (laisser vide pour ne pas modifier)</label>
|
|
<input type="text" id="new_user_id" name="new_user_id" minlength="3">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="edit_password">Nouveau mot de passe (laisser vide pour ne pas modifier)</label>
|
|
<input type="password" id="edit_password" name="password" minlength="8">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="edit_role">Rôle</label>
|
|
<select id="edit_role" name="role">
|
|
<option value="editor">Éditeur</option>
|
|
<option value="admin">Administrateur</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="edit_comment">Commentaire</label>
|
|
<textarea id="edit_comment" name="comment" rows="3"></textarea>
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<button type="button" class="button dark cancel-btn">
|
|
<i class="fas fa-times"></i>
|
|
<span class="button-text">Annuler</span>
|
|
</button>
|
|
<button type="submit" class="button">
|
|
<i class="fas fa-save"></i>
|
|
<span class="button-text">Enregistrer</span>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Formulaire de suppression (caché) -->
|
|
<form id="deleteUserForm" method="POST" style="display: none;">
|
|
<input type="hidden" name="action" value="delete">
|
|
<input type="hidden" id="delete_user_id" name="user_id">
|
|
</form>
|
|
</main>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Gestion des modales
|
|
const addUserModal = document.getElementById('addUserModal');
|
|
const editUserModal = document.getElementById('editUserModal');
|
|
|
|
// Boutons d'ouverture des modales
|
|
const addUserBtn = document.getElementById('addUserBtn');
|
|
|
|
// Boutons de fermeture des modales
|
|
const cancelBtns = document.querySelectorAll('.cancel-btn');
|
|
|
|
// Ouverture de la modale d'ajout
|
|
addUserBtn.addEventListener('click', function() {
|
|
addUserModal.style.display = 'block';
|
|
document.getElementById('addUserForm').reset();
|
|
});
|
|
|
|
// Ouverture de la modale d'édition
|
|
document.querySelectorAll('.edit-user').forEach(button => {
|
|
button.addEventListener('click', function() {
|
|
const userId = this.dataset.userId;
|
|
const userComment = this.dataset.userComment;
|
|
const userRole = this.dataset.userRole;
|
|
|
|
document.getElementById('edit_user_id').value = userId;
|
|
document.getElementById('new_user_id').value = '';
|
|
document.getElementById('edit_password').value = '';
|
|
document.getElementById('edit_comment').value = userComment;
|
|
|
|
// Sélectionner la bonne option dans le select
|
|
const roleSelect = document.getElementById('edit_role');
|
|
for (let i = 0; i < roleSelect.options.length; i++) {
|
|
if (roleSelect.options[i].value === userRole) {
|
|
roleSelect.selectedIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Si c'est le premier utilisateur, désactiver le changement de rôle
|
|
if (userId === '<?= htmlspecialchars(reset($config['users'])['id']) ?>') {
|
|
roleSelect.disabled = true;
|
|
} else {
|
|
roleSelect.disabled = false;
|
|
}
|
|
|
|
editUserModal.style.display = 'block';
|
|
});
|
|
});
|
|
|
|
// Fermeture des modales avec les boutons Annuler
|
|
cancelBtns.forEach(button => {
|
|
button.addEventListener('click', function() {
|
|
addUserModal.style.display = 'none';
|
|
editUserModal.style.display = 'none';
|
|
});
|
|
});
|
|
|
|
// Fermeture des modales en cliquant à l'extérieur
|
|
window.addEventListener('click', function(event) {
|
|
if (event.target === addUserModal) {
|
|
addUserModal.style.display = 'none';
|
|
} else if (event.target === editUserModal) {
|
|
editUserModal.style.display = 'none';
|
|
}
|
|
});
|
|
|
|
// Validation du formulaire d'ajout
|
|
document.getElementById('addUserForm').addEventListener('submit', function(e) {
|
|
const password = document.getElementById('password').value;
|
|
const confirmPassword = document.getElementById('confirm_password').value;
|
|
|
|
if (password !== confirmPassword) {
|
|
e.preventDefault();
|
|
alert('Les mots de passe ne correspondent pas');
|
|
}
|
|
});
|
|
|
|
// Suppression d'un utilisateur
|
|
document.querySelectorAll('.delete-user').forEach(button => {
|
|
button.addEventListener('click', function() {
|
|
const userId = this.dataset.userId;
|
|
|
|
confirmDialog.show({
|
|
title: 'Suppression d\'utilisateur',
|
|
message: `Voulez-vous vraiment supprimer l'utilisateur "${userId}" ? Cette action est irréversible.`,
|
|
confirmText: 'Supprimer',
|
|
confirmClass: 'danger',
|
|
onConfirm: () => {
|
|
document.getElementById('delete_user_id').value = userId;
|
|
document.getElementById('deleteUserForm').submit();
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
<link rel="stylesheet" href="../assets/css/dialog.css">
|
|
<script src="../assets/js/dialog.js"></script>
|
|
|
|
<style>
|
|
/* Styles spécifiques à la page utilisateurs */
|
|
.users-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--spacing-md);
|
|
margin: var(--spacing-lg) 0;
|
|
}
|
|
|
|
.user-item {
|
|
background: var(--bg-tertiary);
|
|
padding: var(--spacing-lg);
|
|
border-radius: var(--radius-md);
|
|
border: 1px solid var(--border-color);
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.user-item.admin-user {
|
|
background: linear-gradient(135deg, var(--bg-tertiary), #57433a);
|
|
position: relative;
|
|
}
|
|
|
|
.user-item.admin-user::after {
|
|
content: 'Admin principal';
|
|
position: absolute;
|
|
top: 0.5rem;
|
|
right: 0.5rem;
|
|
background: var(--accent-primary);
|
|
color: var(--text-tertiary);
|
|
padding: 0.2rem 0.5rem;
|
|
border-radius: var(--radius-sm);
|
|
font-size: 0.8rem;
|
|
}
|
|
|
|
.user-info h3 {
|
|
margin: 0 0 var(--spacing-xs) 0;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.user-role {
|
|
color: var(--text-secondary);
|
|
margin: 0 0 var(--spacing-xs) 0;
|
|
}
|
|
|
|
.user-role span {
|
|
color: var(--accent-primary);
|
|
}
|
|
|
|
.user-comment {
|
|
font-style: italic;
|
|
color: var(--text-secondary);
|
|
margin: 0;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.user-actions {
|
|
display: flex;
|
|
gap: var(--spacing-sm);
|
|
}
|
|
|
|
.user-actions .button {
|
|
padding: var(--spacing-sm) var(--spacing-md);
|
|
}
|
|
|
|
.delete-user {
|
|
background-color: var(--bg-secondary);
|
|
}
|
|
|
|
.delete-user:hover {
|
|
background-color: var(--error-color);
|
|
}
|
|
|
|
/* Responsiveness */
|
|
@media (max-width: 768px) {
|
|
.user-item {
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.user-actions {
|
|
margin-top: var(--spacing-md);
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.modal-content {
|
|
width: 95%;
|
|
max-width: 600px;
|
|
height: auto;
|
|
max-height: 90vh;
|
|
overflow-y: auto;
|
|
}
|
|
}
|
|
</style>
|
|
</body>
|
|
</html>
|