""" Schema Pydantic per autenticazione e autorizzazione. """ import uuid from datetime import datetime from pydantic import BaseModel, EmailStr, Field, field_validator # ─── Request ────────────────────────────────────────────────────────────────── class LoginRequest(BaseModel): email: EmailStr password: str = Field(min_length=1) totp_code: str | None = Field(default=None, description="Codice TOTP 6 cifre (se 2FA attivo)") class RefreshRequest(BaseModel): refresh_token: str class TOTPVerifyRequest(BaseModel): totp_code: str = Field(min_length=6, max_length=6, description="Codice TOTP 6 cifre") class PasswordChangeRequest(BaseModel): current_password: str new_password: str = Field(min_length=8) @field_validator("new_password") @classmethod def validate_password_strength(cls, v: str) -> str: if len(v) < 8: raise ValueError("La password deve essere almeno 8 caratteri") if not any(c.isupper() for c in v): raise ValueError("La password deve contenere almeno una lettera maiuscola") if not any(c.isdigit() for c in v): raise ValueError("La password deve contenere almeno un numero") return v # ─── Response ───────────────────────────────────────────────────────────────── class TokenResponse(BaseModel): access_token: str refresh_token: str token_type: str = "bearer" expires_in: int = Field(description="Scadenza access token in secondi") class TOTPSetupResponse(BaseModel): """Dati per configurare TOTP sull'authenticator app.""" secret: str = Field(description="Segreto TOTP base32 (da inserire manualmente)") qr_uri: str = Field(description="URI otpauth:// per il QR code") qr_image_base64: str = Field(description="QR code come immagine PNG base64") class TOTPStatusResponse(BaseModel): totp_enabled: bool class UserTokenData(BaseModel): """Dati estratti dal JWT per l'utente corrente.""" user_id: uuid.UUID tenant_id: uuid.UUID role: str email: str | None = None