docs(PROJ-46): QA-Testergebnisse (9/9 PASS auf 192.168.1.132) dokumentieren

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
sysops
2026-07-04 12:38:55 +02:00
co-authored by Claude Sonnet 5
parent 81744562c3
commit 08f486a28c
2 changed files with 374 additions and 0 deletions
@@ -76,6 +76,43 @@ Konkreter Support-Fall (2026-06-13): patrick@perlbach24.de konnte sich trotz Pas
- Nicht-Tenant-User per E-Mail → Erfolg
- Unbekannter Identifier → `invalid_credentials`
## QA Test Results (2026-07-04, QA Engineer)
**Testumgebung:** Testserver 192.168.1.132 (nicht Produktiv 131). Dedizierte Test-User
angelegt und nach Test wieder entfernt:
- `qa46-tenant` / `qa46-tenant@perlbach24.de` (tenant_id=1, role user) — username ≠ email
- `qa46-super` / `qa46-super@example.com` (tenant_id NULL, role superadmin)
Passwort `TestPw123!` (bcrypt cost 12). Beide User + zugehörige `login_attempts` nach Testende
gelöscht (verifiziert: 0 verbleibende `qa46%`-User). Audit-Log-Einträge bleiben append-only
erhalten (GoBD). Keine bestehenden Accounts verändert.
**Gesamtergebnis: BESTANDEN (9/9 Punkte pass, 0 Bugs).**
| # | Testpunkt | Erwartung | Ergebnis | Status |
|---|-----------|-----------|----------|--------|
| 1 | Tenant-User Login per E-Mail | 200 | 200, `user.username=qa46-tenant` korrekt aufgelöst | PASS |
| 2 | Tenant-User Login per Username | 401 | 401 invalid_credentials | PASS |
| 3 | Non-Tenant (superadmin, tenant_id NULL) per Username | 200 | 200 | PASS |
| 4 | Non-Tenant per E-Mail | 200 | 200 | PASS |
| 5 | Unbekannter Identifier | 401 | 401 (`{"error":"invalid credentials"}`) | PASS |
| 5b | Tenant-E-Mail + falsches Passwort | 401 | 401 | PASS |
| 6 | Rate-Limiting mit E-Mail-String als Schlüssel | 429 nach Fehlversuchen | 429 ausgelöst; `login_attempts.username` speichert vollständige E-Mail (VARCHAR(255)) ungekürzt | PASS |
| 7 | Audit-Log protokolliert Fehlversuche mit eingegebenem Identifier | Identifier im Log | Fehlversuche geloggt mit exaktem Identifier (`qa46-tenant@perlbach24.de`, `qa46-tenant`), Detail `invalid_password`/`rate limited`; Erfolg loggt kanonischen `user.Username` | PASS |
| 8 | IMAP-Login (PROJ-26, VerifyPassword-Pfad) per Username unverändert | LOGIN completed | `a OK LOGIN completed` per Username auf Port 993; VerifyPassword unangetastet, genutzt in `internal/imapserver/server.go:380` | PASS |
| 9 | Frontend: `/` E-Mail-Label+type=email, `/admin/login` "Benutzername oder E-Mail-Adresse" | korrekt | Deployte Seiten: `/` rendert `E-Mail-Adresse` + `type="email"`; `/admin/login` rendert `Benutzername oder E-Mail-Adresse` (type=text) | PASS |
**Code-Review-Notizen:**
- `VerifyLogin` (userstore.go): Email-Lookup → Fallback `username = $1 AND tenant_id IS NULL`.
Timing-Side-Channel geschlossen (Dummy-bcrypt bei No-Match). `VerifyPassword` unverändert.
- `Manager.Login` (auth.go:79) ruft `VerifyLogin`. LDAP-`extractDomain` bleibt kompatibel (E-Mail-Format).
- Kein Regressions-Fund gegen bestehende Auth-/IMAP-Features.
**Hinweis (kein Bug, informativ):** Alle produktiven Tenant-User auf 132 haben aktuell
`username == email` (z.B. `patrick@perlbach24.de`), sodass ihr Username-Login weiterhin über
den Email-Match greift. Der Reject-Pfad (Punkt 2) wurde deshalb bewusst mit einem Test-User
`username != email` verifiziert. `homelocal-admin` (id 120) wäre ein produktiver Fall mit
abweichendem Username — Passwort unbekannt, daher nicht live geprüft.
## Migration (bereits durchgeführt am 2026-06-13)
- Datenqualitäts-Check auf 192.168.1.131: 0 Tenant-User mit fehlender/ungültiger E-Mail, 0 Username↔E-Mail-Kollisionen
- `login_attempts.username` von VARCHAR(100) → VARCHAR(255) erweitert (idempotenter `initSchema`-Eintrag in `internal/userstore/userstore.go` ergänzt)