add chat user roles and login

This commit is contained in:
team 1
2026-05-11 11:33:03 +02:00
parent 3c5de0d8e6
commit 83ac6d600e
9 changed files with 312 additions and 71 deletions

View File

@@ -0,0 +1,156 @@
# RetrieX Patch p88 - Chat Security Roles
## Zweck
p88 fuehrt eine getrennte Rollen-/Security-Schicht fuer den Chat ein, ohne eine zweite Userverwaltung anzulegen. Chat und Admin nutzen weiterhin denselben Symfony-User-Provider (`App\Entity\User`), werden aber ueber unterschiedliche Bereichsrollen freigeschaltet.
Der Patch baut auf p87 auf: Der Chat wird bereits ueber einen eigenen Symfony-Controller gerendert. p88 schuetzt diesen Chat-Einstieg und die zugehoerigen Chat-API-Endpunkte nun mit `ROLE_CHAT_USER`.
## Architekturentscheidung
Die Userverwaltung bleibt zentral:
- Entity: `App\Entity\User`
- Provider: `app_user_provider`
- Rollenfeld: bestehendes JSON-Feld `roles`
- Command: bestehender `mto:agent:user:create`
Die Bereichsberechtigungen werden getrennt:
- `ROLE_CHAT_USER` fuer Chat und Chat-API-Endpunkte
- `ROLE_ADMIN_AREA` fuer den Adminbereich
- `ROLE_USER` bleibt nur technische Basisrolle fuer eingeloggte User
Wichtig: `ROLE_USER` ist keine Adminberechtigung mehr. Das ist noetig, weil `User::getRoles()` jedem User automatisch `ROLE_USER` gibt.
## Aenderungen
### `config/packages/security.yaml`
- Admin-Firewall bleibt auf `^/admin` begrenzt.
- Neue Chat-Firewall fuer:
- `/`
- `/chat`
- `/chat/login`
- `/chat/logout`
- `/ask-jobs...`
- `/ask-sse...`
- `/history...`
- `/chat-messages/frontend`
- Beide Firewalls verwenden denselben Provider `app_user_provider`.
- Beide Firewalls verwenden denselben Security-Context `retriex_user_area`, damit die zentrale Userverwaltung und Session sauber gemeinsam genutzt werden koennen.
- Adminzugriff verlangt jetzt `ROLE_ADMIN_AREA` statt `ROLE_USER`.
- Chatzugriff verlangt `ROLE_CHAT_USER`.
### Neue Rollenlogik
```yaml
ROLE_SUPER_ADMIN: [ROLE_KNOWLEDGE_ADMIN, ROLE_EDITOR, ROLE_ADMIN_AREA, ROLE_CHAT_USER, ROLE_USER]
ROLE_KNOWLEDGE_ADMIN: [ROLE_EDITOR, ROLE_ADMIN_AREA, ROLE_CHAT_USER, ROLE_USER]
ROLE_EDITOR: [ROLE_ADMIN_AREA, ROLE_CHAT_USER, ROLE_USER]
ROLE_ADMIN_AREA: [ROLE_USER]
ROLE_CHAT_USER: [ROLE_USER]
```
Damit gilt:
- Chat-only User: `ROLE_CHAT_USER`
- Admin-only User: `ROLE_ADMIN_AREA`
- Editor/Knowledge/Super Admins behalten Adminzugriff und bekommen Chatzugriff ueber Hierarchie
- `ROLE_USER` alleine reicht fuer keinen Bereich
### Neuer Chat-Login
Neue Dateien:
- `src/Controller/Chat/SecurityController.php`
- `templates/chat/security/login.html.twig`
Routen:
- `/chat/login`
- `/chat/logout`
Der Controller liegt bewusst unter `App\Controller\Chat`, nicht unter `App\Controller\Admin`.
### Admin-Login-Hardening
`src/Controller/Admin/SecurityController.php` leitet eingeloggte User nur noch direkt zum Admin-Dashboard weiter, wenn sie `ROLE_ADMIN_AREA` haben. Ein reiner Chat-User wird dadurch nicht versehentlich in eine Admin-Weiterleitung geschickt.
### Admin-Endpoint-Hardening
`src/Controller/Admin/IngestJobController.php` nutzt fuer den Status-Endpunkt jetzt `ROLE_ADMIN_AREA` statt `ROLE_USER`.
### User-Create-Command
`src/Command/CreateUserCommand.php` wurde angepasst:
- Beschreibung neutralisiert: erstellt nun einen Application-User, nicht nur Admin-User
- Rollenauswahl erweitert um `ROLE_ADMIN_AREA` und `ROLE_CHAT_USER`
- `ROLE_USER` aus der Auswahl entfernt, weil diese Rolle automatisch gesetzt wird und alleine keinen Bereich freischalten soll
## Bewusst nicht geaendert
- Keine neue User-Entity
- Keine neue User-Tabelle
- Keine neue Migration
- Keine Aenderung an RAG, Retrieval, Scoring, Ranking, Shop-Matching oder Prompt-Logik
- Keine Verschiebung bestehender Ask-/SSE-/History-Controller
- Keine Aenderung an `public/assets/js/base.js`
- Keine Aenderung an Chat-Frontend-Verhalten ausser Loginpflicht
## Hinweis zu `public/index.html`
Wie in p87 muss `public/index.html` geloescht sein. Wenn die Datei liegen bleibt, kann der Webserver `/` weiterhin statisch bedienen und Symfony samt Chat-Firewall umgehen.
Im Full-ZIP ist `public/index.html` entfernt. Im Patch-only-ZIP liegt zusaetzlich `DELETE_PUBLIC_INDEX_HTML.txt` als manueller Hinweis.
## Lokale Checks
Ausgefuehrt:
```bash
php -l src/Controller/Chat/SecurityController.php
php -l src/Controller/Chat/ChatController.php
php -l src/Controller/Admin/SecurityController.php
php -l src/Controller/Admin/IngestJobController.php
php -l src/Command/CreateUserCommand.php
python3 - <<'PY'
from pathlib import Path
import yaml
data = yaml.safe_load(Path('config/packages/security.yaml').read_text())
assert data['security']['access_control'][2]['roles'] == 'ROLE_ADMIN_AREA'
assert data['security']['access_control'][5]['roles'] == 'ROLE_CHAT_USER'
assert not Path('public/index.html').exists()
print('p88 structural checks OK')
PY
```
Ergebnis:
- PHP lint OK
- YAML parse OK
- Adminbereich ist nicht mehr ueber `ROLE_USER` freigeschaltet
- Chatbereich ist ueber `ROLE_CHAT_USER` freigeschaltet
- `public/index.html` ist im Full-ZIP entfernt
## Noch in Zielumgebung ausfuehren
```bash
php bin/console cache:clear
php bin/console debug:router | grep -E 'chat_login|chat_logout|chat_index|admin_login|admin_dashboard'
php bin/console debug:config security
php bin/console mto:agent:config:validate
php bin/console mto:agent:regression:test
php bin/console mto:agent:config:audit-source --details
php bin/console mto:agent:config:audit-patterns --details
```
Manuelle Smoke-Tests:
1. Ohne Login `/` aufrufen: Redirect zu `/chat/login`.
2. User mit `ROLE_CHAT_USER` anlegen und einloggen: `/` und `/chat` oeffnen den Chat.
3. Chat-User ruft `/admin` auf: kein Adminzugriff.
4. Bestehender `ROLE_SUPER_ADMIN`, `ROLE_KNOWLEDGE_ADMIN` oder `ROLE_EDITOR` kann weiterhin `/admin` nutzen.
5. Admin-/Editor-User kann den Chat nutzen.
6. `/ask-jobs`, `/ask-sse/{jobId}`, `/history`, `/history/delete`, `/chat-messages/frontend` funktionieren nach Chat-Login.