Commit Graph

4 Commits

Author SHA1 Message Date
e007a85f56 Админка: защита от перебора пароля и правка дефолта SETTINGS_FILE
- не больше 10 неудачных входов с одного адреса за 5 минут, дальше 429
  (панель доступна из интернета, простой перебор закрываем);
  успешный вход сбрасывает счётчик;
- .env.example: SETTINGS_FILE пустой — локально настройки живут в памяти,
  в docker compose подставляет /data/settings.json по умолчанию.
2026-09-28 12:07:45 +03:00
cfa6a99639 Админка: секретный путь, смена ссылки, интервал и принудительное обновление
Панель без публичного входа: страница живёт по ADMIN_PATH, логин/пароль —
ADMIN_LOGIN/ADMIN_PASSWORD из .env (пусто = админка выключена и маршруты
/api/admin/* не регистрируются, прод можно не трогать).

Умеет: посмотреть текущую ссылку и состояние кэша, вставить новую ссылку
(проверяется скачиванием и разбором до сохранения, при ошибке откат),
принудительно обновить таблицу вне интервала и без проверки modified,
задать интервал в минутах (1..1440).

Реализация:
- backend/admin.py — cookie-сессия на HMAC (ключ = пароль, 12 часов,
  HttpOnly/SameSite/Secure-за-https), сравнение за постоянное время;
  compare_digest по байтам — кириллица в логине не роняет сервер;
- schedule/settings.py — ссылка и интервал в JSON (SETTINGS_FILE), атомарная
  запись, терпимость к битому/недоступному файлу (тогда живёт в памяти);
- schedule/cache.py — интервал вместо TTL, apply_link с откатом,
  force_reload, state() для панели; кэш без ссылки больше не роняет старт;
- frontend: страница admin.html (вне static, прямой /admin.html закрыт) и
  прокси /api/admin/* с телом и Set-Cookie;
- docker-compose: том schedule_data для настроек, ADMIN_* в окружении;
- deploy/: nginx-конфиг и инструкция для стенда dev.schedule.our-place.ru.

Тесты: 138 (новые — админ-API, сессии, ссылка/интервал, force, хранилище).
2026-09-28 12:06:25 +03:00
86c2a3097d Бэкенд: пакет schedule/ по зонам ответственности, обобщённый разбор ячеек
- xlsx.py: чтение книги (мержи, скрытые столбцы, красный текст), фикс дат до 1900
- lessons.py: общая схема ролей (предмет/преподаватель/аудитория/заметка)
  вместо ветвлений по числу строк; маркеры к.в., многострочные заметки,
  ФИО с/без отчества, организации, локации, метки групп -> заметки
- source.py: загрузка с Яндекс.Диска с понятными ошибками
- parsing.py: листы -> расписание, недели семестра, индексы преподов/аудиторий
- cache.py: lock, TTL, проверка modified, stale-while-error с retry cooldown
- main.py: create_app, /healthz, логирование; force-обновление убрано (вернётся с авторизацией)
- переменная окружения SCHEDULE_LINK
2026-09-09 11:33:19 +03:00
dcd9b854a0 Базовая функциональность 2026-09-09 08:25:53 +03:00