login.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <?php
  2. require_once __DIR__ . "/../config.php";
  3. require_once __DIR__ . "/../includes/functions.php";
  4. $error = "";
  5. // Handle logout via POST + CSRF
  6. if ($_SERVER['REQUEST_METHOD'] === "POST" && isset($_POST['logout'])) {
  7. if (!validateCsrfToken($_POST['csrf_token'] ?? "")) {
  8. $error = "Ungültiges Token. Bitte versuchen Sie es erneut.";
  9. } else {
  10. $_SESSION = [];
  11. if (ini_get("session.use_cookies")) {
  12. $params = session_get_cookie_params();
  13. setcookie(
  14. session_name(),
  15. "",
  16. time() - 42000,
  17. $params["path"],
  18. $params["domain"],
  19. $params["secure"],
  20. $params["httponly"],
  21. );
  22. }
  23. session_destroy();
  24. header("Location: login.php");
  25. exit();
  26. }
  27. }
  28. if ($_SERVER['REQUEST_METHOD'] === "POST") {
  29. // Validate CSRF token
  30. if (!validateCsrfToken($_POST['csrf_token'] ?? "")) {
  31. $error = "Ungültiges Token. Bitte versuchen Sie es erneut.";
  32. } else {
  33. if (isAdminLoginRateLimited()) {
  34. $error =
  35. "Zu viele fehlgeschlagene Anmeldeversuche. Bitte versuchen Sie es später erneut.";
  36. } else {
  37. $username = normalizeAdminUsername($_POST["username"] ?? "");
  38. $password = $_POST["password"] ?? "";
  39. $users = getAdminUsers();
  40. if (
  41. isset($users[$username]) &&
  42. password_verify($password, $users[$username])
  43. ) {
  44. clearAdminLoginRateLimitForCurrentIp();
  45. session_regenerate_id(true);
  46. $_SESSION["admin_logged_in"] = true;
  47. $_SESSION["admin_username"] = $username;
  48. logAccess("Admin login successful", ["username" => $username]);
  49. header("Location: index.php");
  50. exit();
  51. } else {
  52. recordAdminLoginFailure();
  53. logAccess("Admin login failed", ["username" => $username]);
  54. $error = "Benutzername oder Passwort falsch.";
  55. }
  56. }
  57. }
  58. }
  59. // Redirect if already logged in
  60. if (isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in']) {
  61. header("Location: index.php");
  62. exit();
  63. }
  64. ?>
  65. <!DOCTYPE html>
  66. <html lang="de">
  67. <head>
  68. <meta charset="UTF-8">
  69. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  70. <title>Administration - <?php echo escape(SITE_FULL_NAME); ?></title>
  71. <link rel="stylesheet" href="<?php echo escape(
  72. SITE_URL,
  73. ); ?>/assets/css/style.css">
  74. </head>
  75. <body class="admin-page">
  76. <header class="site-header">
  77. <div class="container header-inner">
  78. <a class="brand" href="<?php echo escape(SITE_URL); ?>/index.php">
  79. <img class="brand-logo" src="<?php echo escape(
  80. SITE_URL,
  81. ); ?>/assets/branding/stadt-freising-logo.png" alt="Wappen der Stadt Freising">
  82. <div class="brand-text">
  83. <span class="brand-title"><?php echo escape(
  84. SITE_NAME,
  85. ); ?></span>
  86. <span class="brand-subtitle"><?php echo escape(
  87. SITE_SERVICE_HEADER,
  88. ); ?></span>
  89. </div>
  90. </a>
  91. <a href="<?php echo escape(
  92. SITE_URL,
  93. ); ?>/index.php" class="btn btn-secondary">Zurück zu <?php echo escape(
  94. SITE_SERVICE_NAME,
  95. ); ?></a>
  96. </div>
  97. </header>
  98. <main>
  99. <div class="container container-narrow page-top-gap">
  100. <h2>Administration</h2>
  101. <?php if ($error): ?>
  102. <div class="alert alert-error">
  103. <?php echo htmlspecialchars($error); ?>
  104. </div>
  105. <?php endif; ?>
  106. <form method="POST" class="panel panel-lg">
  107. <?php echo csrfField(); ?>
  108. <div class="form-group">
  109. <label for="username">Benutzername:</label>
  110. <input type="text" id="username" name="username" required autofocus>
  111. </div>
  112. <div class="form-group">
  113. <label for="password">Passwort:</label>
  114. <input type="password" id="password" name="password" required>
  115. </div>
  116. <button type="submit" class="btn btn-block">Anmelden</button>
  117. </form>
  118. <div class="text-center mt-2">
  119. <a href="<?php echo escape(
  120. SITE_URL,
  121. ); ?>/index.php">Zurück zu <?php echo escape(
  122. SITE_SERVICE_NAME,
  123. ); ?></a>
  124. </div>
  125. </div>
  126. </main>
  127. </body>
  128. </html>