Login (PIN/NFC/QR/Liste) lieferte einen session_token, aber es gab keinen
Endpunkt der ihn tatsächlich zum Stempeln nutzt (X-Kiosk-Session-Token war
nur als Konzept in kiosk_session_service dokumentiert, nirgends verdrahtet).
Neu: POST /kiosk/stamp/{in,out,break-start,break-end,status}. Gerät wird
weiterhin per Ed25519 verifiziert (verify_kiosk_request), zusätzlich validiert
_user_from_session() dass der session_token zu genau diesem Gerät gehört und
der User noch aktiv/in der richtigen Firma ist. Reuse von time_service
(stamp_in/out/break_start/break_end/get_today), source=KIOSK.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gis16MnuwkYcivLrSxK1pD
64 lines
1.9 KiB
Python
64 lines
1.9 KiB
Python
"""Schemas für Kiosk-User-Authentifizierung."""
|
|
import uuid
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class KioskPinLoginRequest(BaseModel):
|
|
"""Login via Personalnummer + PIN."""
|
|
personnel_number: str = Field(..., min_length=1)
|
|
pin: str = Field(..., min_length=4, max_length=16)
|
|
|
|
|
|
class KioskNfcLoginRequest(BaseModel):
|
|
"""Login via NFC-UID + Pflicht-PIN (Zweitfaktor, da UID allein klonbar ist)."""
|
|
nfc_uid: str = Field(..., min_length=1, max_length=64)
|
|
pin: str = Field(..., min_length=4, max_length=16)
|
|
|
|
|
|
class KioskQrLoginRequest(BaseModel):
|
|
"""Login via QR-Code (enthält verschlüsselten Token)."""
|
|
qr_token: str = Field(..., min_length=1)
|
|
|
|
|
|
class KioskSessionResponse(BaseModel):
|
|
"""Antwort nach erfolgreichem Kiosk-Login."""
|
|
session_token: str
|
|
user_id: uuid.UUID
|
|
user_name: str # "Max M." (Vorname + Nachname abgekürzt für Datenschutz)
|
|
expires_in_seconds: int # 900 (15 min)
|
|
auth_method: str # "pin" | "nfc" | "qr" | "list"
|
|
|
|
|
|
class KioskUserListEntry(BaseModel):
|
|
"""Minimale User-Info für Auswahl in der Mitarbeiterliste."""
|
|
id: uuid.UUID
|
|
display_name: str # "Max M." oder Kürzel
|
|
|
|
|
|
class KioskUserListResponse(BaseModel):
|
|
users: list[KioskUserListEntry]
|
|
|
|
|
|
class KioskStampRequest(BaseModel):
|
|
"""Body für Stempel-Aktionen. session_token identifiziert den eingeloggten
|
|
Mitarbeiter (aus /auth/pin|nfc|qr|list), das Gerät ist bereits über die
|
|
Ed25519-Signatur (verify_kiosk_request) authentifiziert."""
|
|
session_token: str = Field(..., min_length=1)
|
|
note: str | None = None
|
|
|
|
|
|
class KioskStampResponse(BaseModel):
|
|
entry_id: uuid.UUID
|
|
status: str # "stamped_in" | "stamped_out" | "break_started" | "break_ended"
|
|
warnings: list[str] = []
|
|
|
|
|
|
class KioskStampStatusRequest(BaseModel):
|
|
session_token: str = Field(..., min_length=1)
|
|
|
|
|
|
class KioskStampStatusResponse(BaseModel):
|
|
stamped_in: bool
|
|
on_break: bool
|
|
start_time: str | None = None
|