Reviewed-on: https://git.eckertplayground.de/taarly/PHP_AdminTool_Projekt/pulls/24 Co-authored-by: blaerf <blaerf@gmx.de> Co-committed-by: blaerf <blaerf@gmx.de>
164 lines
6.2 KiB
PHP
164 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;
|
|
use App\Services\Logging\LoggingService;
|
|
|
|
/**
|
|
* Zuständig für alles rund um den Login:
|
|
* - Login-Formular anzeigen
|
|
* - Login-Daten verarbeiten (Authentifizierung gegen LDAP/AD)
|
|
* - Logout durchführen
|
|
*
|
|
* NEU:
|
|
* - Statt direkt HTML auszugeben oder header()-Redirects zu setzen,
|
|
* liefert der Controller "View-Results" zurück, die von index.php
|
|
* und einem zentralen Layout verarbeitet werden.
|
|
*/
|
|
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;
|
|
|
|
/** @var LoggingService Logger für technische Fehler */
|
|
private LoggingService $logger;
|
|
|
|
/**
|
|
* Ü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'] ?? []);
|
|
|
|
// LoggingService mit dem Teilbereich "logging" aus der Konfiguration initialisieren.
|
|
$this->logger = new LoggingService($config['logging'] ?? []);
|
|
}
|
|
|
|
/**
|
|
* Zeigt das Login-Formular an.
|
|
* Optional kann eine Fehlermeldung übergeben werden, die in der View dargestellt wird.
|
|
*
|
|
* @return array<string, mixed> View-Result für das zentrale Layout
|
|
*/
|
|
public function showLoginForm(?string $errorMessage = null): array
|
|
{
|
|
// Pfad zur Login-View (Template-Datei) ermitteln.
|
|
$viewPath = __DIR__ . '/../../public/views/login.php';
|
|
|
|
// Wichtig: Die View erwartet aktuell die Variable $error.
|
|
return [
|
|
'view' => $viewPath,
|
|
'data' => [
|
|
'error' => $errorMessage,
|
|
'loginPage' => true,
|
|
],
|
|
'pageTitle' => 'Login',
|
|
// Beim Login ist typischerweise kein Menüpunkt aktiv.
|
|
'activeMenu' => null,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Verarbeitet das Login-Formular:
|
|
* - Liest Benutzername und Passwort aus $_POST
|
|
* - Ruft den LdapAuthService zur Authentifizierung auf
|
|
* - Liefert bei Erfolg ein Redirect-Result zum Dashboard
|
|
* - Liefert bei Fehlern ein View-Result für das Login-Formular mit Fehlermeldung
|
|
*
|
|
* @return array<string, mixed> View-Result ODER Redirect-Result
|
|
*/
|
|
public function processLogin(): array
|
|
{
|
|
// 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) {
|
|
// HIER ist vorher dein Fehler entstanden:
|
|
// - showLoginForm() wurde nur aufgerufen, das Ergebnis aber ignoriert
|
|
// - danach kam ein "return;" ohne Rückgabewert → Rückgabetyp array wurde verletzt
|
|
|
|
// Technischen Fehler ausführlich ins Log schreiben
|
|
$this->logger->logException(
|
|
'Technischer Fehler bei der Anmeldung.',
|
|
$exception,
|
|
[
|
|
'route' => 'login.submit',
|
|
'username' => $username,
|
|
'remote_addr'=> $_SERVER['REMOTE_ADDR'] ?? null,
|
|
]
|
|
);
|
|
|
|
// Für den Benutzer nur eine allgemeine, aber verständliche Meldung anzeigen
|
|
return $this->showLoginForm(
|
|
'Technischer Fehler bei der Anmeldung. Bitte versuchen Sie es später erneut '
|
|
. 'oder wenden Sie sich an den Administrator.'
|
|
);
|
|
}
|
|
|
|
// Fachlich fehlgeschlagene Anmeldung (z. B. falsches Passwort).
|
|
if ($authenticated === false) {
|
|
return $this->showLoginForm('Benutzername oder Passwort ist ungültig.');
|
|
}
|
|
|
|
// 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() bzw. im Layout ausgewertet.
|
|
$_SESSION[$sessionKey] = [
|
|
'username' => $username,
|
|
'login_at' => date('c'), // ISO-8601 Datum/Zeit der Anmeldung
|
|
];
|
|
|
|
// Nach erfolgreicher Anmeldung zum Dashboard weiterleiten.
|
|
// Kein direkter header()-Aufruf, sondern ein Redirect-Result
|
|
// für die zentrale Steuerung in index.php.
|
|
return [
|
|
'redirect' => 'index.php?route=dashboard',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Meldet den aktuell eingeloggten Benutzer ab, indem der entsprechende Session-Eintrag entfernt wird,
|
|
* und liefert anschließend ein Redirect-Result zurück auf die Login-Seite.
|
|
*
|
|
* @return array<string, mixed> Redirect-Result
|
|
*/
|
|
public function logout(): array
|
|
{
|
|
// 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]);
|
|
|
|
// Redirect-Result zur Login-Seite.
|
|
return [
|
|
'redirect' => 'index.php?route=login',
|
|
];
|
|
}
|
|
}
|