KI-Backend: Nutzer-Anlage ohne PHP-CLI (setup-user.php)

scripts/create-user.php setzt SSH/CLI-Zugriff voraus, den viele Shared-Hosting-Pakete
nicht haben. setup-user.php ist die web-erreichbare Alternative (Geheimnis in
config.php, per curl von lokal aufrufbar), muss nach Gebrauch aber wieder vom
Server gelöscht werden — sonst bleibt ein Endpunkt zum Anlegen beliebiger Nutzer
erreichbar.
This commit is contained in:
2026-08-16 01:48:51 +02:00
parent 8495e1b8d0
commit 8546eabbdd
4 changed files with 83 additions and 7 deletions
+4
View File
@@ -681,6 +681,10 @@ folgenden Punkte gehören direkt in `LehrerApp.Desktop`:
nicht verifiziert werden konnten (kein Aufschub aus Unklarheit über den Bedarf, sondern um nicht verifiziert werden konnten (kein Aufschub aus Unklarheit über den Bedarf, sondern um
keine falsch berechneten Kosten zu riskieren). Kein Admin-UI für Guthaben-Aufladung — bei der keine falsch berechneten Kosten zu riskieren). Kein Admin-UI für Guthaben-Aufladung — bei der
aktuellen Nutzerzahl reicht ein dokumentierter manueller SQL-Befehl (`ai-backend/README.md`). aktuellen Nutzerzahl reicht ein dokumentierter manueller SQL-Befehl (`ai-backend/README.md`).
Nutzeranlage über `scripts/create-user.php` setzt PHP-CLI/SSH voraus — auf typischem Shared
Hosting ohne CLI-Zugriff gibt es mit `ai-backend/setup-user.php` eine web-erreichbare
Alternative (durch ein Geheimnis in `config.php` geschützt, nach Gebrauch vom Server zu
löschen).
**Nicht ohne echtes Deployment + echten API-Key verifizierbar** (siehe `ai-backend/README.md`): **Nicht ohne echtes Deployment + echten API-Key verifizierbar** (siehe `ai-backend/README.md`):
ob Anthropic zuverlässig valides JSON im erwarteten Schema liefert, ob die berechneten ob Anthropic zuverlässig valides JSON im erwarteten Schema liefert, ob die berechneten
+25 -7
View File
@@ -22,19 +22,37 @@ macht der Nutzer selbst — dieses README beschreibt die nötigen Schritte.
2. `config.example.php` nach `config.php` kopieren und ausfüllen (DB-Zugang, Anthropic-API-Key, 2. `config.example.php` nach `config.php` kopieren und ausfüllen (DB-Zugang, Anthropic-API-Key,
ggf. die Preistabelle gegen die aktuelle Anthropic-Preisseite prüfen — Preise ändern sich). ggf. die Preistabelle gegen die aktuelle Anthropic-Preisseite prüfen — Preise ändern sich).
`config.php` ist in `.gitignore` und darf nie committet werden. `config.php` ist in `.gitignore` und darf nie committet werden.
3. Ersten Nutzer anlegen (weitere Lehrer später genauso): 3. Falls du die Web-Variante aus Schritt 5 nutzen willst (kein PHP-CLI/SSH auf dem Hosting):
```bash `setup_secret` in `config.php` auf einen langen Zufallswert setzen (z.B. per
php scripts/create-user.php sebastian "einStarkesPasswort" 10.00 `openssl rand -hex 32` erzeugt, oder ein beliebiger Passwortgenerator).
```
Der dritte Parameter ist das Startguthaben in USD, optional (Standard 0).
4. Den kompletten `ai-backend/`-Ordner auf den PHP-Server hochladen. **Empfehlung:** `config.php`, 4. Den kompletten `ai-backend/`-Ordner auf den PHP-Server hochladen. **Empfehlung:** `config.php`,
`db.php`, `schema.sql`, `providers/` und `scripts/` außerhalb des öffentlichen Webroots ablegen, `db.php`, `schema.sql`, `providers/` und `scripts/` außerhalb des öffentlichen Webroots ablegen,
falls das Hosting das erlaubt (Pfade in den `require`-Aufrufen entsprechend anpassen) — robuster falls das Hosting das erlaubt (Pfade in den `require`-Aufrufen entsprechend anpassen) — robuster
als sich allein auf die mitgelieferte `.htaccess` zu verlassen, die nur bei Apache mit als sich allein auf die mitgelieferte `.htaccess` zu verlassen, die nur bei Apache mit
aktiviertem `mod_rewrite`/erlaubten `.htaccess`-Overrides greift. aktiviertem `mod_rewrite`/erlaubten `.htaccess`-Overrides greift.
5. In `LehrerApp.Desktop/AppBootstrapper.cs` die Konstante `AiBackendUrl` auf die tatsächlich 5. Ersten Nutzer anlegen (weitere Lehrer später genauso) — zwei Varianten, je nachdem was das
Hosting hergibt:
**Mit PHP-CLI/SSH-Zugriff** (`scripts/create-user.php`):
```bash
php scripts/create-user.php sebastian "einStarkesPasswort" 10.00
```
Der dritte Parameter ist das Startguthaben in USD, optional (Standard 0).
**Ohne CLI/SSH** (übliches Shared Hosting, nur FTP/Webspace) — der Server läuft nach Schritt 4
bereits, also einmalig von deinem eigenen Rechner aus aufrufen:
```bash
curl -X POST https://DEINE-DOMAIN/setup-user.php \
-d '{"secret":"<setup_secret aus config.php>","username":"sebastian","password":"einStarkesPasswort","balanceUsd":10.00}'
```
**Direkt danach `setup-user.php` per FTP wieder vom Server löschen** — sonst bleibt ein
Endpunkt erreichbar, der (mit dem Geheimnis) beliebige Nutzer anlegen kann. Ein erneuter
Aufruf mit demselben Benutzernamen aktualisiert Passwort/Guthaben, falls z.B. das Guthaben
beim ersten Versuch vergessen wurde — dafür braucht es die Datei aber kein zweites Mal auf
dem Server, einfach vor dem Löschen alle nötigen Nutzer in einer Sitzung anlegen.
6. In `LehrerApp.Desktop/AppBootstrapper.cs` die Konstante `AiBackendUrl` auf die tatsächlich
deployte Domain setzen und die App neu bauen. deployte Domain setzen und die App neu bauen.
6. In der App unter Einstellungen → KI-Unterstützung aktivieren und mit dem angelegten Nutzer 7. In der App unter Einstellungen → KI-Unterstützung aktivieren und mit dem angelegten Nutzer
anmelden. anmelden.
## Smoke-Test ohne echten API-Key ## Smoke-Test ohne echten API-Key
+5
View File
@@ -10,6 +10,11 @@ return [
'pass' => 'CHANGE_ME', 'pass' => 'CHANGE_ME',
], ],
// Nur für setup-user.php gebraucht (Web-Alternative zu scripts/create-user.php auf Hosting
// ohne PHP-CLI/SSH) — ein langer Zufallswert, z.B. per `openssl rand -hex 32` erzeugt.
// setup-user.php nach Gebrauch vom Server löschen, siehe README.md.
'setup_secret' => 'CHANGE_ME',
// Nur 'anthropic' ist aktuell fertig implementiert (siehe providers/AnthropicProvider.php). // Nur 'anthropic' ist aktuell fertig implementiert (siehe providers/AnthropicProvider.php).
// Die Provider-Schnittstelle ist so gebaut, dass ein OpenAiProvider später ergänzt werden // Die Provider-Schnittstelle ist so gebaut, dass ein OpenAiProvider später ergänzt werden
// kann — bewusst nicht in dieser Runde, da aktuelle OpenAI-Preise/API-Version zum Zeitpunkt // kann — bewusst nicht in dieser Runde, da aktuelle OpenAI-Preise/API-Version zum Zeitpunkt
+49
View File
@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
// Web-erreichbare Alternative zu scripts/create-user.php, für Hosting ohne PHP-CLI/SSH-Zugriff.
// Durch ein Geheimnis aus config.php geschützt (setup_secret) — WICHTIG: diese Datei nach dem
// Anlegen der benötigten Nutzer wieder vom Server löschen, siehe README.md.
require_once __DIR__ . '/db.php';
header('Content-Type: application/json');
$config = require __DIR__ . '/config.php';
$secret = $config['setup_secret'] ?? null;
if (!is_string($secret) || $secret === '' || $secret === 'CHANGE_ME') {
ai_backend_fail(500, 'setup_secret ist in config.php nicht (sicher) gesetzt.');
}
$body = json_decode(file_get_contents('php://input'), true) ?? [];
if (!hash_equals($secret, (string) ($body['secret'] ?? ''))) {
ai_backend_fail(403, 'Falsches oder fehlendes Geheimnis.');
}
$username = trim((string) ($body['username'] ?? ''));
$password = (string) ($body['password'] ?? '');
$balance = isset($body['balanceUsd']) ? (float) $body['balanceUsd'] : 0.0;
if ($username === '' || $password === '') {
ai_backend_fail(400, 'username und password erforderlich.');
}
$pdo = ai_backend_db($config);
$hash = password_hash($password, PASSWORD_DEFAULT);
// Erneuter Aufruf mit demselben Benutzernamen aktualisiert Passwort/Guthaben, statt einen Fehler
// zu werfen — praktisch, falls beim ersten Versuch z.B. das Guthaben vergessen wurde.
$stmt = $pdo->prepare(
'INSERT INTO users (username, password_hash, balance_usd) VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE password_hash = VALUES(password_hash), balance_usd = VALUES(balance_usd)'
);
$stmt->execute([$username, $hash, $balance]);
echo json_encode([
'ok' => true,
'username' => $username,
'balanceUsd' => $balance,
'hinweis' => 'Nutzer angelegt/aktualisiert. Diese Datei (setup-user.php) jetzt vom Server löschen.',
]);