Первоначальная версия VidConf
This commit is contained in:
113
backend/schemas/auth.py
Normal file
113
backend/schemas/auth.py
Normal file
@@ -0,0 +1,113 @@
|
||||
"""Pydantic-схемы для аутентификации и профиля пользователя."""
|
||||
|
||||
import uuid
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, EmailStr, Field
|
||||
|
||||
|
||||
class RegisterIn(BaseModel):
|
||||
"""Тело запроса регистрации нового пользователя.
|
||||
|
||||
`team_id` допустим только при включённой настройке инстанса
|
||||
`registration_team_choice` (см. `GET /auth/registration-options`) и
|
||||
существующей команде — иначе `POST /auth/register` вернёт 400.
|
||||
"""
|
||||
|
||||
email: EmailStr
|
||||
name_user: str = Field(min_length=1, max_length=255)
|
||||
password: str = Field(min_length=8)
|
||||
team_id: uuid.UUID | None = None
|
||||
|
||||
|
||||
class VerifyEmailIn(BaseModel):
|
||||
"""Тело запроса подтверждения email."""
|
||||
|
||||
token: str = Field(min_length=1)
|
||||
|
||||
|
||||
class TokenOut(BaseModel):
|
||||
"""Ответ с access-токеном; refresh-токен передаётся отдельно в httpOnly cookie."""
|
||||
|
||||
access_token: str
|
||||
token_type: str = "bearer"
|
||||
|
||||
|
||||
class UserOut(BaseModel):
|
||||
"""Публичное представление пользователя (профиль текущего пользователя).
|
||||
|
||||
`email: str`, а не `EmailStr` — намеренно: это response-схема,
|
||||
отражающая уже сохранённые в БД данные, а не принимающая новый ввод.
|
||||
`EmailStr` дополнительно отсекает синтаксически валидные, но
|
||||
зарезервированные домены (`.local`, `.test` и т.п. из RFC 6761) — валидный
|
||||
email на входе (`RegisterIn`, ниже) мог быть заведён напрямую в БД (seed,
|
||||
ручная миграция) с таким доменом; строгая `EmailStr` на выходе привела бы
|
||||
к 500 `ResponseValidationError` для уже существующих пользователей.
|
||||
"""
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
id: uuid.UUID
|
||||
email: str
|
||||
name_user: str
|
||||
role: str
|
||||
|
||||
|
||||
class UserListItemOut(BaseModel):
|
||||
"""Элемент списка пользователей (пикер участников конференции/мультиселект брони)."""
|
||||
|
||||
id: uuid.UUID
|
||||
display_name: str
|
||||
avatar_url: str | None = None
|
||||
|
||||
|
||||
class ProfileUpdateIn(BaseModel):
|
||||
"""Тело правки профиля текущего пользователя.
|
||||
|
||||
Email НЕ принимается — read-only поле профиля. `team_id` не различает
|
||||
«поле не передано» и «явный `null`» через сравнение с `None` — роутер
|
||||
читает `model_fields_set` (тот же приём, что `AdminUserUpdateIn.team_id`).
|
||||
"""
|
||||
|
||||
name_user: str | None = Field(default=None, min_length=1, max_length=255)
|
||||
team_id: uuid.UUID | None = None
|
||||
|
||||
|
||||
class UserProfileOut(UserOut):
|
||||
"""Профиль пользователя (свой либо открытый администратором) — `UserOut` + аватар/команда."""
|
||||
|
||||
avatar_url: str | None = None
|
||||
team_id: uuid.UUID | None = None
|
||||
team_name: str | None = None
|
||||
|
||||
|
||||
class PasswordChangeIn(BaseModel):
|
||||
"""Тело смены пароля текущим пользователем (`POST /users/me/password`).
|
||||
|
||||
Политика сложности `new_password` — та же, что при регистрации
|
||||
(`RegisterIn.password`, min 8 символов).
|
||||
"""
|
||||
|
||||
current_password: str
|
||||
new_password: str = Field(min_length=8)
|
||||
|
||||
|
||||
class RegistrationTeamOptionOut(BaseModel):
|
||||
"""Команда в списке опций публичной карточки регистрации."""
|
||||
|
||||
id: uuid.UUID
|
||||
name: str
|
||||
|
||||
|
||||
class RegistrationOptionsOut(BaseModel):
|
||||
"""Публичные опции формы регистрации (`GET /auth/registration-options`).
|
||||
|
||||
`teams` отдаётся только при `team_choice_enabled=True` — иначе пустой
|
||||
список (справочник команд не раскрывается, пока выбор выключен).
|
||||
`email_domain` — эталонный домен при включённой верификации регистрации
|
||||
по домену email (настройка инстанса `registration_email_domain`), иначе
|
||||
`None`.
|
||||
"""
|
||||
|
||||
team_choice_enabled: bool
|
||||
teams: list[RegistrationTeamOptionOut]
|
||||
email_domain: str | None = None
|
||||
Reference in New Issue
Block a user