1fedd683e0
Stand: agent-06 (Audit-Log), agent-05 (Krankmeldung), agent-07 Phase 1 (Personalnummer), Busylight-Pull-Integration, TOTP/2FA, Abwesenheiten, Zeiterfassung, Kiosk-Grundgerüst. Migrations 0001–0023 deployed auf 192.168.1.137 + .164. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
103 lines
3.7 KiB
Python
103 lines
3.7 KiB
Python
from uuid import UUID
|
||
|
||
from fastapi import APIRouter, Depends, Header, HTTPException
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
||
from app.core.database import get_db
|
||
from app.core.dependencies import require_role
|
||
from app.models.user import User, UserRole
|
||
from app.schemas.kiosk import KioskDeviceCreate, KioskDeviceCreated, KioskDeviceOut, KioskDeviceUpdate
|
||
from app.services.kiosk_service import kiosk_service
|
||
|
||
router = APIRouter(prefix="/kiosk", tags=["Kiosk"])
|
||
|
||
_admin_roles = (UserRole.COMPANY_ADMIN, UserRole.SUPER_ADMIN)
|
||
|
||
|
||
# ── Geräteverwaltung (COMPANY_ADMIN) ──────────────────────────────────────────
|
||
|
||
@router.get("/devices", response_model=list[KioskDeviceOut])
|
||
async def list_devices(
|
||
current_user: User = require_role(*_admin_roles),
|
||
db: AsyncSession = Depends(get_db),
|
||
):
|
||
"""Alle registrierten Kiosk-Geräte der Firma auflisten."""
|
||
return await kiosk_service.list_devices(current_user.company_id, db)
|
||
|
||
|
||
@router.post("/devices", response_model=KioskDeviceCreated, status_code=201)
|
||
async def create_device(
|
||
data: KioskDeviceCreate,
|
||
current_user: User = require_role(*_admin_roles),
|
||
db: AsyncSession = Depends(get_db),
|
||
):
|
||
"""Neues Kiosk-Gerät registrieren. Token wird nur einmalig zurückgegeben."""
|
||
device, raw_token = await kiosk_service.create_device(current_user.company_id, data, db)
|
||
await db.commit()
|
||
await db.refresh(device)
|
||
return KioskDeviceCreated(
|
||
**KioskDeviceOut.model_validate(device).model_dump(),
|
||
token=raw_token,
|
||
)
|
||
|
||
|
||
@router.get("/devices/{device_id}", response_model=KioskDeviceOut)
|
||
async def get_device(
|
||
device_id: UUID,
|
||
current_user: User = require_role(*_admin_roles),
|
||
db: AsyncSession = Depends(get_db),
|
||
):
|
||
return await kiosk_service.get_device(device_id, current_user.company_id, db)
|
||
|
||
|
||
@router.patch("/devices/{device_id}", response_model=KioskDeviceOut)
|
||
async def update_device(
|
||
device_id: UUID,
|
||
data: KioskDeviceUpdate,
|
||
current_user: User = require_role(*_admin_roles),
|
||
db: AsyncSession = Depends(get_db),
|
||
):
|
||
device = await kiosk_service.update_device(device_id, current_user.company_id, data, db)
|
||
await db.commit()
|
||
await db.refresh(device)
|
||
return KioskDeviceOut.model_validate(device)
|
||
|
||
|
||
@router.post("/devices/{device_id}/rotate-token", response_model=KioskDeviceCreated)
|
||
async def rotate_token(
|
||
device_id: UUID,
|
||
current_user: User = require_role(*_admin_roles),
|
||
db: AsyncSession = Depends(get_db),
|
||
):
|
||
"""Token rotieren – das alte Token wird sofort ungültig."""
|
||
device, raw_token = await kiosk_service.rotate_token(device_id, current_user.company_id, db)
|
||
await db.commit()
|
||
await db.refresh(device)
|
||
return KioskDeviceCreated(
|
||
**KioskDeviceOut.model_validate(device).model_dump(),
|
||
token=raw_token,
|
||
)
|
||
|
||
|
||
@router.delete("/devices/{device_id}", status_code=204)
|
||
async def delete_device(
|
||
device_id: UUID,
|
||
current_user: User = require_role(*_admin_roles),
|
||
db: AsyncSession = Depends(get_db),
|
||
):
|
||
await kiosk_service.delete_device(device_id, current_user.company_id, db)
|
||
await db.commit()
|
||
|
||
|
||
# ── Kiosk-Auth (Gerät authentifiziert sich per Token) ─────────────────────────
|
||
|
||
@router.get("/me", response_model=KioskDeviceOut)
|
||
async def kiosk_me(
|
||
x_kiosk_token: str = Header(..., alias="X-Kiosk-Token", min_length=32, max_length=128),
|
||
db: AsyncSession = Depends(get_db),
|
||
):
|
||
"""Kiosk-Gerät prüft seine eigene Identität / aktualisiert last_seen_at."""
|
||
device = await kiosk_service.authenticate_device(x_kiosk_token, db)
|
||
await db.commit()
|
||
return KioskDeviceOut.model_validate(device)
|