PHP_AdminTool_Projekt/app/Controllers/UserManagementController.php

315 lines
10 KiB
PHP

<?php
// Strenge Typprüfung für Parameter- und Rückgabetypen aktivieren.
declare(strict_types=1);
namespace App\Controllers;
use App\Services\Ldap\LdapDirectoryService;
use App\Services\Logging\LoggingService;
/**
* Controller für die Benutzer- und Gruppenanzeige.
*
* Aufgaben:
* - holt über den LdapDirectoryService die Listen von Benutzern und Gruppen
* - behandelt technische Fehler und bereitet eine Fehlermeldung für die View auf
* - gibt die Daten an eine View-Datei (public/views/users.php) weiter
*
* WICHTIG:
* - Es werden aktuell nur Daten angezeigt (Read-only).
* - Es findet keine Änderung im Active Directory statt.
*
* NEU:
* - Gibt ein View-Result-Array zurück, das von index.php + Layout gerendert wird.
*/
class UserManagementController
{
/** @var array<string, mixed> Vollständige Anwendungskonfiguration (aus config.php) */
private array $config;
/** @var LdapDirectoryService Service für das Lesen von Benutzern und Gruppen aus dem LDAP/AD */
private LdapDirectoryService $directoryService;
/** @var LoggingService Logger für technische Fehler */
private LoggingService $logger;
/**
* @param array<string, mixed> $config Vollständige Konfiguration aus config.php
*/
public function __construct(array $config)
{
// Komplette Konfiguration speichern (falls später weitere Werte benötigt werden).
$this->config = $config;
// LDAP-Konfiguration aus der Gesamt-Konfiguration herausziehen.
$ldapConfig = $config['ldap'] ?? [];
// Directory-Service initialisieren, der die eigentliche LDAP-Arbeit übernimmt.
$this->directoryService = new LdapDirectoryService($ldapConfig);
// Logging-Service initialisieren.
$this->logger = new LoggingService($config['logging'] ?? []);
}
/**
* Zeigt Benutzer- und Gruppenliste an.
* Wird typischerweise über die Route "users" (index.php?route=users) aufgerufen.
*
* @return array<string, mixed> View-Result für das zentrale Layout
*/
public function show(): array
{
// Standardwerte für die View-Variablen vorbereiten.
$error = null;
$users = [];
$groups = [];
try {
// Benutzer- und Gruppenlisten aus dem AD laden.
$users = $this->directoryService->getUsers();
$groups = $this->directoryService->getGroups();
} catch (\Throwable $exception) {
// Technische Details ins Log, für den Benutzer eine allgemeine Meldung.
$this->logger->logException(
'Fehler beim Laden von Benutzern/Gruppen.',
$exception,
[
'route' => 'users',
'remote_addr' => $_SERVER['REMOTE_ADDR'] ?? null,
]
);
$error = 'Fehler beim Laden von Benutzern/Gruppen. '
. 'Bitte versuchen Sie es später erneut oder wenden Sie sich an den Administrator.';
}
// Pfad zur eigentlichen View-Datei bestimmen.
$viewPath = __DIR__ . '/../../public/views/users.php';
return [
'view' => $viewPath,
'data' => [
// Die View erwartet aktuell $users, $groups, $error.
'users' => $users,
'groups' => $groups,
'error' => $error,
'loginPage' => false,
],
'pageTitle' => 'Benutzer & Gruppen',
'activeMenu' => 'users',
];
}
/**
* Zeigt das Formular zum Anlegen eines neuen Benutzers (Platzhalter).
* @return array<string, mixed>
*/
public function create(): array
{
// CSRF token sicherstellen
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(16));
}
$viewPath = __DIR__ . '/../../public/views/users_create.php';
return [
'view' => $viewPath,
'data' => [
'loginPage' => false,
'csrf_token' => $_SESSION['csrf_token'],
],
'pageTitle' => 'Benutzer hinzufügen',
'activeMenu' => 'users',
'activeSubMenu' => 'create',
];
}
/**
* Verarbeitet das Absenden des 'Benutzer hinzufügen'-Formulars (Platzhalter,
* führt keine LDAP-Änderung aus, validiert aber Eingaben).
*
* @return array<string, mixed>
*/
public function createSubmit(): array
{
$errors = [];
// CSRF prüfen
$token = $_POST['csrf_token'] ?? '';
if (empty($token) || !isset($_SESSION['csrf_token']) || hash_equals($_SESSION['csrf_token'], $token) === false) {
$errors[] = 'Ungültiger CSRF-Token.';
}
$username = trim((string)($_POST['username'] ?? ''));
$firstname = trim((string)($_POST['givenName'] ?? ''));
$lastname = trim((string)($_POST['sn'] ?? ''));
$email = trim((string)($_POST['mail'] ?? ''));
if ($username === '') {
$errors[] = 'Benutzername wird benötigt.';
}
if ($email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$errors[] = 'E-Mail-Adresse ist ungültig.';
}
// Für jetzt nur eine Erfolgsmeldung (keine AD-Operation)
$viewPath = __DIR__ . '/../../public/views/users_create.php';
$data = [
'loginPage' => false,
'csrf_token' => $_SESSION['csrf_token'],
];
if (!empty($errors)) {
$data['errors'] = $errors;
$data['form'] = [
'username' => $username,
'givenName' => $firstname,
'sn' => $lastname,
'mail' => $email,
];
return [
'view' => $viewPath,
'data' => $data,
'pageTitle' => 'Benutzer hinzufügen',
'activeMenu' => 'users',
'activeSubMenu' => 'create',
];
}
$data['success'] = 'Benutzer-Formular erfolgreich validiert (Platzhalter, wurde nicht angelegt).';
$data['form'] = ['username' => $username];
return [
'view' => $viewPath,
'data' => $data,
'pageTitle' => 'Benutzer hinzufügen',
'activeMenu' => 'users',
'activeSubMenu' => 'create',
];
}
/**
* Zeigt das CSV-Import-Formular (Platzhalter).
* @return array<string, mixed>
*/
public function import(): array
{
// CSRF token sicherstellen
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(16));
}
$viewPath = __DIR__ . '/../../public/views/users_import.php';
return [
'view' => $viewPath,
'data' => [
'loginPage' => false,
'csrf_token' => $_SESSION['csrf_token'],
],
'pageTitle' => 'Benutzer importieren (CSV)',
'activeMenu' => 'users',
'activeSubMenu' => 'import',
];
}
/**
* Verarbeitet CSV-Upload und zeigt eine Vorschau der ersten Zeilen (Platzhalter).
*
* @return array<string, mixed>
*/
public function importSubmit(): array
{
$errors = [];
// CSRF prüfen
$token = $_POST['csrf_token'] ?? '';
if (empty($token) || !isset($_SESSION['csrf_token']) || hash_equals($_SESSION['csrf_token'], $token) === false) {
$errors[] = 'Ungültiger CSRF-Token.';
}
if (!isset($_FILES['csv_file']) || $_FILES['csv_file']['error'] !== UPLOAD_ERR_OK) {
$errors[] = 'Bitte eine gültige CSV-Datei hochladen.';
}
$preview = [];
if (empty($errors)) {
$tmp = $_FILES['csv_file']['tmp_name'];
if (($handle = fopen($tmp, 'r')) !== false) {
$row = 0;
while (($data = fgetcsv($handle, 0, ',')) !== false && $row < 50) {
$preview[] = $data;
$row++;
}
fclose($handle);
} else {
$errors[] = 'Die hochgeladene Datei konnte nicht gelesen werden.';
}
}
$viewPath = __DIR__ . '/../../public/views/users_import.php';
$data = [
'loginPage' => false,
'csrf_token' => $_SESSION['csrf_token'],
];
if (!empty($errors)) {
$data['errors'] = $errors;
} else {
$data['preview'] = $preview;
$data['success'] = 'CSV-Datei erfolgreich hochgeladen. Vorschau der ersten Zeilen:';
}
return [
'view' => $viewPath,
'data' => $data,
'pageTitle' => 'Benutzer importieren (CSV)',
'activeMenu' => 'users',
'activeSubMenu' => 'import',
];
}
/**
* Zeigt die Benutzersuche (Platzhalter).
* @return array<string, mixed>
*/
public function search(): array
{
$query = trim((string)($_GET['q'] ?? ''));
$users = [];
if ($query !== '') {
try {
$allUsers = $this->directoryService->getUsers();
foreach ($allUsers as $u) {
$hay = strtolower($u['samaccountname'] . ' ' . $u['displayname'] . ' ' . $u['mail']);
if (strpos($hay, strtolower($query)) !== false) {
$users[] = $u;
}
}
} catch (\Throwable $e) {
$this->logger->logException('Fehler bei Benutzersuche.', $e, ['query' => $query]);
}
}
$viewPath = __DIR__ . '/../../public/views/users_search.php';
return [
'view' => $viewPath,
'data' => [
'loginPage' => false,
'query' => $query,
'results' => $users,
],
'pageTitle' => 'Benutzer suchen',
'activeMenu' => 'users',
'activeSubMenu' => 'search',
];
}
}