v2.5.1: Admin theme refactor, Navigation plugin, user roles, guide restructure
- Reorganize admin into admin/theme/default/ (views + assets) - Rename GuideNav to Navigation plugin (essential, protected) - Plugin assets support (SCSS/CSS) loaded after theme CSS - User roles: Admin, Content Manager, BI Manager, Site Admin - Role-based access control (RBAC) for admin routes and sidebar - Guide restructure: sub-topics in separate folders with sidebar nav - Dynamic breadcrumb for homepage and subdirectories - Fix theme path traversal (../../ -> ../) in admin.php - Fix CodeMirror mode load order (xml -> css -> js -> htmlmixed -> php) - Fix editor-toolbar.js null checks for plugin edit pages - Layout select from theme.json with live frontmatter update - Footer sticky at bottom of viewport (min-height: 100vh) - Breadcrumb color fix (var(--nav-font) -> var(--header-bg)) - Remove language switcher from guide pages - Update README.md and README.en.md - Bump version to 2.5.1
This commit is contained in:
+92
-5
@@ -9,6 +9,28 @@ class AdminAuth
|
||||
private array $adminConfig;
|
||||
private string $lockFile;
|
||||
|
||||
/**
|
||||
* Role definitions with permissions.
|
||||
* Each role maps to a list of allowed route prefixes.
|
||||
* 'admin' has wildcard '*' access.
|
||||
*/
|
||||
public const ROLE_PERMISSIONS = [
|
||||
'admin' => ['*'],
|
||||
'content-manager' => ['dashboard', 'content', 'content-edit', 'content-new', 'content-delete', 'content-dir-create', 'content-dir-rename', 'content-dir-delete', 'content-move', 'guide', 'logout'],
|
||||
'bi-manager' => ['dashboard', 'statistics', 'logs', 'guide', 'logout'],
|
||||
'site-admin' => ['dashboard', 'theme', 'theme-new', 'plugins', 'plugins-new', 'plugins-edit', 'plugins-config', 'plugins-toggle', 'plugins-delete', 'statistics', 'logs', 'update', 'guide', 'logout'],
|
||||
];
|
||||
|
||||
/**
|
||||
* Human-readable role labels.
|
||||
*/
|
||||
public const ROLE_LABELS = [
|
||||
'admin' => 'Admin',
|
||||
'content-manager' => 'Content Beheerder',
|
||||
'bi-manager' => 'BI Beheerder',
|
||||
'site-admin' => ' Site Admin',
|
||||
];
|
||||
|
||||
public function __construct(array $appConfig)
|
||||
{
|
||||
$this->config = $appConfig;
|
||||
@@ -154,6 +176,45 @@ class AdminAuth
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the role of the current user.
|
||||
*/
|
||||
public function getCurrentRole(): string
|
||||
{
|
||||
return $_SESSION['admin_role'] ?? 'admin';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user has permission to access a route.
|
||||
*/
|
||||
public function hasPermission(string $route): bool
|
||||
{
|
||||
$role = $this->getCurrentRole();
|
||||
$permissions = self::ROLE_PERMISSIONS[$role] ?? ['dashboard', 'logout'];
|
||||
|
||||
if (in_array('*', $permissions, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return in_array($route, $permissions, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available roles.
|
||||
*/
|
||||
public static function getRoles(): array
|
||||
{
|
||||
return self::ROLE_LABELS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get role label.
|
||||
*/
|
||||
public static function getRoleLabel(string $role): string
|
||||
{
|
||||
return self::ROLE_LABELS[$role] ?? $role;
|
||||
}
|
||||
|
||||
public function getCsrfToken(): string
|
||||
{
|
||||
if (!isset($_SESSION['admin_csrf_token'])) {
|
||||
@@ -176,13 +237,17 @@ class AdminAuth
|
||||
|
||||
public function getUsers(): array
|
||||
{
|
||||
return array_map(function ($u) {
|
||||
return [
|
||||
$users = [];
|
||||
foreach ($this->adminConfig['users'] ?? [] as $u) {
|
||||
$role = $u['role'] ?? 'admin';
|
||||
$users[$u['username']] = [
|
||||
'username' => $u['username'],
|
||||
'role' => $u['role'] ?? 'admin',
|
||||
'role' => $role,
|
||||
'role_label' => self::getRoleLabel($role),
|
||||
'created' => $u['created'] ?? ''
|
||||
];
|
||||
}, $this->adminConfig['users'] ?? []);
|
||||
}
|
||||
return $users;
|
||||
}
|
||||
|
||||
public function addUser(string $username, string $password, string $role = 'admin'): array
|
||||
@@ -193,6 +258,9 @@ class AdminAuth
|
||||
if (strlen($password) < 8) {
|
||||
return ['success' => false, 'message' => 'Wachtwoord moet minimaal 8 tekens zijn.'];
|
||||
}
|
||||
if (!isset(self::ROLE_PERMISSIONS[$role])) {
|
||||
return ['success' => false, 'message' => 'Ongeldige rol.'];
|
||||
}
|
||||
|
||||
$this->adminConfig['users'][] = [
|
||||
'username' => $username,
|
||||
@@ -201,10 +269,29 @@ class AdminAuth
|
||||
'created' => date('Y-m-d')
|
||||
];
|
||||
$this->saveAdminConfig();
|
||||
$this->log('info', "Gebruiker aangemaakt: {$username}");
|
||||
$this->log('info', "Gebruiker aangemaakt: {$username} (rol: {$role})");
|
||||
return ['success' => true, 'message' => 'Gebruiker aangemaakt.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the role of an existing user.
|
||||
*/
|
||||
public function changeRole(string $username, string $role): array
|
||||
{
|
||||
if (!isset(self::ROLE_PERMISSIONS[$role])) {
|
||||
return ['success' => false, 'message' => 'Ongeldige rol.'];
|
||||
}
|
||||
foreach ($this->adminConfig['users'] as &$user) {
|
||||
if ($user['username'] === $username) {
|
||||
$user['role'] = $role;
|
||||
$this->saveAdminConfig();
|
||||
$this->log('info', "Rol gewijzigd: {$username} -> {$role}");
|
||||
return ['success' => true, 'message' => 'Rol gewijzigd.'];
|
||||
}
|
||||
}
|
||||
return ['success' => false, 'message' => 'Gebruiker niet gevonden.'];
|
||||
}
|
||||
|
||||
public function deleteUser(string $username): array
|
||||
{
|
||||
if ($username === ($_SESSION['admin_user'] ?? '')) {
|
||||
|
||||
Reference in New Issue
Block a user