feat: вход, роли и аудит действий (lct-23)
Самое крупное расхождение с ТЗ: входа не было вовсе, экраны открывались ссылкой с номером занятия, и пускало знание адреса. - Таблицы users и audit_log, миграция. Пароль argon2, сессия — подписанная cookie; роль на сокетах читается из той же cookie в момент рукопожатия, отдельного протокола авторизации в канале нет. - Разграничение: control — преподавателю, observe — преподавателю и админу, call и station — обучающемуся и преподавателю. Отказ приходит событием error с кодом forbidden. - Обучающийся не видит чужого: история подменяет фильтр на его собственный идентификатор, разбор и профиль сверяют trainee_id. ТЗ запрещает доступ к чужим результатам, а не только к чужим экранам. - Администратору закрыта правка оценок — ТЗ запрещает это прямо. - make users заводит по записи на роль и печатает случайные пароли один раз: зашитый в репозиторий admin/admin пережил бы сдачу. - Экран входа и проверка роли на каждом маршруте фронта. Наши инструменты не сломались: make lesson и тесты входят через dev-token за флагом dev_auth_bypass, на стенде точка отвечает 404 — выключенной функции не должно быть видно вовсе. У тестов появился conftest.py. Role уехала в домен и в generated.ts через EventCatalog.principal: иначе фронт переписывал бы список ролей руками. 181 тест зелёный (14 новых), make typecheck чистый.
This commit is contained in:
parent
4c2bbfd021
commit
d55c8bc8cd
30 changed files with 984 additions and 21 deletions
31
backend/tests/conftest.py
Normal file
31
backend/tests/conftest.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
"""Общая настройка тестов.
|
||||
|
||||
Голосовой контур выключен: он грузит модели около десяти секунд, а проверяется
|
||||
отдельно в `test_voice_pipeline.py`. Вход включён как на стенде, но тесты
|
||||
логинятся через `dev-token` — так же, как `make lesson` (tasks/lct-23-auth-roles.md).
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
os.environ.setdefault("DEV_AUTH_BYPASS", "true")
|
||||
|
||||
import pytest # noqa: E402
|
||||
|
||||
from app.config import get_settings # noqa: E402
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope="session")
|
||||
def _dev_auth():
|
||||
"""Флаг обхода читается один раз при создании настроек."""
|
||||
get_settings.cache_clear()
|
||||
settings = get_settings()
|
||||
assert settings.dev_auth_bypass, "тесты должны ходить через dev-token"
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def as_instructor(client):
|
||||
"""Клиент, вошедший преподавателем. Cookie живёт в самом TestClient."""
|
||||
response = client.post("/api/auth/dev-token")
|
||||
assert response.status_code == 200, response.text
|
||||
return client
|
||||
Loading…
Reference in a new issue