**Änderungen:** - ✅ app.py: Hinzugefügt, um CSRF-Fehler zu behandeln - ✅ models.py: Fehlerprotokollierung bei der Suche nach Gastanfragen per OTP - ✅ api.py: Fehlerprotokollierung beim Markieren von Benachrichtigungen als gelesen - ✅ calendar.py: Fallback-Daten zurückgeben, wenn keine Kalenderereignisse vorhanden sind - ✅ guest.py: Status-Check-Seite für Gäste aktualisiert - ✅ hardware_integration.py: Debugging-Informationen für erweiterte Geräteinformationen hinzugefügt - ✅ tapo_status_manager.py: Rückgabewert für Statusabfrage hinzugefügt **Ergebnis:** - Verbesserte Fehlerbehandlung und Protokollierung für eine robustere Anwendung - Bessere Nachverfolgbarkeit von Fehlern und Systemverhalten 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
221 lines
6.7 KiB
Markdown
221 lines
6.7 KiB
Markdown
# OTP-System für Gastaufträge
|
|
|
|
## Übersicht
|
|
|
|
Das MYP-System verwendet ein sicheres 6-stelliges OTP (One-Time Password) System für die Ausführung genehmigter Gastaufträge. Dieses System ermöglicht es Gästen, ihre genehmigten Druckaufträge ohne Anmeldung zu starten.
|
|
|
|
## Funktionsweise
|
|
|
|
### 1. Antragstellung
|
|
- Gäste stellen über `/guest/request` einen Druckantrag
|
|
- System generiert automatisch eine eindeutige Anfrage-ID
|
|
- Admin wird über neue Anträge benachrichtigt
|
|
|
|
### 2. Admin-Genehmigung
|
|
- Admins können Anträge über `/admin/guest-requests` verwalten
|
|
- Bei Genehmigung wird automatisch ein 6-stelliger OTP-Code generiert
|
|
- Code besteht aus Großbuchstaben (A-Z) und Zahlen (0-9)
|
|
- Gültigkeitsdauer: 72 Stunden ab Genehmigung
|
|
|
|
### 3. Code-Verwendung
|
|
- Gäste können über `/guest/start` ihren Code eingeben
|
|
- System validiert Code und startet den zugehörigen Job
|
|
- Code wird nach einmaliger Verwendung ungültig
|
|
- Drucker wird automatisch über Tapo-Steckdose eingeschaltet
|
|
|
|
## Technische Details
|
|
|
|
### OTP-Generierung
|
|
```python
|
|
def generate_otp(self) -> str:
|
|
"""Generiert einen 6-stelligen alphanumerischen OTP-Code."""
|
|
characters = string.ascii_uppercase + string.digits
|
|
otp_plain = ''.join(secrets.choice(characters) for _ in range(6))
|
|
|
|
# Hash speichern für sichere Verifikation
|
|
otp_bytes = otp_plain.encode('utf-8')
|
|
salt = bcrypt.gensalt()
|
|
self.otp_code = bcrypt.hashpw(otp_bytes, salt).decode('utf-8')
|
|
|
|
# Ablaufzeit setzen
|
|
self.otp_expires_at = datetime.now() + timedelta(hours=72)
|
|
|
|
return otp_plain
|
|
```
|
|
|
|
### Code-Verifikation
|
|
```python
|
|
def verify_otp(self, otp_plain: str) -> bool:
|
|
"""Verifiziert einen 6-stelligen OTP-Code."""
|
|
# Normalisierung und Validierung
|
|
otp_normalized = otp_plain.upper().strip()
|
|
|
|
# Prüfungen: Länge, Verwendung, Ablauf
|
|
if len(otp_normalized) != 6:
|
|
return False
|
|
if self.otp_used_at:
|
|
return False
|
|
if self.otp_expires_at and datetime.now() > self.otp_expires_at:
|
|
return False
|
|
|
|
# Bcrypt-Verifikation
|
|
return bcrypt.checkpw(otp_normalized.encode('utf-8'),
|
|
self.otp_code.encode('utf-8'))
|
|
```
|
|
|
|
## Sicherheitsfeatures
|
|
|
|
### 1. Kryptographische Sicherheit
|
|
- Verwendung von `secrets` Modul für kryptographisch sichere Zufallszahlen
|
|
- Bcrypt-Hashing mit Salt für Code-Speicherung
|
|
- Keine Klartext-Speicherung der Codes
|
|
|
|
### 2. Zeitbasierte Gültigkeit
|
|
- Automatischer Ablauf nach 72 Stunden
|
|
- Einmalige Verwendung pro Code
|
|
- Zeitstempel für Verwendung und Ablauf
|
|
|
|
### 3. Validierung
|
|
- Eingabe-Normalisierung (Großbuchstaben)
|
|
- Längen-Validierung (exakt 6 Zeichen)
|
|
- Alphanumerische Zeichen-Prüfung
|
|
|
|
## API-Endpunkte
|
|
|
|
### Für Gäste
|
|
- `GET /guest/start` - Code-Eingabe-Formular
|
|
- `POST /api/guest/start-job` - Job mit Code starten
|
|
|
|
### Für Admins
|
|
- `GET /api/admin/requests/{id}/otp` - OTP-Code abrufen
|
|
- `POST /api/requests/{id}/approve` - Antrag genehmigen (generiert OTP)
|
|
- `POST /api/requests/{id}/deny` - Antrag ablehnen/widerrufen
|
|
|
|
## Datenbank-Schema
|
|
|
|
### GuestRequest Erweiterungen
|
|
```sql
|
|
-- OTP-Verwaltung
|
|
otp_code VARCHAR(100) NULL, -- Bcrypt-Hash des OTP-Codes
|
|
otp_expires_at DATETIME NULL, -- Ablaufzeit des Codes
|
|
otp_used_at DATETIME NULL, -- Zeitpunkt der Verwendung
|
|
|
|
-- Admin-Verwaltung
|
|
approved_by INTEGER NULL, -- Admin der genehmigt hat
|
|
approved_at DATETIME NULL, -- Zeitpunkt der Genehmigung
|
|
rejection_reason TEXT NULL, -- Grund bei Ablehnung
|
|
```
|
|
|
|
## Benutzerführung
|
|
|
|
### Für Gäste
|
|
1. Antrag über Webformular stellen
|
|
2. Warten auf Admin-Genehmigung
|
|
3. 6-stelligen Code erhalten (E-Mail/Benachrichtigung)
|
|
4. Code auf Startseite eingeben
|
|
5. Job wird automatisch gestartet
|
|
|
|
### Für Admins
|
|
1. Benachrichtigung über neue Anträge
|
|
2. Anträge in Admin-Panel prüfen
|
|
3. Genehmigen oder ablehnen
|
|
4. OTP-Code bei Bedarf anzeigen/kopieren
|
|
5. Genehmigungen bei Bedarf widerrufen
|
|
|
|
## Monitoring & Logging
|
|
|
|
### System-Logs
|
|
- OTP-Generierung wird protokolliert
|
|
- Code-Verifikation wird geloggt
|
|
- Fehlgeschlagene Versuche werden erfasst
|
|
- Admin-Aktionen werden dokumentiert
|
|
|
|
### Metriken
|
|
- Anzahl generierter Codes
|
|
- Erfolgsrate der Code-Verwendung
|
|
- Durchschnittliche Zeit bis zur Verwendung
|
|
- Abgelaufene/ungenutzte Codes
|
|
|
|
## Fehlerbehandlung
|
|
|
|
### Häufige Fehlerszenarien
|
|
1. **Ungültiger Code**: Code existiert nicht oder falsch eingegeben
|
|
2. **Abgelaufener Code**: Code ist älter als 72 Stunden
|
|
3. **Bereits verwendeter Code**: Code wurde bereits einmal benutzt
|
|
4. **Kein zugehöriger Job**: Job wurde gelöscht oder ist nicht verfügbar
|
|
5. **Job nicht startbar**: Job-Status erlaubt keinen Start
|
|
|
|
### Error-Responses
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": "Ungültiger oder bereits verwendeter Code"
|
|
}
|
|
```
|
|
|
|
## Konfiguration
|
|
|
|
### Einstellungen
|
|
```python
|
|
# OTP-Konfiguration
|
|
OTP_LENGTH = 6 # Code-Länge
|
|
OTP_VALIDITY_HOURS = 72 # Gültigkeitsdauer
|
|
OTP_CHARACTERS = string.ascii_uppercase + string.digits
|
|
|
|
# Sicherheits-Einstellungen
|
|
BCRYPT_ROUNDS = 12 # Bcrypt-Komplexität
|
|
MAX_OTP_ATTEMPTS = 3 # Max. Versuche pro IP
|
|
```
|
|
|
|
## Wartung & Administration
|
|
|
|
### Regelmäßige Aufgaben
|
|
1. **Cleanup abgelaufener Codes**: Automatische Bereinigung alter OTP-Einträge
|
|
2. **Monitoring**: Überwachung der Code-Verwendung und Erfolgsraten
|
|
3. **Backup**: Sicherung der OTP-Daten bei System-Backups
|
|
|
|
### Admin-Funktionen
|
|
- OTP-Code für genehmigte Anträge anzeigen
|
|
- Genehmigungen widerrufen (invalidiert OTP)
|
|
- Statistiken über Code-Verwendung
|
|
- Manuelle Code-Invalidierung bei Bedarf
|
|
|
|
## Sicherheitsrichtlinien
|
|
|
|
### Best Practices
|
|
1. **Codes niemals in Logs speichern** - Nur Hashes verwenden
|
|
2. **Sichere Übertragung** - HTTPS für alle OTP-Operationen
|
|
3. **Rate Limiting** - Begrenzung der Versuche pro IP
|
|
4. **Monitoring** - Überwachung verdächtiger Aktivitäten
|
|
5. **Regelmäßige Audits** - Überprüfung der OTP-Verwendung
|
|
|
|
### Compliance
|
|
- DSGVO-konform: Keine unnötige Speicherung persönlicher Daten
|
|
- Sicherheitsstandards: Verwendung bewährter Kryptographie
|
|
- Audit-Trail: Vollständige Protokollierung aller Aktionen
|
|
|
|
## Troubleshooting
|
|
|
|
### Häufige Probleme
|
|
1. **Code funktioniert nicht**: Prüfung auf Tippfehler, Ablauf, Verwendung
|
|
2. **Job startet nicht**: Validierung des Job-Status und Drucker-Verfügbarkeit
|
|
3. **Admin sieht keinen Code**: Prüfung der Genehmigung und OTP-Generierung
|
|
|
|
### Debug-Informationen
|
|
```python
|
|
# OTP-Status prüfen
|
|
request.get_otp_status() # 'valid', 'used', 'expired', 'not_generated'
|
|
|
|
# Verifikation testen
|
|
request.verify_otp(code) # True/False
|
|
|
|
# Code-Informationen
|
|
request.otp_expires_at # Ablaufzeit
|
|
request.otp_used_at # Verwendungszeit
|
|
```
|
|
|
|
---
|
|
|
|
**Version**: 1.0.0
|
|
**Letzte Aktualisierung**: $(date +%Y-%m-%d)
|
|
**Autor**: MYP Development Team |