Update config and dependencies for auth

Refactor configuration loading to separate user credentials from server
settings.
Update dependencies to their latest compatible versions to leverage new
features
and security patches.

Key changes include:
- Moving user credentials (`api_key`, `web_password`, `role`) from
  `.env`
  to a dedicated `users.toml` file for better manageability and
  security.
- Introducing an `AuthenticatedUser` struct and extractor for API
  key-based
  authentication.
- Updating `axum` and related crates to leverage Rust edition 2024
  improvements.
- Adjusting configuration values and tests to reflect these changes.
This commit is contained in:
2026-04-13 12:51:27 +02:00
parent 80a6537e16
commit 08c6e12a74
8 changed files with 237 additions and 98 deletions
+48 -23
View File
@@ -487,16 +487,28 @@ Freitext: [________________________]
---
### 4. Konfiguration (.env)
### 4. Konfiguration
**System-Konfiguration (.env):**
```
# Server
SERVER_PORT=3000
DATA_PATH=/data
USERS_FILE=users.toml
# Logging
LOG_LEVEL=info
LOG_PATH=/var/log/recorder/
LOG_MAX_DAYS=90
# Aufbewahrung
RETENTION_AUDIO_DAYS=30
RETENTION_TRANSCRIPT_DAYS=30
RETENTION_DOCUMENT_DAYS=0 # 0 = permanent
# faster-whisper
WHISPER_URL=http://localhost:8100
WHISPER_URL=http://localhost:10300
WHISPER_TIMEOUT_SECONDS=120
# Ollama
@@ -510,27 +522,28 @@ LLM_API_KEY=...
LLM_MODEL=...
LLM_TEMPERATURE=0
# Server
SERVER_PORT=3000
DATA_PATH=/data
# Logging
LOG_LEVEL=info
LOG_PATH=/var/log/recorder/
LOG_MAX_DAYS=90
# API Keys (ein Eintrag pro Arzt, für Watch-Authentifizierung)
API_KEY_DR_MUELLER=...
API_KEY_DR_SCHMIDT=...
# Web Login (ein Eintrag pro Arzt, bcrypt-Hash)
WEB_PASSWORD_DR_MUELLER=$2b$12$...
WEB_PASSWORD_DR_SCHMIDT=$2b$12$...
# Session
SESSION_TIMEOUT_HOURS=8
```
**User-Verwaltung (users.toml):**
User-Daten (API-Keys, Passwörter, Rollen) werden separat in `users.toml` verwaltet statt in .env. So können neue User hinzugefügt werden, ohne die System-Konfiguration anzufassen. Das `role`-Feld ermöglicht neben `doctor` auch andere Rollen (z.B. `mta`, `admin`).
```toml
[[user]]
slug = "dr_mueller"
api_key = "..."
web_password = "$2b$12$..."
role = "doctor"
[[user]]
slug = "dr_schmidt"
api_key = "..."
web_password = "$2b$12$..."
role = "doctor"
```
---
### 5. Vorgefertigte Prompts (prompts.toml)
@@ -656,7 +669,7 @@ Axum selbst benötigt keinen GPU-Zugriff — STT und Preprocessing laufen als ex
```toml
[dependencies]
axum = "0.7"
axum = "0.8" # 0.8 wegen edition 2024 (native async fn in Traits)
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.12", features = ["json", "multipart"] }
askama = "0.12"
@@ -668,10 +681,10 @@ uuid = { version = "1", features = ["v4"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
toml = "0.8"
tower-http = { version = "0.5", features = ["limit", "trace"] }
tower-http = { version = "0.6", features = ["limit", "trace"] } # passend zu axum 0.8
rand = "0.8" # Session-Token-Generierung (OsRng)
bcrypt = "0.15" # Passwort-Hashing (Web-Login)
axum-extra = { version = "0.9", features = ["cookie"] } # Cookie-Handling
axum-extra = { version = "0.12", features = ["cookie"] } # passend zu axum 0.8
```
---
@@ -814,7 +827,7 @@ axum-extra = { version = "0.9", features = ["cookie"] } # Cookie-Handling
| Ollama Modell | Gemma 3 4B — ggf. Llama 3.1 8B falls Qualität nicht reicht |
| Ionos Modell | Noch zu evaluieren |
| Watch Hardware | Pixel Watch 2 oder 3 (LTE empfohlen) |
| Authentifizierung Browser | Entschieden: Serverseitiges Session-Token (256-Bit, Cookie mit `Secure`/`HttpOnly`/`SameSite=Strict`), Ablauf 8 h. Arzt-Identität ausschließlich aus Session, nie aus URL (IDOR-Prävention). Login gegen Arzt-Passwort in `.env`. |
| Authentifizierung Browser | Entschieden: Serverseitiges Session-Token (256-Bit, Cookie mit `Secure`/`HttpOnly`/`SameSite=Strict`), Ablauf 8 h. User-Identität ausschließlich aus Session, nie aus URL (IDOR-Prävention). Login gegen User-Passwort in `users.toml`. |
| Prompt-Qualität | Erfordert Testing mit echten Diktaten |
| Transkript editierbar? | Read-only oder editierbar vor Abschluss — offen |
| Sicheres Löschen | Reicht rm oder Overwrite nötig? — offen |
@@ -831,3 +844,15 @@ axum-extra = { version = "0.9", features = ["cookie"] } # Cookie-Handling
- Multi-Tenant / Cloud-Hosting
- Echtzeit-Transkription
- Automatische Patientenzuordnung
---
## Abweichungen von der Originalplanung
| Änderung | Original | Aktuell | Grund |
|---|---|---|---|
| Crate-Versionen | axum 0.7, tower-http 0.5, axum-extra 0.9 | axum 0.8, tower-http 0.6, axum-extra 0.12 | Rust edition 2024 erfordert native async fn in Traits; axum 0.7 nutzt `#[async_trait]`, was inkompatibel ist |
| User-Verwaltung | `API_KEY_*` / `WEB_PASSWORD_*` in .env | Separate `users.toml` mit role-Feld | Flexibler: neue User ohne .env-Änderung, Rollen-System (doctor, mta, admin) |
| faster-whisper Port | 8100 | 10300 | Tatsächlicher Port des laufenden Containers auf minerva |
| Terminologie | "Arzt/Ärzte" | "User" | Rollen-System: nicht nur Ärzte, auch MTAs und ggf. Admins |
| Erster Upload neue case_id | "Fall unbekannt → ACK gone" | Neuer Fall anlegen, ACK "received" | Sonst würde der allererste Upload einer neuen case_id immer abgelehnt. "gone" nur für gelöschte Fälle. |