|
All checks were successful
CI / changes (pull_request) Successful in 8s
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 52s
rbac_guard гейтил только /api/v1/admin/* → revoked (role=expired, roles.yaml paths:[] deny:/**) и узко-скоупленные аккаунты сохраняли полный non-admin API-доступ (напр. POST /api/v1/search — экспорт листингов + estimate-quota). is_path_allowed (roles.yaml paths/deny) существовал, но НЕ вызывался (0 callers). Fix: после admin-гейта вызываем is_path_allowed(role, external_path) для всех non-bootstrap путей. roles.yaml globs — внешние (Caddy срезал /trade-in), поэтому восстанавливаем внешний путь (_EXTERNAL_PREFIX + path). Bootstrap-пути /me и /brand/* исключены — expired ДОЛЖЕН получить role=expired через /me (trial-экран) и брендинг; без исключения trial-UX сломался бы (expired paths:[] → 403 на /me). На сбой парса — fail-open + громкий лог (не лочим платящего pilot из-за конфиг-бага). roles.yaml НЕ меняю — только энфорсю уже задекларированную политику. pilot/admin/ analyst доступ сохранён (verified), expired теперь 403 на non-admin API. Тесты: +5 scope-кейсов (expired denied search/trade-in, allowed me/brand; pilot/ admin/analyst preserved) — 31 passed. Тест-harness middleware — mirror, обновлён. |
||
|---|---|---|
| .. | ||
| app | ||
| data/sql | ||
| scripts | ||
| tests | ||
| .dockerignore | ||
| Dockerfile | ||
| pyproject.toml | ||