Первоначальная версия VidConf
This commit is contained in:
78
backend/services/conference_access.py
Normal file
78
backend/services/conference_access.py
Normal file
@@ -0,0 +1,78 @@
|
||||
"""Проверка права входа в конференцию (статус/пароль) и генерация ответа join.
|
||||
|
||||
Заменяет `services/room_access.py`: комнаты больше не конкурируют за
|
||||
время («правило часа» удалено вместе с бронированием, ADR-001, п.5), но
|
||||
пароль закрытой конференции по-прежнему проверяется здесь же — для обычного
|
||||
пользователя и гостя одинаково.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from core.config import get_settings
|
||||
from core.security import verify_password
|
||||
from models.conference import Conference
|
||||
from schemas.conferences import JoinOut
|
||||
from services.livekit_tokens import create_room_access_token
|
||||
|
||||
|
||||
class ConferenceEndedError(Exception):
|
||||
"""Конференция завершена (терминальный статус) — повторный вход невозможен."""
|
||||
|
||||
|
||||
class PasswordRequiredError(Exception):
|
||||
"""Конференция закрыта паролем; пароль не передан."""
|
||||
|
||||
|
||||
class InvalidPasswordError(Exception):
|
||||
"""Указанный пароль не совпадает с паролем закрытой конференции."""
|
||||
|
||||
|
||||
def ensure_joinable(conference: Conference, *, password: str | None) -> None:
|
||||
"""Проверить, что в конференцию можно войти прямо сейчас.
|
||||
|
||||
Бросает `ConferenceEndedError` для терминального статуса `ended`
|
||||
(история и саммари остаются, но повторный вход невозможен — ADR-001,
|
||||
п.2), либо `PasswordRequiredError`/`InvalidPasswordError` для закрытой
|
||||
паролем конференции. Ничего не бросает для открытой конференции в
|
||||
статусе `scheduled`/`active`.
|
||||
"""
|
||||
if conference.status == "ended":
|
||||
raise ConferenceEndedError
|
||||
if not conference.is_closed:
|
||||
return
|
||||
if conference.password_hash is None or password is None:
|
||||
raise PasswordRequiredError
|
||||
if not verify_password(password, conference.password_hash):
|
||||
raise InvalidPasswordError
|
||||
|
||||
|
||||
def build_join(
|
||||
conference: Conference,
|
||||
*,
|
||||
identity: str,
|
||||
name: str,
|
||||
chat_enabled: bool,
|
||||
avatar_url: str | None = None,
|
||||
) -> JoinOut:
|
||||
"""Построить ответ join: LiveKit access-токен для входа в комнату конференции.
|
||||
|
||||
Имя LiveKit-комнаты всегда равно `conference.slug` (ADR-001, п.4).
|
||||
`chat_enabled` — снятый вызывающей стороной тоггл `instance_settings`:
|
||||
читается здесь параметром, а не заново из БД, чтобы не плодить
|
||||
отдельный запрос настроек на каждый join. `avatar_url` прокидывается
|
||||
в метаданные токена как JSON
|
||||
`{"avatar_url": ...}`; `None` (гость либо пользователь без аватара) —
|
||||
метаданные не выставляются вовсе.
|
||||
"""
|
||||
settings = get_settings()
|
||||
metadata = json.dumps({"avatar_url": avatar_url}) if avatar_url else None
|
||||
token = create_room_access_token(
|
||||
room_name=conference.slug, identity=identity, name=name, metadata=metadata
|
||||
)
|
||||
return JoinOut(
|
||||
livekit_url=settings.livekit_public_url,
|
||||
token=token,
|
||||
room_name=conference.slug,
|
||||
conference_id=conference.id,
|
||||
chat_enabled=chat_enabled,
|
||||
)
|
||||
Reference in New Issue
Block a user