v2.6.1c (Lyra): Admin gebruikersbeheer opnieuw ontworpen + CLI reset
Nieuwe features: - Admin gebruikerslijst met zoeken/filter op gebruikersnaam en rol - Profiel bewerken pagina met wachtwoord wijzigen en rol wijzigen - Nieuwe gebruiker aanmaken via aparte pagina - CLI commando cli/reset-admin-password.php voor admin wachtword reset + lockout reset Architectuur: - /admin/users: lijst met zoekveld, rol filter, bewerk/verwijder acties - /admin/users-edit?user=<naam>: profiel, wachtwoord, rol, verwijderen - /admin/users-new: nieuwe gebruiker aanmaken - AdminAuth::clearLockout() public methode voor CLI gebruik Documentatie: - guide/nl/en/admin-beheerder/gebruikers.md herschreven - 15 nieuwe admin vertaalkeys in NL/EN/DE - Release notes: docs/release-notes/v2.6.1c.md Tests: - Pentest: 30/30 geslaagd, 0 vulnerabilities - WCAG 2.1 AA: 25/25 geslaagd, 100% compliance
This commit is contained in:
+147
-24
@@ -328,6 +328,14 @@ switch ($route) {
|
||||
handleUsers($auth, $appConfig, $twig, $user, $csrf);
|
||||
break;
|
||||
|
||||
case 'users-edit':
|
||||
handleUsersEdit($auth, $appConfig, $twig, $user, $csrf);
|
||||
break;
|
||||
|
||||
case 'users-new':
|
||||
handleUsersNew($auth, $appConfig, $twig, $user, $csrf);
|
||||
break;
|
||||
|
||||
case 'guide':
|
||||
handleGuide($auth, $appConfig, $twig, $user, $csrf);
|
||||
break;
|
||||
@@ -1575,35 +1583,15 @@ function handleUsers($auth, $config, $twig, $user, $csrf): void
|
||||
{
|
||||
$message = '';
|
||||
$messageType = '';
|
||||
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!$auth->verifyCsrf($_POST['csrf_token'] ?? '')) {
|
||||
$message = 'Ongeldige CSRF token.';
|
||||
$messageType = 'danger';
|
||||
} else {
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'add') {
|
||||
$newUsername = trim($_POST['new_username'] ?? '');
|
||||
$newPassword = $_POST['new_password'] ?? '';
|
||||
$newRole = $_POST['new_role'] ?? 'content-manager';
|
||||
$newEmail = trim($_POST['new_email'] ?? '');
|
||||
$newAuthorName = trim($_POST['new_author_name'] ?? '');
|
||||
$newAuthorEmail = trim($_POST['new_author_email'] ?? '');
|
||||
|
||||
$result = $auth->addUser($newUsername, $newPassword, $newRole, $newEmail, $newAuthorName, $newAuthorEmail);
|
||||
$message = $result['message'];
|
||||
$messageType = $result['success'] ? 'success' : 'danger';
|
||||
} elseif ($action === 'profile') {
|
||||
$profileUser = $_POST['profile_username'] ?? '';
|
||||
$profileEmail = trim($_POST['profile_email'] ?? '');
|
||||
$profileAuthorName = trim($_POST['profile_author_name'] ?? '');
|
||||
$profileAuthorEmail = trim($_POST['profile_author_email'] ?? '');
|
||||
|
||||
$result = $auth->updateUserProfile($profileUser, $profileEmail, $profileAuthorName, $profileAuthorEmail);
|
||||
$message = $result['message'];
|
||||
$messageType = $result['success'] ? 'success' : 'danger';
|
||||
} elseif ($action === 'delete') {
|
||||
|
||||
if ($action === 'delete') {
|
||||
$deleteUser = $_POST['delete_username'] ?? '';
|
||||
if ($deleteUser !== $user['username']) {
|
||||
$result = $auth->deleteUser($deleteUser);
|
||||
@@ -1622,17 +1610,152 @@ function handleUsers($auth, $config, $twig, $user, $csrf): void
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$route = 'users';
|
||||
$users = $auth->getUsers();
|
||||
$roles = AdminAuth::getRoles();
|
||||
|
||||
// Search and filter
|
||||
$search = trim($_GET['search'] ?? '');
|
||||
$roleFilter = $_GET['role'] ?? '';
|
||||
|
||||
if ($search !== '') {
|
||||
$users = array_filter($users, function($u) use ($search) {
|
||||
return stripos($u['username'], $search) !== false
|
||||
|| stripos($u['email'] ?? '', $search) !== false
|
||||
|| stripos($u['author_name'] ?? '', $search) !== false;
|
||||
});
|
||||
}
|
||||
if ($roleFilter !== '') {
|
||||
$users = array_filter($users, function($u) use ($roleFilter) {
|
||||
return $u['role'] === $roleFilter;
|
||||
});
|
||||
}
|
||||
|
||||
echo $twig->render('pages/users.twig', [
|
||||
'user' => $user,
|
||||
'route' => $route,
|
||||
'csrf_token' => $csrf,
|
||||
'users' => $users,
|
||||
'roles' => $roles,
|
||||
'search' => $search,
|
||||
'role_filter' => $roleFilter,
|
||||
'sidebar_color' => getSidebarColor($config),
|
||||
'needs_editor' => false,
|
||||
'message' => $message,
|
||||
'message_type' => $messageType,
|
||||
]);
|
||||
}
|
||||
|
||||
function handleUsersEdit($auth, $config, $twig, $user, $csrf): void
|
||||
{
|
||||
$targetUsername = $_GET['user'] ?? '';
|
||||
$targetUsername = preg_replace('/[^a-zA-Z0-9_\-]/', '', $targetUsername);
|
||||
|
||||
if ($targetUsername === '') {
|
||||
header('Location: /admin/users');
|
||||
exit;
|
||||
}
|
||||
|
||||
$message = '';
|
||||
$messageType = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!$auth->verifyCsrf($_POST['csrf_token'] ?? '')) {
|
||||
$message = 'Ongeldige CSRF token.';
|
||||
$messageType = 'danger';
|
||||
} else {
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'profile') {
|
||||
$profileEmail = trim($_POST['profile_email'] ?? '');
|
||||
$profileAuthorName = trim($_POST['profile_author_name'] ?? '');
|
||||
$profileAuthorEmail = trim($_POST['profile_author_email'] ?? '');
|
||||
|
||||
$result = $auth->updateUserProfile($targetUsername, $profileEmail, $profileAuthorName, $profileAuthorEmail);
|
||||
$message = $result['message'];
|
||||
$messageType = $result['success'] ? 'success' : 'danger';
|
||||
} elseif ($action === 'change_role') {
|
||||
$newRole = $_POST['new_role'] ?? '';
|
||||
$result = $auth->changeRole($targetUsername, $newRole);
|
||||
$message = $result['message'];
|
||||
$messageType = $result['success'] ? 'success' : 'danger';
|
||||
} elseif ($action === 'change_password') {
|
||||
$newPassword = $_POST['new_password'] ?? '';
|
||||
$result = $auth->changePassword($targetUsername, $newPassword);
|
||||
$message = $result['message'];
|
||||
$messageType = $result['success'] ? 'success' : 'danger';
|
||||
} elseif ($action === 'delete') {
|
||||
if ($targetUsername !== $user['username']) {
|
||||
$result = $auth->deleteUser($targetUsername);
|
||||
header('Location: /admin/users?msg=' . urlencode($result['message']));
|
||||
exit;
|
||||
} else {
|
||||
$message = 'Je kunt jezelf niet verwijderen.';
|
||||
$messageType = 'danger';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$users = $auth->getUsers();
|
||||
if (!isset($users[$targetUsername])) {
|
||||
header('Location: /admin/users');
|
||||
exit;
|
||||
}
|
||||
|
||||
$targetUser = $users[$targetUsername];
|
||||
$roles = AdminAuth::getRoles();
|
||||
$isSelf = ($targetUsername === $user['username']);
|
||||
|
||||
echo $twig->render('pages/users-edit.twig', [
|
||||
'user' => $user,
|
||||
'route' => 'users',
|
||||
'csrf_token' => $csrf,
|
||||
'target_user' => $targetUser,
|
||||
'is_self' => $isSelf,
|
||||
'roles' => $roles,
|
||||
'sidebar_color' => getSidebarColor($config),
|
||||
'needs_editor' => false,
|
||||
'message' => $message,
|
||||
'message_type' => $messageType,
|
||||
]);
|
||||
}
|
||||
|
||||
function handleUsersNew($auth, $config, $twig, $user, $csrf): void
|
||||
{
|
||||
$message = '';
|
||||
$messageType = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!$auth->verifyCsrf($_POST['csrf_token'] ?? '')) {
|
||||
$message = 'Ongeldige CSRF token.';
|
||||
$messageType = 'danger';
|
||||
} else {
|
||||
$newUsername = trim($_POST['new_username'] ?? '');
|
||||
$newPassword = $_POST['new_password'] ?? '';
|
||||
$newRole = $_POST['new_role'] ?? 'content-manager';
|
||||
$newEmail = trim($_POST['new_email'] ?? '');
|
||||
$newAuthorName = trim($_POST['new_author_name'] ?? '');
|
||||
$newAuthorEmail = trim($_POST['new_author_email'] ?? '');
|
||||
|
||||
$result = $auth->addUser($newUsername, $newPassword, $newRole, $newEmail, $newAuthorName, $newAuthorEmail);
|
||||
if ($result['success']) {
|
||||
header('Location: /admin/users-edit?user=' . urlencode($newUsername) . '&msg=' . urlencode($result['message']));
|
||||
exit;
|
||||
}
|
||||
$message = $result['message'];
|
||||
$messageType = 'danger';
|
||||
}
|
||||
}
|
||||
|
||||
$roles = AdminAuth::getRoles();
|
||||
|
||||
echo $twig->render('pages/users-new.twig', [
|
||||
'user' => $user,
|
||||
'route' => 'users',
|
||||
'csrf_token' => $csrf,
|
||||
'roles' => $roles,
|
||||
'sidebar_color' => getSidebarColor($config),
|
||||
'needs_editor' => false,
|
||||
'message' => $message,
|
||||
|
||||
Reference in New Issue
Block a user