test(tradein/auth): правило про синхронную сверку — сторожем, а не комментарием (#2715) #2735
1 changed files with 27 additions and 0 deletions
|
|
@ -20,6 +20,13 @@
|
||||||
которую `grep 'verify_password('` не поймал бы вовсе — то есть ровно ту, ради
|
которую `grep 'verify_password('` не поймал бы вовсе — то есть ровно ту, ради
|
||||||
которой сторож и написан.
|
которой сторож и написан.
|
||||||
|
|
||||||
|
ЧЕГО СТОРОЖ НЕ ВИДИТ, и это записано тут, а не подразумевается: строкового
|
||||||
|
доступа (`getattr(mod, "verify_password")`) и обхода модуля целиком (прямой
|
||||||
|
`bcrypt.checkpw`). От НАМЕРЕННОГО обхода он не защищает и не может — только от
|
||||||
|
нечаянного, а нечаянный и есть частый случай. Обе непойманные формы закреплены
|
||||||
|
исполняемо (`test_detector_blind_spots_are_known`), чтобы «не ловим» было
|
||||||
|
проверенным фактом, а не обещанием в тексте.
|
||||||
|
|
||||||
Без БД и без сети — только чтение файлов.
|
Без БД и без сети — только чтение файлов.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -68,8 +75,28 @@ def test_detector_actually_detects() -> None:
|
||||||
assert not _references_verify_password("# verify_password тут только в комментарии")
|
assert not _references_verify_password("# verify_password тут только в комментарии")
|
||||||
|
|
||||||
|
|
||||||
|
def test_detector_blind_spots_are_known() -> None:
|
||||||
|
"""Слепые зоны — зафиксированы, а не забыты.
|
||||||
|
|
||||||
|
Обе формы обходят сторож НАМЕРЕННЫМ усилием: строковый доступ к атрибуту и
|
||||||
|
обход модуля целиком. Ловить их AST'ом можно было бы только ценой ложняков
|
||||||
|
(любой `getattr` с любой строкой, любой вызов bcrypt), а цена ложняка —
|
||||||
|
требование выключить сторож. Тест держит это знание исполняемым: захочет
|
||||||
|
однажды детектор их ловить — покраснеет здесь и заставит осознанно
|
||||||
|
переписать и этот тест, и текст модуля.
|
||||||
|
"""
|
||||||
|
assert not _references_verify_password('fn = getattr(password_mod, "verify_password")')
|
||||||
|
assert not _references_verify_password("bcrypt.checkpw(plain.encode(), hashed.encode())")
|
||||||
|
|
||||||
|
|
||||||
def test_sync_verify_password_is_called_from_one_place_only() -> None:
|
def test_sync_verify_password_is_called_from_one_place_only() -> None:
|
||||||
"""В `app/` синхронную сверку не поминает никто, кроме её собственного модуля."""
|
"""В `app/` синхронную сверку не поминает никто, кроме её собственного модуля."""
|
||||||
|
# Область сканирования жива. `rglob` по несуществующему каталогу не падает —
|
||||||
|
# отдаёт пусто, нарушителей ноль, сторож зелен НАВСЕГДА. Достаточно
|
||||||
|
# переложить этот файл в подкаталог tests/ (их уже восемь, и прецедент
|
||||||
|
# такого сторожа лежит именно в подкаталоге), чтобы `parents[1]` уехал.
|
||||||
|
assert _OWNER.exists(), f"область сканирования съехала: {_APP_DIR}"
|
||||||
|
|
||||||
offenders = [
|
offenders = [
|
||||||
str(path.relative_to(_BACKEND_ROOT))
|
str(path.relative_to(_BACKEND_ROOT))
|
||||||
for path in sorted(_APP_DIR.rglob("*.py"))
|
for path in sorted(_APP_DIR.rglob("*.py"))
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue