gwoe-antragspruefer/docs/reference/zugriffsrechte.md
Dotty Dotter 2dec009b5c docs+ops: ADRs 0006/0008, DDD-Bewertung, Zugriffsrechte, Smoke-Test, Cron-Scripts
ADRs:
- 0006 Embedding-Modell-Migration v3->v4 (#123)
- 0008 DDD-Lightweight-Migration (#136)

Analysen:
- ddd-bewertung.md (1237 Zeilen) — vollstaendige DDD-Analyse mit Tages-Roadmap
- protokoll-parser-v6-machbarkeit.md (418 Zeilen) — #106 Phase 2 Vorbereitung

Reference:
- zugriffsrechte.md — 63 Routes x 3 User-Status, UI-Sichtbarkeits-Matrix

Ops:
- scripts/deploy.sh — mit Uptime-Kuma-Wartungsmodus (#149)
- scripts/run-digest.sh — taeglicher Mail-Digest-Cron
- scripts/run-monitoring-scan.sh — Monitoring-Scan-Cron (noch nicht aktiv)
- scripts/smoke-test.sh — Gesamt-Funktionspruefung
- pytest.ini: integration/slow/e2e Markers, addopts not-integration

Tests/integration/: Live-Adapter-Tests + Frontend-XRef + Citation-Substring
                    + Wahlprogramm-Indexed (4 Live-Test-Suites, marker-opt-in)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 20:55:57 +02:00

6.6 KiB
Raw Blame History

Zugriffsrechte & User-Status

Abgeleitet direkt aus dem Code (app/main.py, app/auth.py, Templates). Stand des Generats: 2026-04-20.

Drei User-Status

Status Signal Guard im Code
Gast (anonymous) Kein gültiger access_token-Cookie
Registriert (authenticated) Gültiger Keycloak-JWT, Rolle beliebig Depends(require_auth)
Admin Keycloak-JWT mit Rolle admin oder gwoe-admin Depends(require_admin)

Zwei Sonder-Modi:

  • Dev-Modus (AUTH_ENABLED=false in .env): jede Anfrage wird als Anonymous+Admin ausgegeben, sämtliche Guards fallen. Nur lokal, nie in Prod. Siehe ADR 0005.
  • Approval-pending: Nutzer:innen, die über /api/auth/register angelegt sind aber noch nicht von einem Admin via /api/auth/approve-user freigeschaltet wurden, können sich einloggen, aber keine require_auth-Features nutzen (Keycloak verweigert Token-Ausgabe). Siehe docs/how-to/keycloak-setup.md.

Endpoint × Status-Matrix (63 Routes)

Admin-only (5)

Nur Nutzer:innen mit Rolle admin/gwoe-admin erreichen diese:

Methode Pfad Zweck
POST /api/batch-analyze Batch-Bewertung starten
POST /api/programme/index Wahlprogramm indexieren
POST /api/auth/approve-user User-Freischaltung
GET /api/auth/pending-users Liste offener Freischaltungs-Anträge
DELETE /api/assessment/delete Bewertung löschen (für Re-Analyse)

Authenticated (8)

Jede:r eingeloggte:r Nutzer:in:

Methode Pfad Zweck
POST /analyze Freitext-Upload bewerten
POST /api/analyze-drucksache Antrag aus Landtag bewerten
POST /api/bookmark Merklisten-Eintrag toggeln
POST /api/comment Kommentar anlegen
DELETE /api/comment/{id} Eigenen Kommentar löschen
POST /api/subscriptions E-Mail-Abo anlegen
DELETE /api/subscriptions/{id} E-Mail-Abo löschen
POST /api/vote Antrag-Bewertung votieren

Optional-User (5)

Funktionieren auch ohne Login, aber personalisieren mit User-Daten wenn eingeloggt:

Methode Pfad Verhalten
GET /api/auth/me Gibt Auth-Status zurück
GET /api/bookmarks Liste eigener Bookmarks (wenn eingeloggt), sonst []
GET /api/comments?drucksache=X Öffentliche + eigene Kommentare
GET /api/subscriptions Eigene Abos
GET /api/votes?drucksache=X Alle Votes + eigenes Vote-Flag

Public (45)

Alle Lese-Endpoints und statische Seiten sind offen. Darunter u.a.:

  • Seiten: /, /antrag/{ds}, /classic, /auswertungen, /methodik, /quellen, /impressum, /datenschutz, /health, /v2/{merkliste,tags,cluster,neu,batch}
  • API-Listen: /api/assessments, /api/assessment, /api/clusters, /api/bundeslaender, /api/programme, /api/search, /api/search-landtag, /api/feed.xml, /api/wahlprogramm-cite
  • Auswertungen: /api/auswertungen/{matrix,zeitreihe,themen-matrix,export.csv,export.json}
  • Auth-Flow: /api/auth/login, /api/auth/register, /api/auth/callback, /api/auth/login-url, /api/auth/refresh, /unsubscribe/{sub}/{token}
  • Jobs: /api/analyze-drucksache-Ergebnisse via /status/{job_id}, /result/{job_id}, /result/{job_id}/pdf, /api/queue/status

Das heißt: Lesen und Navigieren braucht keinen Account. Erst Aktionen (Merken, Kommentieren, Bewerten, neue Analyse starten) erfordern Login.

UI-Sichtbarkeit — was sieht wer

v2-Frontend (/, /antrag/*, /v2/*)

UI-Element Gast Registriert Admin
Sidebar-Gruppe „Lesen" (Durchsuchen / Merkliste / Tags / Cluster)
Sidebar-Gruppe „Prüfen" (Neuer Antrag / Batch-Analyse) ✓ Links ✓ funktional ✓ funktional
Sidebar-Gruppe „Daten" (Auswertungen / Export / Feed)
Sidebar-Gruppe „Administration" (Freischaltungen / Queue / Abos) ✓ (via {% if is_admin %} in base.html:61)
Topbar „Klassische Ansicht" + Theme-Toggle
/v2/merkliste Bookmark-Liste Login-CTA eigene Liste eigene Liste
Bookmark-Stern auf Antragsdetail Login-CTA
Kommentar-Form Login-CTA
Vote-Buttons Login-CTA
Re-Analyze-Button ✓ (nach Ablauf) ✓ jederzeit
Delete-Assessment-Button

Classic-Frontend (/classic)

UI-Element Gast Registriert Admin
Listenansicht + Detail
Hamburger → Anmelden/Registrieren ✓ (öffnet Modal)
Hamburger → Auswertungen / Quellen / Methodik
Merkliste-Tab ✓ (localStorage, gerätegebunden) ✓ (synced mit Server)
Kommentare anlegen Login-CTA
Admin-Tab ✓ (Freischaltungen, Queue, Batch)

Login-/Auth-Flows

Zwei Varianten koexistieren:

Direct Access Grant (Default in v2 + /classic-Modal)

  1. User klickt „Anmelden" → Modal öffnet
  2. POST /api/auth/login mit username+password
  3. Server ruft Keycloak grant_type=password gegen Client gwoe-antragspruefer
  4. Setzt access_token (HttpOnly-Cookie) + rt (Refresh-Token, Path /api/auth/refresh)
  5. Modal schließt, UI refreshed via /api/auth/me

Voraussetzung: Keycloak-Client gwoe-antragspruefer hat directAccessGrantsEnabled: true (ist gesetzt seit 2026-04-20).

OIDC Redirect (Fallback)

/api/auth/login-url → Keycloak-Login-Seite → /api/auth/callback → Cookie gesetzt → Redirect auf /.

Wurde mit der Direct-Access-Variante überflüssig, bleibt für Notfall erhalten.

Admin-Rollen definieren

Im Keycloak-Admin:

  1. Realm collaborationRoles → Rolle admin anlegen (oder gwoe-admin)
  2. User → dem jeweiligen Nutzer die Rolle zuweisen
  3. Code prüft in auth.py:220: "admin" in roles or "gwoe-admin" in roles

Kein Fein-Granular-Rollen-Modell vorgesehen — admin ist alles-oder-nichts.

Dev-Bypass

In .env: AUTH_ENABLED=false setzt alle Guards auf Bypass. require_auth gibt Dev-Modus-User zurück (sub=anonymous, roles=[]), require_admin gibt roles=["admin"]. Nur für lokale Entwicklung ohne Keycloak-Stack. In Prod immer auf true.

Änderung gegenüber alter Doku

docs/reference/api.md hatte eine stale „Auth"-Spalte mit „Keycloak (geplant)". Diese Doku ersetzt sie inhaltlich — das api.md könnte zusammengelegt oder auf diese Seite verlinken.

Wartungshinweis

Diese Doku wird nicht automatisch generiert. Bei neuen Routes / Guards manuell nachpflegen oder via docs/reference/scan-zugriffsrechte.py (TODO: hat bisher keiner geschrieben) regenerieren.