07e23b957d
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
91 lines
2.7 KiB
Python
91 lines
2.7 KiB
Python
"""Pydantic schemas for User operations."""
|
|
from src.backend.models.api.tipi import UtcDateTime
|
|
from typing import Optional
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
|
|
class UserCreate(BaseModel):
|
|
"""Schema for creating a new user."""
|
|
username: str = Field(..., min_length=3, max_length=100)
|
|
password: str = Field(..., min_length=6, max_length=128)
|
|
email: Optional[str] = Field(None, max_length=255)
|
|
display_name: str = Field(..., min_length=1, max_length=255)
|
|
roles: list[str] = Field(default_factory=list)
|
|
is_admin: bool = False
|
|
language_pref: str = Field("it", pattern="^(it|en)$")
|
|
theme_pref: str = Field("light", pattern="^(light|dark)$")
|
|
|
|
|
|
class UserUpdate(BaseModel):
|
|
"""Schema for updating a user (admin)."""
|
|
email: Optional[str] = Field(None, max_length=255)
|
|
display_name: Optional[str] = Field(None, min_length=1, max_length=255)
|
|
roles: Optional[list[str]] = None
|
|
is_admin: Optional[bool] = None
|
|
active: Optional[bool] = None
|
|
language_pref: Optional[str] = Field(None, pattern="^(it|en)$")
|
|
theme_pref: Optional[str] = Field(None, pattern="^(light|dark)$")
|
|
|
|
|
|
class UserProfileUpdate(BaseModel):
|
|
"""Schema for user self-update (profile)."""
|
|
display_name: Optional[str] = Field(None, min_length=1, max_length=255)
|
|
language_pref: Optional[str] = Field(None, pattern="^(it|en)$")
|
|
theme_pref: Optional[str] = Field(None, pattern="^(light|dark)$")
|
|
|
|
|
|
class UserResponse(BaseModel):
|
|
"""Schema for user response."""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
username: str
|
|
email: Optional[str] = None
|
|
display_name: str
|
|
roles: list[str]
|
|
is_admin: bool
|
|
language_pref: str
|
|
theme_pref: str
|
|
active: bool
|
|
created_at: UtcDateTime
|
|
last_login: Optional[UtcDateTime] = None
|
|
# #59: solo il fatto che il PIN esista, mai l'hash
|
|
has_pin: bool = False
|
|
|
|
|
|
class UserPasswordChange(BaseModel):
|
|
"""Schema for changing user password (admin only)."""
|
|
password: str = Field(..., min_length=6, max_length=128)
|
|
|
|
|
|
class LoginRequest(BaseModel):
|
|
"""Schema for login request."""
|
|
username: str
|
|
password: str
|
|
|
|
|
|
class LoginResponse(BaseModel):
|
|
"""Schema for login response."""
|
|
user: UserResponse
|
|
api_key: str
|
|
message: str = "Login successful"
|
|
|
|
|
|
class PinUserItem(BaseModel):
|
|
"""Voce dell'elenco pubblico per il login con PIN (#59): solo id e nome."""
|
|
id: int
|
|
display_name: str
|
|
|
|
|
|
class PinLoginRequest(BaseModel):
|
|
"""Login con PIN (#59)."""
|
|
user_id: int
|
|
pin: str = Field(..., pattern=r"^[0-9]{4}$")
|
|
|
|
|
|
class PinSet(BaseModel):
|
|
"""Imposta (4 cifre) o toglie (null) il PIN di un utente (#59)."""
|
|
pin: Optional[str] = Field(None, pattern=r"^[0-9]{4}$")
|
|
|