168 lines
6.2 KiB
PHP
168 lines
6.2 KiB
PHP
<?php
|
||
|
||
// Strenge Typprüfung für Parameter- und Rückgabetypen aktivieren.
|
||
declare(strict_types=1);
|
||
|
||
namespace App\Controllers;
|
||
|
||
use App\Services\Ldap\LdapAuthService;
|
||
|
||
/**
|
||
* Zuständig für alles rund um den Login:
|
||
* - Login-Formular anzeigen
|
||
* - Login-Daten verarbeiten (Authentifizierung gegen LDAP/AD)
|
||
* - Logout durchführen
|
||
*/
|
||
class AuthController
|
||
{
|
||
/** @var array<string, mixed> Konfigurationswerte der Anwendung (aus config.php) */
|
||
private array $config;
|
||
|
||
/** @var LdapAuthService Service, der die eigentliche LDAP/AD-Authentifizierung übernimmt */
|
||
private LdapAuthService $ldapAuthService;
|
||
|
||
/**
|
||
* Übergibt die Konfiguration an den Controller und initialisiert den LDAP-Authentifizierungsservice.
|
||
*
|
||
* @param array<string, mixed> $config Vollständige Konfiguration aus config.php
|
||
*/
|
||
public function __construct(array $config)
|
||
{
|
||
// Komplette Config in der Instanz speichern (z. B. für Zugriff auf security- oder ldap-Settings)
|
||
$this->config = $config;
|
||
|
||
// LdapAuthService mit dem Teilbereich "ldap" aus der Konfiguration initialisieren.
|
||
// Wenn 'ldap' nicht gesetzt ist, wird ein leeres Array übergeben (Fail fast erfolgt dann im Service).
|
||
$this->ldapAuthService = new LdapAuthService($config['ldap'] ?? []);
|
||
}
|
||
|
||
/**
|
||
* Zeigt das Login-Formular an.
|
||
* Optional kann eine Fehlermeldung übergeben werden, die in der View dargestellt wird.
|
||
*/
|
||
public function showLoginForm(?string $errorMessage = null): void
|
||
{
|
||
// Pfad zur Login-View (Template-Datei) ermitteln.
|
||
$viewPath = __DIR__ . '/../../public/views/login.php';
|
||
|
||
// Variable für die View vorbereiten (wird in der eingebundenen Datei verwendet).
|
||
$error = $errorMessage;
|
||
|
||
// Falls die View-Datei (noch) nicht existiert, einen Fallback-HTML-Output verwenden.
|
||
if (file_exists($viewPath) === false) {
|
||
$this->renderInlineLogin($error);
|
||
return;
|
||
}
|
||
|
||
// View-Datei einbinden. Variablen aus dieser Methode (z. B. $error) sind dort verfügbar.
|
||
require $viewPath;
|
||
}
|
||
|
||
/**
|
||
* Verarbeitet das Login-Formular:
|
||
* - Liest Benutzername und Passwort aus $_POST
|
||
* - Ruft den LdapAuthService zur Authentifizierung auf
|
||
* - Setzt bei Erfolg die Session und leitet zum Dashboard weiter
|
||
* - Zeigt bei Fehlern erneut das Login-Formular mit Fehlermeldung an
|
||
*/
|
||
public function processLogin(): void
|
||
{
|
||
// Formulardaten aus dem POST-Request lesen.
|
||
$username = trim($_POST['username'] ?? '');
|
||
$password = (string)($_POST['password'] ?? '');
|
||
|
||
try {
|
||
// Versuch, den Benutzer per LDAP/AD zu authentifizieren.
|
||
// true = Authentifizierung erfolgreich
|
||
// false = Anmeldedaten fachlich ungültig (Benutzer/Passwort falsch)
|
||
$authenticated = $this->ldapAuthService->authenticate($username, $password);
|
||
} catch (\Throwable $exception) {
|
||
// Technischer Fehler (z. B. LDAP-Server nicht erreichbar, falsche Konfiguration).
|
||
// In diesem Fall wird eine technische Fehlermeldung im Login-Formular angezeigt.
|
||
$this->showLoginForm('Technischer Fehler bei der Anmeldung: ' . $exception->getMessage());
|
||
return;
|
||
}
|
||
|
||
// Fachlich fehlgeschlagene Anmeldung (z. B. falsches Passwort).
|
||
if ($authenticated === false) {
|
||
$this->showLoginForm('Benutzername oder Passwort ist ungültig.');
|
||
return;
|
||
}
|
||
|
||
// Ab hier ist die Anmeldung erfolgreich.
|
||
|
||
// Session-Key für den eingeloggten Benutzer aus der Konfiguration lesen.
|
||
// Wenn nicht gesetzt, wird "admin_user" als Standard verwendet.
|
||
$sessionKey = $this->config['security']['session_key_user'] ?? 'admin_user';
|
||
|
||
// Benutzerinformationen in der Session hinterlegen.
|
||
// Diese Daten werden später von requireLogin() ausgewertet.
|
||
$_SESSION[$sessionKey] = [
|
||
'username' => $username,
|
||
'login_at' => date('c'), // ISO-8601 Datum/Zeit der Anmeldung
|
||
];
|
||
|
||
// Nach erfolgreicher Anmeldung zum Dashboard weiterleiten.
|
||
header('Location: index.php?route=dashboard');
|
||
exit;
|
||
}
|
||
|
||
/**
|
||
* Meldet den aktuell eingeloggten Benutzer ab, indem der entsprechende Session-Eintrag entfernt wird,
|
||
* und leitet anschließend zurück auf die Login-Seite.
|
||
*/
|
||
public function logout(): void
|
||
{
|
||
// Session-Key für den eingeloggten Benutzer aus der Konfiguration lesen.
|
||
$sessionKey = $this->config['security']['session_key_user'] ?? 'admin_user';
|
||
|
||
// Eintrag aus der Session entfernen → Benutzer gilt als ausgeloggt.
|
||
unset($_SESSION[$sessionKey]);
|
||
|
||
// Zur Login-Seite zurückleiten.
|
||
header('Location: index.php?route=login');
|
||
exit;
|
||
}
|
||
|
||
/**
|
||
* Fallback-Ausgabe für das Login-Formular, falls noch keine separate View-Datei existiert.
|
||
* Gibt direkt HTML aus (inline-Template).
|
||
*/
|
||
private function renderInlineLogin(?string $errorMessage): void
|
||
{
|
||
?>
|
||
<!doctype html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>AD Admin Tool – Login</title>
|
||
</head>
|
||
<body>
|
||
<h1>AD Admin Tool – Login</h1>
|
||
|
||
<?php if ($errorMessage !== null): ?>
|
||
<!-- Fehlermeldung ausgeben, HTML-Ausgabe wird dabei sicher maskiert -->
|
||
<p style="color: red;"><?php echo htmlspecialchars($errorMessage, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); ?></p>
|
||
<?php endif; ?>
|
||
|
||
<!-- Einfaches Login-Formular, das per POST an die Route "login.submit" gesendet wird -->
|
||
<form action="index.php?route=login.submit" method="post">
|
||
<div>
|
||
<label for="username">Benutzername:</label>
|
||
<input type="text" id="username" name="username" required>
|
||
</div>
|
||
|
||
<div>
|
||
<label for="password">Passwort:</label>
|
||
<input type="password" id="password" name="password" required>
|
||
</div>
|
||
|
||
<button type="submit">Anmelden</button>
|
||
</form>
|
||
|
||
</body>
|
||
</html>
|
||
<?php
|
||
}
|
||
}
|