Rectesystem eingebaut

This commit is contained in:
2026-04-05 11:19:20 +02:00
parent cfd25d3b54
commit eb35501712
9 changed files with 1046 additions and 25 deletions
+125 -9
View File
@@ -1,4 +1,5 @@
<?php
require_once __DIR__ . '/auth_helpers.php';
$title = isset($pageTitle) && is_string($pageTitle) && $pageTitle !== ''
? $pageTitle
: 'Skyview & AstroTools — Astronomiemuseum der Sternwarte Sonneberg';
@@ -14,10 +15,14 @@ $headerIntroSub = isset($headerIntroSub) && is_string($headerIntroSub) ? trim($h
$showHeaderIntro = $headerIntroPre !== '' || $headerIntroTitle !== '' || $headerIntroSub !== '';
$publicBasePath = isset($publicBasePath) && is_string($publicBasePath) ? rtrim($publicBasePath, '/') . '/' : '';
$pdoHeader = isset($pdo) ? $pdo : null;
$isAdmin = $loggedIn && (($_SESSION['role'] ?? '') === 'admin');
$hasFullAdminAccess = $loggedIn && currentUserIsAdminLike();
$canAccessCurrentPage = $hasFullAdminAccess;
$pendingApprovals = 0;
$publicScriptName = currentPublicPageKey();
$publicAccessAllowlist = publicAccessAllowlist();
$manageablePublicPages = manageablePublicPages();
if (($loggedIn || $isAdmin) && $pdoHeader === null) {
if ($loggedIn && $pdoHeader === null) {
$cfgHeader = require __DIR__ . '/../config/database.php';
$pdoHeader = new PDO(
sprintf('mysql:host=%s;dbname=%s;charset=%s', $cfgHeader['host'], $cfgHeader['dbname'], $cfgHeader['charset'] ?? 'utf8mb4'),
@@ -26,6 +31,67 @@ if (($loggedIn || $isAdmin) && $pdoHeader === null) {
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
);
}
if (!in_array($publicScriptName, $publicAccessAllowlist, true) && !$canAccessCurrentPage) {
if (!$loggedIn) {
header('Location: ' . $publicBasePath . 'login.php');
exit;
}
$userHasPagePermission = false;
if ($pdoHeader !== null && isset($manageablePublicPages[$publicScriptName], $_SESSION['user_id'])) {
try {
$stmtPagePermission = $pdoHeader->prepare("
SELECT 1
FROM `app_user_page_permissions`
WHERE `user_id` = :user_id
AND `page_key` = :page_key
LIMIT 1
");
$stmtPagePermission->execute([
':user_id' => (int) $_SESSION['user_id'],
':page_key' => $publicScriptName,
]);
$userHasPagePermission = (bool) $stmtPagePermission->fetchColumn();
} catch (Throwable $e) {
$userHasPagePermission = false;
}
}
if ($userHasPagePermission) {
$canAccessCurrentPage = true;
}
}
if (!in_array($publicScriptName, $publicAccessAllowlist, true) && !$canAccessCurrentPage) {
if (!$loggedIn) {
header('Location: ' . $publicBasePath . 'login.php');
exit;
}
http_response_code(403);
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Zugriff verweigert</title>
<link rel="stylesheet" href="<?= htmlspecialchars($publicBasePath . 'css/style.css', ENT_QUOTES, 'UTF-8') ?>">
</head>
<body>
<main class="container" style="padding-top: 4rem; padding-bottom: 4rem;">
<section class="card">
<h1>Zugriff verweigert</h1>
<p>Diese Seite ist aktuell nur fuer Benutzer mit der Rolle <strong>admin</strong> oder <strong>master</strong> freigegeben.</p>
<p><a class="btn btn-primary" href="<?= htmlspecialchars($publicBasePath . 'logout.php', ENT_QUOTES, 'UTF-8') ?>">Abmelden</a></p>
</section>
</main>
</body>
</html>
<?php
exit;
}
// Standard-Standort des eingeloggten Benutzers laden
$currentLocation = null;
if (!empty($defaultLocation)) {
@@ -43,7 +109,7 @@ if (!empty($defaultLocation)) {
$currentLocation = $stmtLoc->fetch() ?: null;
}
if ($isAdmin && $pdoHeader !== null) {
if ($hasFullAdminAccess && $pdoHeader !== null) {
$stmtPendingUsers = $pdoHeader->query('SELECT COUNT(*) FROM app_users WHERE is_active = 0');
$pendingApprovals = (int)$stmtPendingUsers->fetchColumn();
}
@@ -53,7 +119,6 @@ $menuGroups = [
'title' => 'Himmel &amp; Planeten',
'links' => [
['href' => 'moonphase.php', 'label' => 'Mondphase'],
['href' => 'index_py.php', 'label' => 'Sonne & Mond'],
['href' => 'planetensichtbarkeit.php', 'label' => 'Planetensichtbarkeit'],
['href' => 'tcrb_lightcurve.php', 'label' => 'T CrB Lichtkurve'],
['href' => 'solarsystem.php', 'label' => 'Sonnensystem'],
@@ -81,6 +146,57 @@ $adminLinks = [
['href' => 'monatsvorhersage.php', 'label' => 'Monatsvorhersage'],
['href' => 'telegram/broadcast_test.php', 'label' => 'Telegram-Test'],
];
$accountLinks = [
['href' => 'settings.php', 'label' => 'Einstellungen'],
['href' => 'my_favorites.php', 'label' => 'Favoriten'],
['href' => 'satellitenhimmel.php', 'label' => 'Satellitenhimmel'],
];
if ($loggedIn && !$hasFullAdminAccess && $pdoHeader !== null) {
$allowedPageKeys = [];
try {
$stmtAllowedPages = $pdoHeader->prepare("
SELECT `page_key`
FROM `app_user_page_permissions`
WHERE `user_id` = :user_id
");
$stmtAllowedPages->execute([
':user_id' => (int) ($_SESSION['user_id'] ?? 0),
]);
foreach ($stmtAllowedPages as $allowedPageRow) {
$pageKey = trim((string) ($allowedPageRow['page_key'] ?? ''));
if ($pageKey !== '') {
$allowedPageKeys[$pageKey] = true;
}
}
} catch (Throwable $e) {
$allowedPageKeys = [];
}
foreach ($menuGroups as &$group) {
$group['links'] = array_values(array_filter(
$group['links'],
static function (array $link) use ($allowedPageKeys): bool {
$href = trim((string) ($link['href'] ?? ''));
return $href !== '' && isset($allowedPageKeys[$href]);
}
));
}
unset($group);
$menuGroups = array_values(array_filter(
$menuGroups,
static fn (array $group): bool => !empty($group['links'])
));
$accountLinks = array_values(array_filter(
$accountLinks,
static function (array $link) use ($allowedPageKeys): bool {
$href = trim((string) ($link['href'] ?? ''));
return $href !== '' && isset($allowedPageKeys[$href]);
}
));
}
?>
<!DOCTYPE html>
<html lang="de">
@@ -165,7 +281,7 @@ $adminLinks = [
<a href="<?= htmlspecialchars($publicBasePath . 'index.php', ENT_QUOTES, 'UTF-8') ?>">Skyview &amp; AstroTools</a>
<span class="header-sub"><a href="https://www.astronomiemuseum.de" target="_blank" rel="noopener">Astronomiemuseum der Sternwarte Sonneberg</a></span>
</div>
<?php if ($isAdmin && $pendingApprovals > 0): ?>
<?php if ($hasFullAdminAccess && $pendingApprovals > 0): ?>
<a href="<?= htmlspecialchars($publicBasePath . 'admin_users.php', ENT_QUOTES, 'UTF-8') ?>" class="admin-alert" aria-live="polite">
<span class="admin-alert-icon" aria-hidden="true">!</span>
<span class="admin-alert-text">Achtung: <?= $pendingApprovals ?> <?= $pendingApprovals === 1 ? 'Benutzer wartet' : 'Benutzer warten' ?> auf Freischaltung</span>
@@ -195,16 +311,16 @@ $adminLinks = [
<div class="menu-group">
<div class="menu-title">Konto</div>
<?php if ($loggedIn): ?>
<a href="<?= htmlspecialchars($publicBasePath . 'settings.php', ENT_QUOTES, 'UTF-8') ?>">Einstellungen</a>
<a href="<?= htmlspecialchars($publicBasePath . 'my_favorites.php', ENT_QUOTES, 'UTF-8') ?>">Favoriten</a>
<a href="<?= htmlspecialchars($publicBasePath . 'satellitenhimmel.php', ENT_QUOTES, 'UTF-8') ?>">Satellitenhimmel</a>
<?php foreach ($accountLinks as $accountLink): ?>
<a href="<?= htmlspecialchars($publicBasePath . $accountLink['href'], ENT_QUOTES, 'UTF-8') ?>"><?= htmlspecialchars($accountLink['label'], ENT_QUOTES, 'UTF-8') ?></a>
<?php endforeach; ?>
<a href="<?= htmlspecialchars($publicBasePath . 'logout.php', ENT_QUOTES, 'UTF-8') ?>" class="nav-logout">Abmelden</a>
<?php else: ?>
<a href="<?= htmlspecialchars($publicBasePath . 'login.php', ENT_QUOTES, 'UTF-8') ?>">Anmelden</a>
<a href="<?= htmlspecialchars($publicBasePath . 'register.php', ENT_QUOTES, 'UTF-8') ?>">Registrieren</a>
<?php endif; ?>
</div>
<?php if ($isAdmin): ?>
<?php if ($hasFullAdminAccess): ?>
<div class="menu-group">
<div class="menu-title">Administration</div>
<?php foreach ($adminLinks as $adminLink): ?>