Rectesystem eingebaut
This commit is contained in:
+221
-14
@@ -10,6 +10,8 @@ if (!isset($_SESSION['user_id'])) {
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/auth_helpers.php';
|
||||
|
||||
$config = require __DIR__ . '/../config/database.php';
|
||||
|
||||
$dsn = sprintf(
|
||||
@@ -49,6 +51,28 @@ function redirectToAdminUsers(): void
|
||||
exit;
|
||||
}
|
||||
|
||||
function isPrivilegedRole(?string $role): bool
|
||||
{
|
||||
return isAdminLikeRole($role);
|
||||
}
|
||||
|
||||
function ensureUserPagePermissionsTable(PDO $pdo): void
|
||||
{
|
||||
$pdo->exec("
|
||||
CREATE TABLE IF NOT EXISTS `app_user_page_permissions` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` bigint(20) unsigned NOT NULL,
|
||||
`page_key` varchar(100) NOT NULL,
|
||||
`created_at` datetime NOT NULL DEFAULT current_timestamp(),
|
||||
`updated_at` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uq_app_user_page_permissions_user_page` (`user_id`, `page_key`),
|
||||
KEY `idx_app_user_page_permissions_page_key` (`page_key`),
|
||||
CONSTRAINT `fk_app_user_page_permissions_user_id` FOREIGN KEY (`user_id`) REFERENCES `app_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
");
|
||||
}
|
||||
|
||||
function sendActivationNotification(string $username, string $email, ?string $displayName): void
|
||||
{
|
||||
$subject = 'Dein SkyView-Konto wurde freigeschaltet';
|
||||
@@ -99,7 +123,7 @@ $currentUser = $stmtCurrentUser->fetch();
|
||||
|
||||
if (
|
||||
!$currentUser ||
|
||||
$currentUser['role'] !== 'admin' ||
|
||||
!isAdminLikeRole((string) $currentUser['role']) ||
|
||||
(int)$currentUser['is_active'] !== 1
|
||||
) {
|
||||
$_SESSION = [];
|
||||
@@ -108,6 +132,13 @@ if (
|
||||
exit;
|
||||
}
|
||||
|
||||
$currentUserIsMaster = isMasterRole((string) ($currentUser['role'] ?? ''));
|
||||
$manageablePages = manageablePublicPages();
|
||||
|
||||
if ($currentUserIsMaster) {
|
||||
ensureUserPagePermissionsTable($pdo);
|
||||
}
|
||||
|
||||
if (isset($_SESSION['admin_users_flash_success'])) {
|
||||
$successMessage = (string)$_SESSION['admin_users_flash_success'];
|
||||
unset($_SESSION['admin_users_flash_success']);
|
||||
@@ -140,6 +171,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$targetUser = $stmtTargetUser->fetch();
|
||||
}
|
||||
|
||||
if ($action === 'update_page_permissions' && !$currentUserIsMaster) {
|
||||
$errors[] = 'Nur ein Master-Benutzer darf Seitenfreigaben verwalten.';
|
||||
}
|
||||
|
||||
if (!$targetUser) {
|
||||
$errors[] = 'Das ausgewählte Benutzerkonto wurde nicht gefunden.';
|
||||
}
|
||||
@@ -148,40 +183,66 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$errors[] = 'Das eigene Administrationskonto kann hier nicht deaktiviert, geloescht oder umgestellt werden.';
|
||||
}
|
||||
|
||||
$currentUserIsMaster = isMasterRole((string) ($currentUser['role'] ?? ''));
|
||||
$targetUserIsMaster = $targetUser ? isMasterRole((string) ($targetUser['role'] ?? '')) : false;
|
||||
$requestedRole = (string) ($_POST['role'] ?? 'user');
|
||||
|
||||
if (empty($errors) && $targetUser) {
|
||||
$stmtActiveAdminCount = $pdo->query("
|
||||
SELECT COUNT(*)
|
||||
FROM `app_users`
|
||||
WHERE `role` = 'admin' AND `is_active` = 1
|
||||
WHERE `role` IN ('admin', 'master') AND `is_active` = 1
|
||||
");
|
||||
$activeAdminCount = (int)$stmtActiveAdminCount->fetchColumn();
|
||||
|
||||
$stmtMasterCount = $pdo->query("
|
||||
SELECT COUNT(*)
|
||||
FROM `app_users`
|
||||
WHERE `role` = 'master'
|
||||
");
|
||||
$masterCount = (int)$stmtMasterCount->fetchColumn();
|
||||
|
||||
if (
|
||||
!$currentUserIsMaster &&
|
||||
$targetUserIsMaster
|
||||
) {
|
||||
$errors[] = 'Nur ein Master-Benutzer darf die Rolle master vergeben oder aendern.';
|
||||
}
|
||||
|
||||
if (
|
||||
!$currentUserIsMaster &&
|
||||
$requestedRole === 'master' &&
|
||||
$masterCount > 0
|
||||
) {
|
||||
$errors[] = 'Nur ein Master-Benutzer darf die Rolle master vergeben oder aendern.';
|
||||
}
|
||||
|
||||
if (
|
||||
$action === 'deactivate_user' &&
|
||||
$targetUser['role'] === 'admin' &&
|
||||
isPrivilegedRole((string) $targetUser['role']) &&
|
||||
(int)$targetUser['is_active'] === 1 &&
|
||||
$activeAdminCount <= 1
|
||||
) {
|
||||
$errors[] = 'Der letzte aktive Admin kann nicht deaktiviert werden.';
|
||||
$errors[] = 'Der letzte aktive privilegierte Benutzer kann nicht deaktiviert werden.';
|
||||
}
|
||||
|
||||
if (
|
||||
$action === 'change_role' &&
|
||||
$targetUser['role'] === 'admin' &&
|
||||
($_POST['role'] ?? '') !== 'admin' &&
|
||||
isPrivilegedRole((string) $targetUser['role']) &&
|
||||
!isPrivilegedRole($requestedRole) &&
|
||||
(int)$targetUser['is_active'] === 1 &&
|
||||
$activeAdminCount <= 1
|
||||
) {
|
||||
$errors[] = 'Der letzte aktive Admin kann nicht zur Benutzerrolle herabgestuft werden.';
|
||||
$errors[] = 'Der letzte aktive privilegierte Benutzer kann nicht zur Benutzerrolle herabgestuft werden.';
|
||||
}
|
||||
|
||||
if (
|
||||
$action === 'delete_user' &&
|
||||
$targetUser['role'] === 'admin' &&
|
||||
isPrivilegedRole((string) $targetUser['role']) &&
|
||||
(int)$targetUser['is_active'] === 1 &&
|
||||
$activeAdminCount <= 1
|
||||
) {
|
||||
$errors[] = 'Der letzte aktive Admin kann nicht geloescht werden.';
|
||||
$errors[] = 'Der letzte aktive privilegierte Benutzer kann nicht geloescht werden.';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,9 +282,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
}
|
||||
|
||||
if ($action === 'change_role') {
|
||||
$newRole = (string)($_POST['role'] ?? 'user');
|
||||
$newRole = $requestedRole;
|
||||
|
||||
if (!in_array($newRole, ['user', 'admin'], true)) {
|
||||
if (!in_array($newRole, ['user', 'admin', 'master'], true)) {
|
||||
$errors[] = 'Die gewählte Rolle ist ungültig.';
|
||||
} else {
|
||||
$stmtUpdate = $pdo->prepare("
|
||||
@@ -251,6 +312,59 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$_SESSION['admin_users_flash_success'] = 'Benutzerkonto wurde geloescht. Zugehoerige Standorte und Satelliten wurden automatisch entfernt.';
|
||||
redirectToAdminUsers();
|
||||
}
|
||||
|
||||
if ($action === 'update_page_permissions' && $currentUserIsMaster) {
|
||||
$submittedPages = array_values(array_unique(array_filter(array_map(
|
||||
static fn ($value): string => trim((string) $value),
|
||||
is_array($_POST['page_keys'] ?? null) ? $_POST['page_keys'] : []
|
||||
), static fn (string $value): bool => $value !== '')));
|
||||
|
||||
$submittedPages = array_values(array_intersect($submittedPages, array_keys($manageablePages)));
|
||||
|
||||
$pdo->beginTransaction();
|
||||
try {
|
||||
$stmtDeletePermissions = $pdo->prepare("
|
||||
DELETE FROM `app_user_page_permissions`
|
||||
WHERE `user_id` = :user_id
|
||||
");
|
||||
$stmtDeletePermissions->execute([
|
||||
':user_id' => $targetUserId,
|
||||
]);
|
||||
|
||||
if ($submittedPages !== []) {
|
||||
$stmtInsertPermission = $pdo->prepare("
|
||||
INSERT INTO `app_user_page_permissions` (
|
||||
`user_id`,
|
||||
`page_key`,
|
||||
`created_at`,
|
||||
`updated_at`
|
||||
) VALUES (
|
||||
:user_id,
|
||||
:page_key,
|
||||
NOW(),
|
||||
NOW()
|
||||
)
|
||||
");
|
||||
|
||||
foreach ($submittedPages as $pageKey) {
|
||||
$stmtInsertPermission->execute([
|
||||
':user_id' => $targetUserId,
|
||||
':page_key' => $pageKey,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$pdo->commit();
|
||||
} catch (Throwable $e) {
|
||||
if ($pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$_SESSION['admin_users_flash_success'] = 'Die Seitenfreigaben wurden aktualisiert.';
|
||||
redirectToAdminUsers();
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($errors)) {
|
||||
@@ -264,6 +378,7 @@ $stats = [
|
||||
'active' => 0,
|
||||
'pending' => 0,
|
||||
'admins' => 0,
|
||||
'masters' => 0,
|
||||
];
|
||||
|
||||
$stmtStats = $pdo->query("
|
||||
@@ -271,7 +386,8 @@ $stmtStats = $pdo->query("
|
||||
COUNT(*) AS total_users,
|
||||
SUM(CASE WHEN `is_active` = 1 THEN 1 ELSE 0 END) AS active_users,
|
||||
SUM(CASE WHEN `is_active` = 0 THEN 1 ELSE 0 END) AS pending_users,
|
||||
SUM(CASE WHEN `role` = 'admin' THEN 1 ELSE 0 END) AS admin_users
|
||||
SUM(CASE WHEN `role` = 'admin' THEN 1 ELSE 0 END) AS admin_users,
|
||||
SUM(CASE WHEN `role` = 'master' THEN 1 ELSE 0 END) AS master_users
|
||||
FROM `app_users`
|
||||
");
|
||||
$statsRow = $stmtStats->fetch();
|
||||
@@ -280,6 +396,7 @@ if ($statsRow) {
|
||||
$stats['active'] = (int)$statsRow['active_users'];
|
||||
$stats['pending'] = (int)$statsRow['pending_users'];
|
||||
$stats['admins'] = (int)$statsRow['admin_users'];
|
||||
$stats['masters'] = (int)$statsRow['master_users'];
|
||||
}
|
||||
|
||||
$stmtUsers = $pdo->query("
|
||||
@@ -297,13 +414,36 @@ $stmtUsers = $pdo->query("
|
||||
ORDER BY `is_active` ASC, `role` DESC, `created_at` DESC, `username` ASC
|
||||
");
|
||||
$users = $stmtUsers->fetchAll();
|
||||
$pagePermissionsByUser = [];
|
||||
|
||||
if ($currentUserIsMaster) {
|
||||
$stmtPagePermissions = $pdo->query("
|
||||
SELECT `user_id`, `page_key`
|
||||
FROM `app_user_page_permissions`
|
||||
ORDER BY `user_id` ASC, `page_key` ASC
|
||||
");
|
||||
|
||||
foreach ($stmtPagePermissions as $permissionRow) {
|
||||
$permissionUserId = (int) ($permissionRow['user_id'] ?? 0);
|
||||
$permissionPageKey = (string) ($permissionRow['page_key'] ?? '');
|
||||
if ($permissionUserId < 1 || $permissionPageKey === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($pagePermissionsByUser[$permissionUserId])) {
|
||||
$pagePermissionsByUser[$permissionUserId] = [];
|
||||
}
|
||||
|
||||
$pagePermissionsByUser[$permissionUserId][$permissionPageKey] = true;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?php require __DIR__ . '/header.php'; ?>
|
||||
|
||||
<div class="admin-users-layout">
|
||||
<section class="card admin-users-summary-card">
|
||||
<h2>Uebersicht</h2>
|
||||
<p class="hint">Hier kannst du Benutzerkonten freischalten, deaktivieren, loeschen und zwischen <strong>user</strong> und <strong>admin</strong> wechseln.</p>
|
||||
<p class="hint">Hier kannst du Benutzerkonten freischalten, deaktivieren, loeschen und zwischen <strong>user</strong>, <strong>admin</strong> und <strong>master</strong> wechseln.</p>
|
||||
|
||||
<?php if ($successMessage !== ''): ?>
|
||||
<p class="msg-success"><?= h($successMessage) ?></p>
|
||||
@@ -334,6 +474,10 @@ $users = $stmtUsers->fetchAll();
|
||||
<span class="admin-stat-label">Admins</span>
|
||||
<strong><?= $stats['admins'] ?></strong>
|
||||
</div>
|
||||
<div class="admin-stat-box">
|
||||
<span class="admin-stat-label">Master</span>
|
||||
<strong><?= $stats['masters'] ?></strong>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -375,7 +519,7 @@ $users = $stmtUsers->fetchAll();
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="role-badge <?= $userRow['role'] === 'admin' ? 'role-badge-admin' : 'role-badge-user' ?>">
|
||||
<span class="role-badge <?= in_array($userRow['role'], ['admin', 'master'], true) ? 'role-badge-admin' : 'role-badge-user' ?>">
|
||||
<?= h($userRow['role']) ?>
|
||||
</span>
|
||||
</td>
|
||||
@@ -403,6 +547,9 @@ $users = $stmtUsers->fetchAll();
|
||||
<select name="role"<?= $isSelf ? ' disabled' : '' ?>>
|
||||
<option value="user"<?= $userRow['role'] === 'user' ? ' selected' : '' ?>>user</option>
|
||||
<option value="admin"<?= $userRow['role'] === 'admin' ? ' selected' : '' ?>>admin</option>
|
||||
<?php if ($currentUserIsMaster || $userRow['role'] === 'master'): ?>
|
||||
<option value="master"<?= $userRow['role'] === 'master' ? ' selected' : '' ?>>master</option>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
<button type="submit" class="btn btn-secondary btn-sm"<?= $isSelf ? ' disabled' : '' ?>>Rolle speichern</button>
|
||||
</form>
|
||||
@@ -421,6 +568,66 @@ $users = $stmtUsers->fetchAll();
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php if ($currentUserIsMaster): ?>
|
||||
<section class="card admin-users-table-card">
|
||||
<h2>Seitenfreigaben</h2>
|
||||
<p class="hint">Nur Master-Benutzer duerfen hier festlegen, welche Seiten normale Nutzer im Menue sehen und direkt aufrufen duerfen.</p>
|
||||
<div class="admin-users-table-wrap">
|
||||
<table class="data-table admin-users-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Benutzer</th>
|
||||
<?php foreach ($manageablePages as $pageKey => $pageLabel): ?>
|
||||
<th><?= h($pageLabel) ?></th>
|
||||
<?php endforeach; ?>
|
||||
<th>Speichern</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($users as $userRow): ?>
|
||||
<?php
|
||||
$permissionUserId = (int) $userRow['id'];
|
||||
$userPermissions = $pagePermissionsByUser[$permissionUserId] ?? [];
|
||||
$isPrivilegedUser = isPrivilegedRole((string) ($userRow['role'] ?? ''));
|
||||
$permissionFormId = 'page-permissions-user-' . $permissionUserId;
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<form id="<?= h($permissionFormId) ?>" method="post" action="">
|
||||
<input type="hidden" name="csrf_token" value="<?= h($_SESSION['admin_users_csrf']) ?>">
|
||||
<input type="hidden" name="action" value="update_page_permissions">
|
||||
<input type="hidden" name="user_id" value="<?= $permissionUserId ?>">
|
||||
</form>
|
||||
<strong><?= h($userRow['display_name'] ?: $userRow['username']) ?></strong><br>
|
||||
<small><?= h($userRow['username']) ?> (<?= h($userRow['role']) ?>)</small>
|
||||
</td>
|
||||
<?php foreach ($manageablePages as $pageKey => $pageLabel): ?>
|
||||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="page_keys[]"
|
||||
value="<?= h($pageKey) ?>"
|
||||
form="<?= h($permissionFormId) ?>"
|
||||
<?= isset($userPermissions[$pageKey]) ? 'checked' : '' ?>
|
||||
<?= $isPrivilegedUser ? 'disabled' : '' ?>
|
||||
>
|
||||
</td>
|
||||
<?php endforeach; ?>
|
||||
<td>
|
||||
<?php if ($isPrivilegedUser): ?>
|
||||
<span class="hint">Vollzugriff ueber Rolle</span>
|
||||
<?php else: ?>
|
||||
<button type="submit" class="btn btn-secondary btn-sm" form="<?= h($permissionFormId) ?>">Freigaben speichern</button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<dialog class="admin-dialog" id="activateNotifyDialog">
|
||||
|
||||
Reference in New Issue
Block a user