System-Test
';
// 1. PHP Version
echo "
1. PHP Version
";
echo "PHP Version: " . phpversion() . "
";
// 2. Config.php vorhanden?
echo "
2. Config.php Check
";
if (file_exists('config.php')) {
echo "✓ config.php existiert
";
require_once 'config.php';
echo "✓ config.php geladen
";
echo "DB_HOST: " . DB_HOST . "
";
echo "DB_NAME: " . DB_NAME . "
";
} else {
echo "✗ config.php nicht gefunden!
";
}
// 3. Datenbankverbindung
echo "
3. Datenbankverbindung
";
try {
$pdo = new PDO(
"mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4",
DB_USER,
DB_PASS
);
echo "✓ Datenbankverbindung erfolgreich
";
// Tabellen prüfen
$tables = $pdo->query("SHOW TABLES")->fetchAll(PDO::FETCH_COLUMN);
echo "✓ Gefundene Tabellen: " . implode(", ", $tables) . "
";
} catch (PDOException $e) {
echo "✗ Datenbankfehler: " . $e->getMessage() . "
";
}
// 4. Includes prüfen
echo "
4. Include-Dateien
";
$files = ['includes/Database.php', 'includes/Auth.php', 'includes/UniFiController.php'];
foreach ($files as $file) {
if (file_exists($file)) {
echo "✓ $file existiert
";
try {
require_once $file;
echo "✓ $file geladen
";
} catch (Exception $e) {
echo "✗ Fehler beim Laden von $file: " . $e->getMessage() . "
";
}
} else {
echo "✗ $file nicht gefunden!
";
}
}
// 5. Database-Klasse testen
echo "
5. Database-Klasse
";
try {
$db = Database::getInstance();
echo "✓ Database::getInstance() erfolgreich
";
$result = $db->fetchOne("SELECT COUNT(*) as count FROM users");
echo "✓ Anzahl Benutzer: " . $result['count'] . "
";
} catch (Exception $e) {
echo "✗ Database-Fehler: " . $e->getMessage() . "
";
}
// 6. Auth-Klasse testen
echo "
6. Auth-Klasse
";
try {
$auth = new Auth();
echo "✓ Auth-Klasse initialisiert
";
echo "Eingeloggt: " . ($auth->isLoggedIn() ? 'Ja' : 'Nein') . "
";
} catch (Exception $e) {
echo "✗ Auth-Fehler: " . $e->getMessage() . "
";
}
// 7. Session-Test
echo "
7. Session
";
echo "Session Status: " . session_status() . " (1=disabled, 2=active)
";
echo "Session ID: " . session_id() . "
";
// 8. UniFi API Diagnose
echo "
8. UniFi API Diagnose
";
try {
$db2 = Database::getInstance();
$site = $db2->fetchOne("SELECT * FROM sites WHERE is_active = 1 ORDER BY id ASC LIMIT 1");
if (!$site) {
echo "✗ Keine aktive Site in der Datenbank gefunden
";
} else {
echo "Site:
" . htmlspecialchars($site['name']) . "";
echo "Controller URL:
" . htmlspecialchars($site['unifi_controller_url']) . "";
echo "Site ID:
" . htmlspecialchars($site['site_id']) . "";
echo "Username:
" . htmlspecialchars($site['unifi_username']) . "";
echo "
";
// --- Raw Login Test ---
echo "
Login-Test (raw cURL):";
$cookieFile = tempnam(sys_get_temp_dir(), 'UNIFI_TEST_');
$csrfToken = null;
$controllerUrl = rtrim($site['unifi_controller_url'], '/');
$ch = curl_init();
$responseHeaders = [];
curl_setopt_array($ch, [
CURLOPT_URL => $controllerUrl . "/api/auth/login",
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
'username' => $site['unifi_username'],
'password' => Crypto::decrypt($site['unifi_password'])
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_COOKIEJAR => $cookieFile,
CURLOPT_COOKIEFILE => $cookieFile,
CURLOPT_TIMEOUT => 10,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Origin: ' . $controllerUrl,
'Referer: ' . $controllerUrl . '/login',
],
CURLOPT_HEADERFUNCTION => function($ch, $header) use (&$csrfToken, &$responseHeaders) {
$responseHeaders[] = rtrim($header);
$parts = explode(':', $header, 2);
if (count($parts) === 2 && strtolower(trim($parts[0])) === 'x-csrf-token') {
$csrfToken = trim($parts[1]);
}
return strlen($header);
}
]);
$body = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlErr = curl_error($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($curlErr) {
echo "✗ cURL Fehler: " . htmlspecialchars($curlErr) . "
";
} else {
$icon = ($httpCode === 200) ? '✓' : '✗';
echo "$icon HTTP Code:
$httpCode";
echo "Effective URL:
" . htmlspecialchars($info['url']) . "";
}
// Response headers
echo "
Response-Header:";
foreach ($responseHeaders as $h) {
if ($h !== '') echo htmlspecialchars($h) . "\n";
}
echo "";
// CSRF token
if ($csrfToken !== null) {
echo "✓ X-CSRF-Token aus Header:
" . htmlspecialchars($csrfToken) . "";
} else {
echo "✗ Kein X-CSRF-Token im Login-Response-Header gefunden
";
// Check cookie file fallback
if (file_exists($cookieFile)) {
$tokenFromCookie = null;
foreach (file($cookieFile) as $line) {
$line = trim($line);
if ($line === '' || $line[0] === '#') continue;
$parts = explode("\t", $line);
if (count($parts) >= 7 && strtoupper($parts[5]) === 'TOKEN') {
$tokenFromCookie = $parts[6];
}
}
if ($tokenFromCookie) {
echo "✓ CSRF-Token aus Cookie-Datei (Fallback):
" . htmlspecialchars($tokenFromCookie) . "";
$csrfToken = $tokenFromCookie;
} else {
echo "✗ Auch kein TOKEN-Cookie in der Cookie-Datei gefunden
";
}
}
}
// Response body
echo "
Login Response Body:";
echo htmlspecialchars(substr($body, 0, 2000));
echo "";
// Cookie file contents
if (file_exists($cookieFile)) {
$cookieContents = file_get_contents($cookieFile);
echo "
Cookie-Datei:";
echo htmlspecialchars($cookieContents ?: '(leer — TOKEN hat Partitioned-Attribut, libcurl schreibt es nicht in die Jar-Datei)');
echo "";
}
// Extract TOKEN from Set-Cookie header (the fix for Partitioned cookie issue)
$tokenCookie = null;
foreach ($responseHeaders as $h) {
if (stripos($h, 'set-cookie:') === 0) {
$cookieVal = trim(substr($h, strlen('set-cookie:')));
$cookieParts = explode(';', $cookieVal);
$first = trim($cookieParts[0]);
if (strpos($first, 'TOKEN=') === 0) {
$tokenCookie = $first;
}
}
}
if ($tokenCookie) {
echo "✓ TOKEN aus Set-Cookie-Header extrahiert:
" . htmlspecialchars(substr($tokenCookie, 0, 40)) . "…";
} else {
echo "✗ TOKEN nicht in Set-Cookie-Header gefunden
";
}
// --- API Test (only if login succeeded) ---
if ($httpCode === 200) {
echo "
API-Test (stat/voucher GET) — mit extrahiertem Cookie:";
$apiHeaders = ['Content-Type: application/json'];
if ($csrfToken !== null) {
$apiHeaders[] = 'X-CSRF-Token: ' . $csrfToken;
}
$ch2 = curl_init();
$apiOpts = [
CURLOPT_URL => $controllerUrl . "/proxy/network/api/s/" . $site['site_id'] . "/stat/voucher",
CURLOPT_HTTPGET => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => 10,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_HTTPHEADER => $apiHeaders,
];
if ($tokenCookie !== null) {
$apiOpts[CURLOPT_COOKIE] = $tokenCookie;
} else {
$apiOpts[CURLOPT_COOKIEFILE] = $cookieFile;
}
curl_setopt_array($ch2, $apiOpts);
$apiBody = curl_exec($ch2);
$apiCode = curl_getinfo($ch2, CURLINFO_HTTP_CODE);
$apiErr = curl_error($ch2);
curl_close($ch2);
if ($apiErr) {
echo "✗ cURL Fehler: " . htmlspecialchars($apiErr) . "
";
} else {
$icon2 = ($apiCode === 200) ? '✓' : '✗';
echo "$icon2 HTTP Code:
$apiCode";
}
echo "
API Response Body:";
echo htmlspecialchars(substr($apiBody, 0, 2000));
echo "";
}
@unlink($cookieFile);
}
} catch (Exception $e) {
echo "✗ Diagnose-Fehler: " . htmlspecialchars($e->getMessage()) . "
";
}
echo "
";
echo "
Test abgeschlossen
";
echo "
Zum Login "
. "Zur Startseite
";
echo "
";
?>