Code refactoring und Kommentare hinzugefügt
This commit is contained in:
parent
7bde20e968
commit
61a517ada7
167
app/Controllers/AuthController.php
Normal file
167
app/Controllers/AuthController.php
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
<?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
|
||||||
|
}
|
||||||
|
}
|
||||||
98
app/Services/Ldap/LdapAuthService.php
Normal file
98
app/Services/Ldap/LdapAuthService.php
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Strenge Typprüfung für Parameter- und Rückgabetypen aktivieren.
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Services\Ldap;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service zur Authentifizierung von Benutzern gegen ein Active Directory per LDAP/LDAPS.
|
||||||
|
* Bekommt Benutzername und Passwort und liefert:
|
||||||
|
* - true -> Anmeldedaten sind gültig
|
||||||
|
* - false -> Anmeldedaten sind fachlich ungültig (z. B. falsches Passwort)
|
||||||
|
* Technische Fehler (z. B. falsche Konfiguration, keine Verbindung) werden als Exception geworfen.
|
||||||
|
*/
|
||||||
|
class LdapAuthService
|
||||||
|
{
|
||||||
|
/** @var array<string, mixed> LDAP-spezifische Konfiguration (Server, Port, Domain-Suffix, Timeout, etc.) */
|
||||||
|
private array $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erwartet den Teilbereich "ldap" aus der allgemeinen Konfiguration (config.php).
|
||||||
|
*
|
||||||
|
* @param array<string, mixed> $ldapConfig Konfiguration für die LDAP-Verbindung
|
||||||
|
*/
|
||||||
|
public function __construct(array $ldapConfig)
|
||||||
|
{
|
||||||
|
// LDAP-Konfiguration in der Instanz speichern.
|
||||||
|
$this->config = $ldapConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Führt die eigentliche LDAP/AD-Authentifizierung durch.
|
||||||
|
*
|
||||||
|
* @param string $username Benutzername (ohne Domain-Suffix, z. B. "administrator")
|
||||||
|
* @param string $password Passwort im Klartext (wird direkt an ldap_bind übergeben)
|
||||||
|
*
|
||||||
|
* @return bool true bei erfolgreicher Anmeldung, false bei fachlich ungültigen Anmeldedaten
|
||||||
|
*
|
||||||
|
* @throws RuntimeException bei technischen Problemen (z. B. fehlende Konfiguration, Verbindungsfehler)
|
||||||
|
*/
|
||||||
|
public function authenticate(string $username, string $password): bool
|
||||||
|
{
|
||||||
|
// Wenn Benutzername oder Passwort leer sind, gar nicht erst versuchen zu binden.
|
||||||
|
// Das ist ein fachlich ungültiger Login und wird mit false behandelt.
|
||||||
|
if ($username === '' || $password === '') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Benötigte Werte aus der LDAP-Konfiguration auslesen.
|
||||||
|
// Falls einzelne Werte fehlen, werden sinnvolle Standardwerte gesetzt.
|
||||||
|
$server = (string)($this->config['server'] ?? '');
|
||||||
|
$port = (int)($this->config['port'] ?? 636);
|
||||||
|
$domainSuffix = (string)($this->config['domain_suffix'] ?? '');
|
||||||
|
$timeout = (int)($this->config['timeout'] ?? 5);
|
||||||
|
|
||||||
|
// Ohne Server-Adresse oder Domain-Suffix ist eine sinnvolle Anmeldung nicht möglich.
|
||||||
|
// Das ist ein Konfigurationsfehler und wird als technischer Fehler behandelt.
|
||||||
|
if ($server === '' || $domainSuffix === '') {
|
||||||
|
throw new RuntimeException('LDAP-Konfiguration ist unvollständig.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verbindung zum LDAP/AD-Server herstellen.
|
||||||
|
// Rückgabewert ist eine Ressource (Verbindungshandle) oder false bei Fehlern.
|
||||||
|
$connection = ldap_connect($server, $port);
|
||||||
|
|
||||||
|
if ($connection === false) {
|
||||||
|
throw new RuntimeException('LDAP-Verbindung konnte nicht aufgebaut werden.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// LDAP-Optionen setzen:
|
||||||
|
// - Protokollversion 3 (Standard in aktuellen Umgebungen)
|
||||||
|
// - Netzwerk-Timeout, damit die Anfrage nicht unendlich hängt
|
||||||
|
ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||||
|
ldap_set_option($connection, LDAP_OPT_NETWORK_TIMEOUT, $timeout);
|
||||||
|
|
||||||
|
// UPN (User Principal Name) aus Benutzername und Domain-Suffix bilden.
|
||||||
|
// Beispiel: "administrator" + "@ITFA-PROJ-DOM.local" -> "administrator@ITFA-PROJ-DOM.local"
|
||||||
|
$bindRdn = $username . $domainSuffix;
|
||||||
|
|
||||||
|
// Eigentliche Authentifizierung:
|
||||||
|
// ldap_bind versucht, sich mit den angegebenen Anmeldedaten am AD/LDAP anzumelden.
|
||||||
|
// Rückgabewerte:
|
||||||
|
// - true -> Anmeldedaten sind gültig
|
||||||
|
// - false -> Anmeldedaten sind ungültig (z. B. falsches Passwort)
|
||||||
|
//
|
||||||
|
// Das @-Zeichen unterdrückt PHP-Warnings, damit Fehlermeldungen nicht unformatiert im HTML landen.
|
||||||
|
$bindResult = @ldap_bind($connection, $bindRdn, $password);
|
||||||
|
|
||||||
|
// Verbindung zum LDAP-Server wieder schließen.
|
||||||
|
ldap_unbind($connection);
|
||||||
|
|
||||||
|
// Bei erfolgreichem Bind (true) -> Authentifizierung erfolgreich.
|
||||||
|
// Bei false -> fachlich fehlgeschlagene Anmeldung (z. B. falsche Credentials).
|
||||||
|
return $bindResult === true;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
config/config.php
Normal file
27
config/config.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/** Typsicherheit aktivieren
|
||||||
|
* var = "1" != var = 1
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'ldap' => [
|
||||||
|
// LDAP-URL des Domain Controllers
|
||||||
|
'server' => 'ITFA-PROJ-SRV.ITFA-PROJ-DOM.local',
|
||||||
|
'port' => 389,
|
||||||
|
|
||||||
|
// wird an den Benutzernamen angehängt (z.B. "admin" + "@ITFA-PROJ-DOM.local")
|
||||||
|
'domain_suffix' => '@ITFA-PROJ-DOM.local',
|
||||||
|
|
||||||
|
// Base DN der Domäne
|
||||||
|
'base_dn' => 'DC=ITFA-PROJ-DOM,DC=local',
|
||||||
|
|
||||||
|
// Optional: Timeout in Sekunden
|
||||||
|
'timeout' => 5,
|
||||||
|
],
|
||||||
|
|
||||||
|
'security' => [
|
||||||
|
// Session-Key unter dem der eingeloggte Admin gespeichert wird
|
||||||
|
'session_key_user' => 'admin_user',
|
||||||
|
],
|
||||||
|
];
|
||||||
100
public/index.php
Normal file
100
public/index.php
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Strenge Typprüfung für Parameter- und Rückgabetypen aktivieren.
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
// Eine neue Session wird gestartet und die entsprechende Variable ($_SESSION) angelegt oder eine bestehende wird fortgesetzt.
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Registriert eine Autoload-Funktion für Klassen mit dem Namespace-Präfix "App\".
|
||||||
|
* Statt jede Klasse manuell über "require pfad_zur_klasse.php" einzubinden,
|
||||||
|
* versucht PHP nun automatisch, die passende Datei zu laden, sobald eine Klasse
|
||||||
|
* im Namespace "App\..." verwendet wird.
|
||||||
|
*/
|
||||||
|
spl_autoload_register(
|
||||||
|
// Anonyme Funktion, die den Klassennamen prüft und den Dateipfad zur Klasse ermittelt.
|
||||||
|
static function (string $class): void {
|
||||||
|
$prefix = 'App\\';
|
||||||
|
$baseDir = __DIR__ . '/../app/';
|
||||||
|
|
||||||
|
$len = strlen($prefix);
|
||||||
|
if (strncmp($prefix, $class, $len) !== 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$relativeClass = substr($class, $len);
|
||||||
|
$file = $baseDir . str_replace('\\', DIRECTORY_SEPARATOR, $relativeClass) . '.php';
|
||||||
|
|
||||||
|
if (file_exists($file) === true) {
|
||||||
|
require $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Pfad zur Konfigurationsdatei prüfen und Konfiguration laden
|
||||||
|
$configPath = __DIR__ . '/../config/config.php';
|
||||||
|
if (file_exists($configPath) === false) {
|
||||||
|
// Fail fast: ohne Konfiguration macht die App keinen Sinn
|
||||||
|
http_response_code(500);
|
||||||
|
echo 'Konfigurationsdatei config/config.php wurde nicht gefunden. '
|
||||||
|
. 'Bitte config.example.php kopieren und anpassen.';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var array<string, mixed> $config */
|
||||||
|
$config = require $configPath;
|
||||||
|
|
||||||
|
use App\Controllers\AuthController;
|
||||||
|
|
||||||
|
// Hilfsfunktion für geschützte Routen
|
||||||
|
function requireLogin(array $config): void
|
||||||
|
{
|
||||||
|
// session_key_user aus dem Config-Array lesen. Wenn nicht gesetzt oder null, Standard "admin_user" verwenden.
|
||||||
|
$sessionKey = $config['security']['session_key_user'] ?? 'admin_user';
|
||||||
|
|
||||||
|
// Prüfen, ob in $_SESSION unter diesem Key ein eingeloggter Benutzer hinterlegt ist.
|
||||||
|
// Falls nicht, zurück zur Login-Seite umleiten.
|
||||||
|
if (isset($_SESSION[$sessionKey]) === false) {
|
||||||
|
header('Location: index.php?route=login');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route aus dem GET-Parameter lesen. Wenn nicht gesetzt, Standardroute "login" verwenden.
|
||||||
|
$route = $_GET['route'] ?? 'login';
|
||||||
|
|
||||||
|
// Neue Instanz der Klasse AuthController erstellen (wird bei Bedarf über den Autoloader geladen).
|
||||||
|
$authController = new AuthController($config);
|
||||||
|
|
||||||
|
// Anhand des Routing-Ziels (route) entscheiden, welcher Code ausgeführt wird.
|
||||||
|
switch ($route) {
|
||||||
|
case 'login':
|
||||||
|
$authController->showLoginForm();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'login.submit':
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
|
header('Location: index.php?route=login');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$authController->processLogin();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'logout':
|
||||||
|
$authController->logout();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'dashboard':
|
||||||
|
requireLogin($config);
|
||||||
|
// Später: DashboardController aufrufen
|
||||||
|
echo '<h1>Dashboard (Platzhalter)</h1>';
|
||||||
|
echo '<p>Hier kommt später dein SNMP/Server-Status hin.</p>';
|
||||||
|
echo '<p><a href="index.php?route=logout">Logout</a></p>';
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
http_response_code(404);
|
||||||
|
echo 'Route nicht gefunden.';
|
||||||
|
break;
|
||||||
|
}
|
||||||
@ -1,33 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
declare(strict_types=1);
|
||||||
require_once __DIR__ . '/../config/ldap.php';
|
|
||||||
|
|
||||||
$error = "";
|
/**
|
||||||
|
* @var string|null $error
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
*/
|
||||||
var_dump($_POST);
|
|
||||||
$username = isset($_POST['username']) ? trim($_POST['username']) : "";
|
|
||||||
$password = isset($_POST['password']) ? $_POST['password'] : "";
|
|
||||||
|
|
||||||
$ldapConn = ldap_authenticate($username, $password);
|
|
||||||
|
|
||||||
if ($ldapConn === false) {
|
|
||||||
$error = "Anmeldung fehlgeschlagen. Benutzername oder Passwort falsch.";
|
|
||||||
} else {
|
|
||||||
// Optional: User-Infos aus AD lesen, z. B. displayName
|
|
||||||
// $result = ldap_search($ldapConn, $LDAP_BASE_DN, "(sAMAccountName=$username)", ["displayName"]);
|
|
||||||
// $entries = ldap_get_entries($ldapConn, $result);
|
|
||||||
|
|
||||||
$_SESSION['logged_in'] = true;
|
|
||||||
$_SESSION['username'] = $username;
|
|
||||||
// $_SESSION['displayName'] = $entries[0]['displayname'][0] ?? $username;
|
|
||||||
|
|
||||||
ldap_unbind($ldapConn);
|
|
||||||
|
|
||||||
header("Location: dashboard.php");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@ -73,12 +49,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<h1 class="h4 text-gray-900 mb-4">Welcome Back!</h1>
|
<h1 class="h4 text-gray-900 mb-4">Welcome Back!</h1>
|
||||||
</div>
|
</div>
|
||||||
<?php if ($error !== ""): ?>
|
<?php if ($error !== null): ?>
|
||||||
<div class="alert alert-danger" role="alert">
|
<div class="alert alert-danger" role="alert">
|
||||||
<?php echo htmlspecialchars($error); ?>
|
<?php echo htmlspecialchars($error, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); ?>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<form class="user" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
|
<form class="user" method="post" action="index.php?route=login.submit">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" name="username" class="form-control form-control-user"
|
<input type="text" name="username" class="form-control form-control-user"
|
||||||
id="username" aria-describedby="usernameHelp"
|
id="username" aria-describedby="usernameHelp"
|
||||||
|
|||||||
109
public/views/login.php
Normal file
109
public/views/login.php
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|null $error
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>SB Admin 2 - Login</title>
|
||||||
|
|
||||||
|
<!-- Custom fonts for this template-->
|
||||||
|
<link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i"
|
||||||
|
rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template-->
|
||||||
|
<link href="css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="bg-gradient-primary">
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<!-- Outer Row -->
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
|
||||||
|
<div class="col-xl-10 col-lg-12 col-md-9">
|
||||||
|
|
||||||
|
<div class="card o-hidden border-0 shadow-lg my-5">
|
||||||
|
<div class="card-body p-0">
|
||||||
|
<!-- Nested Row within Card Body -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6 d-none d-lg-block bg-login-image"></div>
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="p-5">
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="h4 text-gray-900 mb-4">Welcome Back!</h1>
|
||||||
|
</div>
|
||||||
|
<?php if ($error !== null): ?>
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
<?php echo htmlspecialchars($error, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<form class="user" method="post" action="index.php?route=login.submit">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" name="username" class="form-control form-control-user"
|
||||||
|
id="username" aria-describedby="usernameHelp"
|
||||||
|
placeholder="Enter Username...">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="password" name="password" class="form-control form-control-user"
|
||||||
|
id="password" placeholder="Password">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="custom-control custom-checkbox small">
|
||||||
|
<input type="checkbox" class="custom-control-input" id="customCheck">
|
||||||
|
<label class="custom-control-label" for="customCheck">Remember
|
||||||
|
Me</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary btn-user btn-block">
|
||||||
|
Anmelden
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<hr>
|
||||||
|
<div class="text-center">
|
||||||
|
<a class="small" href="forgot-password.php">Forgot Password?</a>
|
||||||
|
</div>
|
||||||
|
<div class="text-center">
|
||||||
|
<a class="small" href="register.php">Create an Account!</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Bootstrap core JavaScript-->
|
||||||
|
<script src="vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Core plugin JavaScript-->
|
||||||
|
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Custom scripts for all pages-->
|
||||||
|
<script src="js/sb-admin-2.min.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue
Block a user