Doku: Screen-Usserverwaltung (Phase 8)
Aktualisiert Dokumentation für Screen-User Management nach Backy's Implementierung:
docs/SCHEMA.md:
- users.role erweitert: 'admin' | 'screen_user' | 'tenant'
- Neue Tabelle: user_screen_permissions (user_id, screen_id, created_at, unique constraint, FK mit CASCADE)
- AuthStore: CreateScreenUser, ListScreenUsers, DeleteUser
- ScreenStore: GetAccessibleScreens, HasUserScreenAccess, AddUserToScreen, RemoveUserFromScreen, GetScreenUsers
docs/API-ENDPOINTS.md:
- POST /admin/users — Screen-User anlegen
- POST /admin/users/{userID}/delete — Screen-User löschen
- POST /admin/screens/{screenID}/users — User zu Screen hinzufügen
- POST /admin/screens/{screenID}/users/{userID}/remove — User von Screen entfernen
server/backend/README.md:
- AuthStore und ScreenStore Methoden dokumentiert
- Middleware RequireScreenAccess erklärt
- Migration 003_user_screen_permissions.sql erwähnt
DEVELOPMENT.md:
- users.role Werte dokumentiert (admin, screen_user, tenant)
Co-Authored-By: Backy (Screen-User Implementation) <noreply@anthropic.com>
This commit is contained in:
parent
d1d86126c8
commit
8e0501a012
4 changed files with 190 additions and 7 deletions
|
|
@ -164,6 +164,11 @@ Konfigurierbar ueber:
|
|||
- `MORZ_INFOBOARD_REGISTER_SECRET` – Pre-Shared-Secret fuer POST /api/v1/screens/register; leer = offen fuer alle
|
||||
- `MORZ_INFOBOARD_DEV_MODE` – wenn `true`: Session-Cookie wird ohne `Secure`-Flag gesetzt (nur fuer lokale Entwicklung)
|
||||
|
||||
**Hinweis zu `users.role`:**
|
||||
- `admin` — hat Zugriff auf alle Admin-Funktionen und Screens
|
||||
- `screen_user` — hat Zugriff nur auf Screens, fuer die explizit ein Eintrag in `user_screen_permissions` existiert
|
||||
- `tenant` — hat Zugriff auf alle Screens seines Tenants (veraltet, noch nicht vollstaendig implementiert)
|
||||
|
||||
Beispiele:
|
||||
|
||||
```bash
|
||||
|
|
|
|||
|
|
@ -694,6 +694,89 @@ Rückleitung zur Admin-Seite.
|
|||
|
||||
---
|
||||
|
||||
## Screen-User Management (Admin)
|
||||
|
||||
### POST /admin/users
|
||||
|
||||
Erstellt einen neuen Screen-User für einen Tenant (Admin-Formular).
|
||||
|
||||
**Request-Body (Form-Encoded):**
|
||||
```
|
||||
username=screenuser1&password=geheim
|
||||
```
|
||||
|
||||
**Verhalten:**
|
||||
- Neuer User mit `role = 'screen_user'` wird angelegt
|
||||
- Passwort wird per bcrypt gehasht
|
||||
- User wird dem aktuellen Tenant zugeordnet
|
||||
|
||||
**Status:**
|
||||
- `200 OK` oder `201 Created` — Screen-User erstellt
|
||||
- `400 Bad Request` — Fehlende oder ungültige Parameter, Username bereits vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
Rückleitung zur Admin-Seite.
|
||||
|
||||
---
|
||||
|
||||
### POST /admin/users/{userID}/delete
|
||||
|
||||
Löscht einen Screen-User und alle zugeordneten Screen-Permissions.
|
||||
|
||||
**Verhalten:**
|
||||
- User mit Rolle `screen_user` wird gelöscht
|
||||
- Alle Einträge in `user_screen_permissions` für diesen User werden gelöscht
|
||||
|
||||
**Status:**
|
||||
- `200 OK` — Screen-User gelöscht
|
||||
- `404 Not Found` — User nicht vorhanden oder falscher Typ
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
Rückleitung zur Admin-Seite.
|
||||
|
||||
---
|
||||
|
||||
### POST /admin/screens/{screenID}/users
|
||||
|
||||
Fügt einen Screen-User zu einem Screen hinzu.
|
||||
|
||||
**Request-Body (Form-Encoded):**
|
||||
```
|
||||
user_id=<userID>
|
||||
```
|
||||
|
||||
**Verhalten:**
|
||||
- Eintrag in `user_screen_permissions` wird erstellt
|
||||
- User muss vom Typ `screen_user` sein
|
||||
- Unique-Constraint verhindert Duplikate
|
||||
|
||||
**Status:**
|
||||
- `200 OK` — User zu Screen hinzugefügt
|
||||
- `400 Bad Request` — Fehlende Parameter, User bereits hinzugefügt
|
||||
- `404 Not Found` — Screen oder User nicht vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
Rückleitung zur Admin-Seite oder zum Screen-Detail.
|
||||
|
||||
---
|
||||
|
||||
### POST /admin/screens/{screenID}/users/{userID}/remove
|
||||
|
||||
Entfernt einen Screen-User von einem Screen.
|
||||
|
||||
**Verhalten:**
|
||||
- Eintrag in `user_screen_permissions` wird gelöscht
|
||||
- User behält seine Existenz; nur die Permission wird entfernt
|
||||
|
||||
**Status:**
|
||||
- `200 OK` — User von Screen entfernt
|
||||
- `404 Not Found` — Screen, User oder Permission nicht vorhanden
|
||||
- `500 Internal Server Error` — DB-Fehler
|
||||
|
||||
Rückleitung zur Admin-Seite oder zum Screen-Detail.
|
||||
|
||||
---
|
||||
|
||||
## Playlist Management UI (Web-Formulare)
|
||||
|
||||
### GET /manage/{screenSlug}
|
||||
|
|
@ -954,6 +1037,11 @@ Die folgenden Endpoints sind derzeit vorbereitet, aber noch nicht vollständig i
|
|||
|
||||
## Änderungshistorie
|
||||
|
||||
- **2026-03-23 (Update):** Screen-User Management Endpoints (Doris / Doku-Review)
|
||||
- `POST /admin/users` — Screen-User anlegen
|
||||
- `POST /admin/users/{userID}/delete` — Screen-User löschen
|
||||
- `POST /admin/screens/{screenID}/users` — User zu Screen hinzufügen
|
||||
- `POST /admin/screens/{screenID}/users/{userID}/remove` — User von Screen entfernen
|
||||
- **2026-03-23 (Update):** Security-Enhancements und Upload-Konsolidierung (Doris / Doku-Review)
|
||||
- CSRF-Schutz (Double-Submit-Cookie) in `internal/httpapi/csrf.go`
|
||||
- Rate-Limiting für `/login` in `internal/httpapi/ratelimit.go`
|
||||
|
|
|
|||
|
|
@ -59,12 +59,34 @@ unique(tenant_id, username)
|
|||
|
||||
Regeln:
|
||||
|
||||
- `role` in v1: `admin`, `tenant`
|
||||
- `role` in v1: `admin`, `screen_user`, `tenant`
|
||||
- `username` ist nur innerhalb eines Tenants eindeutig (Unique-Constraint auf `(tenant_id, username)`)
|
||||
- `tenant_id` ist `NOT NULL` — jeder User gehoert genau einem Tenant
|
||||
- IDs sind `text`, nicht `uuid`, enthalten aber UUID-Werte (via `gen_random_uuid()::text`)
|
||||
- Felder wie `email`, `active`, `last_login_at` und `updated_at` existieren in v1 nicht
|
||||
|
||||
### `user_screen_permissions`
|
||||
|
||||
Zweck:
|
||||
|
||||
- Zuordnung von Screen-Usern zu Screens (rollenbasierter Zugriff)
|
||||
|
||||
Spalten:
|
||||
|
||||
```sql
|
||||
id uuid primary key
|
||||
user_id text not null references users(id) on delete cascade
|
||||
screen_id uuid not null references screens(id) on delete cascade
|
||||
created_at timestamptz not null default now()
|
||||
unique(user_id, screen_id)
|
||||
```
|
||||
|
||||
Regeln:
|
||||
|
||||
- `user_id` muss ein User mit `role = 'screen_user'` sein
|
||||
- `screen_id` muss existieren; Loeschen des Screens loescht auch die Permission
|
||||
- Loeschen des Users loescht auch alle seine Permissions
|
||||
|
||||
### `sessions`
|
||||
|
||||
Zweck:
|
||||
|
|
@ -529,6 +551,9 @@ last_error_message text null
|
|||
Die Auth-Tabellen werden durch `server/backend/internal/db/migrations/002_auth.sql` angelegt
|
||||
und sind vollstaendig unter den Abschnitten `users` und `sessions` oben beschrieben.
|
||||
|
||||
Die Screen-Usserverwaltung wird durch `server/backend/internal/db/migrations/003_user_screen_permissions.sql` angelegt
|
||||
und ist unter dem Abschnitt `user_screen_permissions` oben beschrieben.
|
||||
|
||||
Der `AuthStore` (`internal/store/auth.go`) stellt folgende Methoden bereit:
|
||||
|
||||
- `GetUserByUsername(ctx, username)` — Nutzer per Username laden (inkl. `TenantSlug` via LEFT JOIN)
|
||||
|
|
@ -538,6 +563,17 @@ Der `AuthStore` (`internal/store/auth.go`) stellt folgende Methoden bereit:
|
|||
- `CleanExpiredSessions(ctx)` — abgelaufene Sessions bereinigen
|
||||
- `EnsureAdminUser(ctx, tenantSlug, password)` — Admin-User beim Start anlegen wenn nicht vorhanden
|
||||
- `VerifyPassword(ctx, userID, password)` — Passwort gegen bcrypt-Hash pruefen
|
||||
- `CreateScreenUser(ctx, tenantID, username, password)` — neuen Screen-User anlegen
|
||||
- `ListScreenUsers(ctx, tenantID)` — alle Screen-User eines Tenants auflisten
|
||||
- `DeleteUser(ctx, userID)` — User und alle zugeordneten Permissions loeschen
|
||||
|
||||
Der `ScreenStore` (`internal/store/screen.go`) stellt folgende Methoden bereit:
|
||||
|
||||
- `GetAccessibleScreens(ctx, userID)` — alle Screens, auf die der User Zugriff hat
|
||||
- `HasUserScreenAccess(ctx, userID, screenID)` — prueft ob User auf Screen zugreifen darf
|
||||
- `AddUserToScreen(ctx, userID, screenID)` — User zu Screen hinzufuegen
|
||||
- `RemoveUserFromScreen(ctx, userID, screenID)` — User von Screen entfernen
|
||||
- `GetScreenUsers(ctx, screenID)` — alle User, die auf Screen Zugriff haben
|
||||
|
||||
## Wichtige Indizes
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,33 @@ Dieses Verzeichnis enthaelt das zentrale Go-Backend fuer das Info-Board-System.
|
|||
- `internal/mqttnotifier/` — MQTT-Notifizierungen
|
||||
- `internal/reqcontext/` — Context-Keys fuer authentifizierten User
|
||||
|
||||
## Datenbank-Stores
|
||||
|
||||
### AuthStore (`internal/store/auth.go`)
|
||||
|
||||
**Screen-User Management:**
|
||||
- `CreateScreenUser(ctx, tenantID, username, passwordHash)` — neuen Screen-User anlegen
|
||||
- `ListScreenUsers(ctx, tenantID)` — alle Screen-User eines Tenants auflisten
|
||||
- `DeleteUser(ctx, userID)` — User und alle zugeordneten Permissions loeschen
|
||||
|
||||
**Authentifizierung:**
|
||||
- `GetUserByUsername(ctx, username)` — Nutzer per Username laden
|
||||
- `CreateSession(ctx, userID, ttl)` — neue Session anlegen
|
||||
- `GetSessionUser(ctx, sessionID)` — User zu gueltigem Session-Token laden
|
||||
- `DeleteSession(ctx, sessionID)` — Session loeschen (Logout)
|
||||
- `CleanExpiredSessions(ctx)` — abgelaufene Sessions bereinigen
|
||||
- `EnsureAdminUser(ctx, tenantSlug, password)` — Admin-User beim Start anlegen
|
||||
- `VerifyPassword(ctx, userID, password)` — Passwort gegen bcrypt-Hash pruefen
|
||||
|
||||
### ScreenStore (`internal/store/screen.go`)
|
||||
|
||||
**Screen-User Zugriffskontrolle:**
|
||||
- `GetAccessibleScreens(ctx, userID)` — alle Screens, auf die der User Zugriff hat
|
||||
- `HasUserScreenAccess(ctx, userID, screenID)` — prueft ob User auf Screen zugreifen darf (boolean)
|
||||
- `AddUserToScreen(ctx, userID, screenID)` — User zu Screen hinzufuegen (Eintrag in `user_screen_permissions`)
|
||||
- `RemoveUserFromScreen(ctx, userID, screenID)` — User von Screen entfernen
|
||||
- `GetScreenUsers(ctx, screenID)` — alle User, die auf Screen Zugriff haben
|
||||
|
||||
## Aktuelle Endpunkte
|
||||
|
||||
### Oeffentlich (keine Auth)
|
||||
|
|
@ -75,12 +102,16 @@ Dieses Verzeichnis enthaelt das zentrale Go-Backend fuer das Info-Board-System.
|
|||
|
||||
### Nur Admins (`RequireAuth` + `RequireAdmin`)
|
||||
|
||||
| Methode | Pfad | Beschreibung |
|
||||
|---------|-------------------------------------|---------------------------------------|
|
||||
| GET | `/admin` | Admin-Uebersicht |
|
||||
| POST | `/admin/screens/provision` | Provisionierungs-Job starten |
|
||||
| POST | `/admin/screens` | Neuen Screen anlegen |
|
||||
| POST | `/admin/screens/{screenId}/delete` | Screen loeschen |
|
||||
| Methode | Pfad | Beschreibung |
|
||||
|---------|-------------------------------------------|---------------------------------------|
|
||||
| GET | `/admin` | Admin-Uebersicht |
|
||||
| POST | `/admin/screens/provision` | Provisionierungs-Job starten |
|
||||
| POST | `/admin/screens` | Neuen Screen anlegen |
|
||||
| POST | `/admin/screens/{screenId}/delete` | Screen loeschen |
|
||||
| POST | `/admin/users` | Screen-User anlegen |
|
||||
| POST | `/admin/users/{userID}/delete` | Screen-User loeschen |
|
||||
| POST | `/admin/screens/{screenID}/users` | User zu Screen hinzufuegen |
|
||||
| POST | `/admin/screens/{screenID}/users/{userID}/remove` | User von Screen entfernen |
|
||||
|
||||
### Tenant-scoped (`RequireAuth` + `RequireTenantAccess`)
|
||||
|
||||
|
|
@ -113,3 +144,26 @@ Alle Werte per Umgebungsvariable:
|
|||
| `MORZ_INFOBOARD_MQTT_PASSWORD` | MQTT-Passwort | leer |
|
||||
|
||||
Detailliertere Beschreibung und lokale Startbeispiele: `DEVELOPMENT.md`.
|
||||
|
||||
## Middleware
|
||||
|
||||
### `RequireScreenAccess`
|
||||
|
||||
Middleware zur rollenbasierten Zugriffskontrolle auf Screen-Ressourcen.
|
||||
|
||||
**Verhalten:**
|
||||
- Admins duerfen auf alle Screens zugreifen
|
||||
- Screen-User duerfen nur auf Screens zugreifen, fuer die sie in `user_screen_permissions` eingetragen sind
|
||||
- Tenant-User duerfen auf alle Screens ihres Tenants zugreifen
|
||||
- Response: `403 Forbidden` wenn keine Berechtigung
|
||||
|
||||
**Verwendung:**
|
||||
- `GET /api/v1/screens/{screenId}/playlist`
|
||||
- `POST /manage/{screenSlug}/...`
|
||||
- Alle privaten Screen-Endpunkte
|
||||
|
||||
## Migrationen
|
||||
|
||||
- `001_core.sql` — initiales Schema (Tenants, Screens, Playlists, Media, etc.)
|
||||
- `002_auth.sql` — Auth-Tabellen (`users`, `sessions`)
|
||||
- `003_user_screen_permissions.sql` — Screen-User Management (`user_screen_permissions`)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue