Files
ros_control/tests/conftest.py
T
ayurishchevandClaude Opus 5.5 c4079724c5 Безопасность: проверка секретов, блокировка перебора входа, безопасные редиректы
Безопасность, пункты 1–4 ревью (docs/changes/021):
- приложение не стартует со слабыми секретами: API_TOKEN и SESSION_SECRET
  пустые, change-me или короче 32 символов, ADMIN_PASSWORD короче 12,
  невалидный SECRET_KEY; значения секретов в ошибку не попадают;
- вход в UI: 5 неверных попыток за 10 минут блокируют IP на 10 минут
  (429, пароль не проверяется); неверный пароль — 401; событие
  auth.locked пишется один раз, журнал не засыпается перебором;
- SESSION_COOKIE_SECURE — флаг Secure у cookie сессии (по умолчанию выкл.);
- _safe_next: редирект только на локальный путь (/ui/move, удаление бэкапов);
- .env.bak-* в .gitignore.

Тесты: 28 из 28. Стенд: change-me → 401, новый токен → 200, отказ старта
со слабым токеном, блокировка входа и редиректы проверены, боевые данные
не изменены. Ручная проверка UI пользователем на момент коммита не
подтверждена.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:41:58 +03:00

32 lines
1.8 KiB
Python

import pytest
from cryptography.fernet import Fernet
from app import db, security
from app.config import get_settings
from app.services import backups
# секреты для тестов: значения, проходящие проверку insecure_settings (см. app/config.py), но не боевые
API_TOKEN = "test-api-token-0123456789abcdef0" # 32 символа
ADMIN_PASSWORD = "test-admin-pass123" # 12+ символов
SESSION_SECRET = "test-session-secret-0123456789ab" # 32 символа
@pytest.fixture(autouse=True)
def env(tmp_path, monkeypatch):
monkeypatch.setenv("DATABASE_URL", f"sqlite:///{tmp_path}/test.db")
monkeypatch.setenv("SECRET_KEY", Fernet.generate_key().decode())
monkeypatch.setenv("SESSION_SECRET", SESSION_SECRET)
monkeypatch.setenv("API_TOKEN", API_TOKEN)
monkeypatch.setenv("S3_BUCKET", "test-bucket")
monkeypatch.setenv("S3_ACCESS_KEY", "") # без ключей S3: сверка бакета при старте отключена
monkeypatch.setenv("POLL_INTERVAL", "0") # фоновый опрос в тестах выключен
monkeypatch.setenv("ADMIN_USER", "admin") # не зависеть от реального .env
monkeypatch.setenv("ADMIN_PASSWORD", ADMIN_PASSWORD)
get_settings.cache_clear()
security.reset_failures("admin") # блокировки очистки журнала — в памяти процесса
security.reset_failures("login:testclient") # блокировки входа — в памяти процесса (IP TestClient по умолчанию)
backups.invalidate() # кэш списка бакета — модульное состояние, не должен переживать тест
db.init_db()
yield
get_settings.cache_clear()