Files
archivmail/features/PROJ-1-authentifizierung-und-rollen.md
T
sysops d360c9a5ba feat(PROJ-17): Admin Dashboard Systemauslastung immer anzeigen
- Systemauslastungs-Sektion wird immer gerendert (nicht nur bei Erfolg)
- Fehlermeldung wenn /api/admin/system/stats nicht erreichbar ist
- Feature-Status auf In Review gesetzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 11:43:19 +01:00

186 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PROJ-1: Nutzer-Authentifizierung & Rollen
## Status: In Progress
**Created:** 2026-03-12
**Last Updated:** 2026-03-12
## Dependencies
- PROJ-16 (LDAP / Active Directory Anbindung) — optionale Erweiterung des Login-Flows
## Rollen-Übersicht
| Rolle | Zugriff |
|-------|---------|
| `user` | Suche und Lesen eigener archivierter E-Mails |
| `auditor` | Alle E-Mails lesen und suchen (postfachübergreifend) + Audit-Log einsehen und exportieren keine Konfiguration |
| `admin` | Konfiguration, Nutzerverwaltung, Import-Quellen, Systemeinstellungen kein Zugriff auf E-Mails, kein Audit-Log |
## User Stories
- Als Admin möchte ich mich mit Benutzername/Passwort einloggen, damit nur autorisierte Personen Zugriff haben.
- Als Admin möchte ich neue Nutzer anlegen und ihnen eine Rolle zuweisen (`user`, `auditor`, `admin`).
- Als Auditor möchte ich den Audit-Log einsehen und als CSV exportieren, ohne Zugriff auf E-Mails oder Konfiguration zu haben.
- Als Nutzer möchte ich mich abmelden können, damit meine Session sicher beendet wird.
- Als Admin möchte ich Passwörter zurücksetzen können, damit gesperrte Nutzer wieder Zugang erhalten.
- Als System möchte ich Sessions nach Inaktivität automatisch beenden, damit unbefugter Zugriff verhindert wird.
## Acceptance Criteria
- [ ] Login-Seite mit E-Mail/Benutzername und Passwort-Formular
- [ ] Fehlermeldung bei falschen Zugangsdaten (kein Hinweis ob E-Mail oder Passwort falsch)
- [ ] Session-Token wird sicher gespeichert (httpOnly Cookie oder JWT)
- [ ] Sessions laufen nach konfigurierbarer Inaktivität ab (Standard: 8 Stunden)
- [ ] Drei Rollen: `user`, `auditor`, `admin` strikt getrennte Zugriffsrechte
- [ ] `auditor` hat Zugriff auf alle E-Mails (postfachübergreifend, auch fremde Postfächer) + Audit-Log keine Konfiguration
- [ ] `admin` hat ausschließlich Zugriff auf Konfiguration und Nutzerverwaltung kein Zugriff auf E-Mails und kein Zugriff auf Audit-Log
- [ ] Admin kann Nutzer anlegen, deaktivieren und löschen
- [ ] Admin kann Passwörter zurücksetzen (temporäres Passwort)
- [ ] Alle API-Endpunkte prüfen Authentifizierung und Rolle
- [ ] Logout löscht die Session serverseitig
## Edge Cases
- Login mit deaktiviertem Account → klare Fehlermeldung, kein Zugang
- Mehrfaches Fehllogin → Rate-Limiting oder Account-Sperre nach X Versuchen
- Session-Token abgelaufen → automatische Weiterleitung zur Login-Seite
- Erster Start: Zwei feste Default-User werden beim ersten Start automatisch angelegt:
- `admin@archivmail` / `archivmailrockz` (Rolle: `admin`)
- `auditor@archivmail` / `archivmailrockz` (Rolle: `auditor`)
- Passwörter sollten nach dem ersten Login geändert werden (Hinweis in der UI)
- Admin löscht sich selbst → verhindern wenn letzter Admin
## Technical Requirements
- Passwörter mit bcrypt gehasht (min. Cost 12)
- Alle Routen außer `/login` erfordern gültige Session
- Admin-Routen (`/admin/*`) nur für `admin`-Rolle
- Audit-Routen (`/audit/*`) und E-Mail-Suche/Ansicht nur für `auditor`- und `user`-Rolle
- `admin` erhält bei E-Mail-Endpunkten HTTP 403 keine Ausnahmen
- Keine Rolle vereint `admin` + `auditor` strikte Funktionstrennung
- Audit-Log-Eintrag bei Login, Logout, fehlgeschlagenem Login
---
<!-- Sections below are added by subsequent skills -->
## Tech Design (Solution Architect)
### Systemübersicht: Two-Tier Architektur
```
Browser (Next.js App) Go REST API Backend
│ │
│ POST /api/auth/login │
│ {email, password} │
│ ─────────────────────────────────► │
│ 1. Lokaler Account? → bcrypt verify
│ 2. Nicht gefunden + LDAP aktiv?
│ → LDAP-Bind (Service Account)
│ → User-DN suchen
│ → User-Bind mit Passwort
│ → AD-Gruppen → Rolle bestimmen
│ → UpsertLDAPUser in PostgreSQL
│ 3. Session-Token erstellen
│ Session in PostgreSQL speichern
│ ◄─────────────────────────────────
│ Set-Cookie: session=TOKEN │
│ (httpOnly, Secure, SameSite) │
│ │
│ GET /api/search?q=... │
│ Cookie: session=TOKEN │
│ ─────────────────────────────────► │
│ Session-Middleware: Token prüfen
│ Role-Middleware: Route erlaubt?
│ ◄─────────────────────────────────
│ JSON-Antwort │
```
> **LDAP ist vollständig optional.** Wenn `ldap.enabled: false` (Standard), verhält sich das System exakt wie ohne LDAP. Lokale Accounts funktionieren immer — auch wenn LDAP aktiviert ist (Fallback bei LDAP-Fehler).
### Komponentenstruktur
**Next.js Frontend:**
```
src/app/
├── /login ← Login-Seite (öffentlich)
├── /search ← Suche + E-Mail-Ansicht (user + auditor)
├── /audit ← Audit-Log (nur auditor)
└── /admin ← Admin-Bereich (nur admin)
src/components/
├── LoginForm ← E-Mail + Passwort, Fehlermeldungen
├── RoleGuard ← Schützt Routen clientseitig, redirect auf /login
└── PasswordChangePrompt ← Hinweis bei Default-Passwort
```
**Go Backend:**
```
HTTP-Server
├── POST /api/auth/login ← Session ausstellen
├── POST /api/auth/logout ← Session löschen
├── Session Middleware ← prüft Token bei allen /api/* Routen
├── Role Middleware
│ ├── /api/admin/* → nur `admin`
│ ├── /api/audit/* → nur `auditor`
│ └── /api/* → `user` + `auditor` (admin → 403)
├── Password Manager ← bcrypt Hash + Verify
├── User Store ← PostgreSQL users-Tabelle
└── Bootstrap ← Default-User beim ersten Start
```
### Datenmodell
**Tabelle `users`:**
| Feld | Beschreibung |
|------|-------------|
| `id` | Interne ID |
| `email` | Login-E-Mail (eindeutig) |
| `password_hash` | bcrypt-Hash (Cost 12) — NULL bei LDAP-Usern |
| `role` | `user` / `auditor` / `admin` |
| `source` | `local` oder `ldap` — Herkunft des Accounts |
| `active` | Deaktivierte Nutzer können sich nicht einloggen |
| `created_at` | Erstellungszeitpunkt |
| `last_login_at` | Letzter erfolgreicher Login |
**Tabelle `sessions`:**
| Feld | Beschreibung |
|------|-------------|
| `token` | Zufälliger 32-Byte-Token |
| `user_id` | Referenz auf `users` |
| `expires_at` | Ablaufzeitpunkt (rollierend, +8h bei Aktivität) |
| `last_active_at` | Wird bei jeder Anfrage aktualisiert |
### Technische Entscheidungen
| Entscheidung | Begründung |
|---|---|
| **Next.js Frontend + Go REST API** | Klare Trennung: Next.js rendert die UI, Go verwaltet Daten und Sicherheit. Kein Java. |
| **Session-Cookie (httpOnly)** | Next.js sendet Cookie automatisch mit kein manuelles Token-Handling im Frontend-Code nötig |
| **Server-side Sessions (nicht JWT)** | Logout und Admin-Deaktivierung wirken sofort JWT wäre bis Ablauf weiterhin gültig |
| **Role-Check im Go-Backend** | Sicherheits-kritische Prüfung liegt im Backend, nicht im Next.js-Client (der wäre manipulierbar) |
| **RoleGuard in Next.js zusätzlich** | Verhindert kurzes Aufblitzen falscher Seiten rein UX, kein Sicherheits-Feature |
| **bcrypt Cost 12** | Ausreichend langsam gegen Brute-Force |
| **LDAP als optionaler Fallback** | Login versucht erst lokalen Account, dann LDAP Reihenfolge garantiert, dass lokale Admins immer funktionieren |
| **LDAP-User in PostgreSQL gespiegelt** | Nach erstem Login landet LDAP-User in `users`-Tabelle (`source: ldap`) einheitliche Session-Verwaltung, kein Sonder-Code |
| **AD-Gruppen → Rollen-Mapping** | Rolle wird bei jedem Login aus AD-Gruppenmitgliedschaft neu bestimmt Rollen-Änderung in AD wirkt beim nächsten Login |
### Abhängigkeiten
**Go Backend:**
| Paket | Zweck |
|---|---|
| `golang.org/x/crypto/bcrypt` | Passwort-Hashing |
| `crypto/rand` | Sichere Token-Generierung (Stdlib) |
| `github.com/go-ldap/ldap/v3` | LDAP/AD-Authentifizierung (PROJ-16) |
**Next.js Frontend:**
| Paket | Zweck |
|---|---|
| `react-hook-form` + `zod` | Login-Formular-Validierung (bereits im Template) |
| `shadcn/ui` | UI-Komponenten (bereits installiert) |
## QA Test Results
_To be added by /qa_
## Deployment
_To be added by /deploy_