Website-fabianschieder/adminer/user_auth.php

117 lines
3.5 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/auth.php';
require_once __DIR__ . '/env.php';
/**
* App-Login (schöne Login-Seite) für /adminer.
* Nutzer werden in einer MySQL-Tabelle gespeichert.
*
* Wir nutzen die DB-Verbindungsdaten aus .env (DB_*), um die User-Tabelle zu hosten.
*/
function adminer_app_session_start()
{
if (session_status() === PHP_SESSION_NONE) {
ini_set('session.cookie_httponly', '1');
if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
ini_set('session.cookie_secure', '1');
}
session_start();
}
}
function adminer_app_pdo()
{
$vars = env_load(dirname(__DIR__) . '/.env');
$host = env_get($vars, 'DB_SERVERNAME', 'localhost');
$port = (int)env_get($vars, 'DB_PORT', '3306');
$user = env_get($vars, 'DB_USERNAME', '');
$pass = env_get($vars, 'DB_PASSWORD', '');
$db = env_get($vars, 'DB_DATABASE', '');
if ($host === '' || $port <= 0 || $user === '' || $db === '') {
throw new RuntimeException('DB_* ist in .env nicht vollständig gesetzt (für Admin-Login-User-Store).');
}
$dsn = sprintf('mysql:host=%s;port=%d;dbname=%s;charset=utf8mb4', $host, $port, $db);
return new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
}
function adminer_app_bootstrap()
{
$pdo = adminer_app_pdo();
// Minimal users table
$pdo->exec(
'CREATE TABLE IF NOT EXISTS adminer_users ('
. 'id INT AUTO_INCREMENT PRIMARY KEY,'
. 'username VARCHAR(190) NOT NULL UNIQUE,'
. 'password_hash VARCHAR(255) NOT NULL,'
. 'created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP'
. ') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4'
);
// Optional: auto-seed from .env ADMINER_APP_SEED_USER/PASS
$vars = env_load(dirname(__DIR__) . '/.env');
$seedUser = env_get($vars, 'ADMINER_APP_SEED_USER', '');
$seedPass = env_get($vars, 'ADMINER_APP_SEED_PASS', '');
if ($seedUser !== '' && $seedPass !== '') {
$stmt = $pdo->prepare('SELECT id FROM adminer_users WHERE username = ?');
$stmt->execute([$seedUser]);
$exists = (bool)$stmt->fetchColumn();
if (!$exists) {
$hash = password_hash($seedPass, PASSWORD_DEFAULT);
$ins = $pdo->prepare('INSERT INTO adminer_users (username, password_hash) VALUES (?, ?)');
$ins->execute([$seedUser, $hash]);
}
}
}
function adminer_app_is_logged_in()
{
adminer_app_session_start();
return !empty($_SESSION['adminer_app']['ok']);
}
function adminer_app_logout()
{
adminer_app_session_start();
unset($_SESSION['adminer_app']);
}
function adminer_app_try_login($username, $password)
{
$username = trim((string)$username);
$password = (string)$password;
if ($username === '' || $password === '') {
return ['ok' => false, 'error' => 'Bitte Benutzername und Passwort eingeben.'];
}
$pdo = adminer_app_pdo();
$stmt = $pdo->prepare('SELECT id, password_hash FROM adminer_users WHERE username = ?');
$stmt->execute([$username]);
$row = $stmt->fetch();
if (!$row || empty($row['password_hash']) || !password_verify($password, (string)$row['password_hash'])) {
return ['ok' => false, 'error' => 'Login fehlgeschlagen.'];
}
adminer_app_session_start();
$_SESSION['adminer_app'] = [
'ok' => true,
'username' => $username,
'uid' => (int)$row['id'],
];
return ['ok' => true, 'error' => null];
}