From e13374e3197bceef8daf78bc1060eb061abeb581 Mon Sep 17 00:00:00 2001 From: bot-backend Date: Sat, 29 Aug 2026 18:49:43 +0300 Subject: [PATCH] =?UTF-8?q?fix(smoke):=20=D0=BF=D0=B5=D1=80=D0=B8=D0=BC?= =?UTF-8?q?=D0=B5=D1=82=D1=80=20=D1=82=D1=80=D0=B5=D0=B1=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BB=20401=20=D0=BE=D1=82=20=D0=B2=D0=B5=D0=B1=D1=85=D1=83?= =?UTF-8?q?=D0=BA=D0=B0,=20=D0=BA=D0=BE=D1=82=D0=BE=D1=80=D1=8B=D0=B9=20PR?= =?UTF-8?q?-D3=20=D0=BE=D1=82=D0=BA=D1=80=D1=8B=D0=BB=20=D0=BD=D0=B0=D0=BC?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=BD=D0=BD=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Деплой main после #3237 покраснел на perimeter-smoke: FAIL: trade-in payments/notify — 401 anonymous -> got '405', expected 401 Это не регрессия, а сработавшая канарейка. PR-D3 (#3231) внёс notify в `_PUBLIC_PATHS` осознанно: это вебхук банка, он обязан быть достижим без наших заголовков. В теле того PR прямо сказано, что 401 здесь стал бы признаком поломки («вебхук банка получил бы отказ»). Ожидание в смоуке обновить забыли — ровно то, о чём предупреждал комментарий над блоком в PR-D2. Замена не ослабляет проверку, а усиливает: вместо GET→401 теперь POST→503, что утверждает сразу два факта — маршрут существует (404 означал бы старый образ) И приём платежей выключен (`payments_enabled=False`). 200 здесь поймает включение флага, сделанное мимо этого смоука. Плюс GET→405 закрепляет, что путь принимает только POST. Проверено на живом проде: POST notify 503, GET notify 405, checkout 401, meraocenka 404 на обоих путях; payments/payment_notifications/ payment_entitlements пусты. Полный прогон скрипта — ALL CHECKS PASSED. Ожидания под meraocenka.ru не тронуты: PR-D4 не смержен, 404 там остаётся канарейкой. --- scripts/smoke-mera-perimeter.sh | 41 ++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/scripts/smoke-mera-perimeter.sh b/scripts/smoke-mera-perimeter.sh index 3ac08d76..52357c7b 100644 --- a/scripts/smoke-mera-perimeter.sh +++ b/scripts/smoke-mera-perimeter.sh @@ -174,25 +174,38 @@ check "www.meraocenka.ru — 301 to canonical" "https://www.meraocenka.ru/" 301 check "www.merahome.ru — 301 to canonical" "https://www.merahome.ru/" 301 check "www.meraotsenka.ru — 301 to canonical" "https://www.meraotsenka.ru/" 301 -# 6. Платёжный периметр (PR-D2) — готовит почву под PR-D3 (роутер) и PR-D4 -# (Caddy), но САМ НИЧЕГО НЕ ОТКРЫВАЕТ. Ожидаем закрытое состояние С ОБЕИХ -# СТОРОН прямо сейчас: +# 6. Платёжный периметр. Заведён в PR-D2 как канарейка «ожидания обновляют +# вместе с тем PR, который путь открывает». Канарейка отработала: PR-D3 +# (#3231, роутер) смержен 29.08 и внёс notify в `_PUBLIC_PATHS`, ожидание +# здесь обновлено тем же днём — но уже ПОСЛЕ красного деплоя, а не вместе с +# ним. Кто будет делать PR-D4 — правьте ожидания в одном PR с ним. +# +# Состояние на 29.08, чего ждём сейчас: # - meraocenka.ru вообще не проксирует /trade-in/api/* (allowlist-by-default, -# см. проверку 2) — 404 от Caddy, до бэкенда не доходит; -# - gendsgn.ru проксирует /trade-in/api/* в tradein-backend, но rbac_guard -# (`_PUBLIC_PATHS` в app/core/rbac.py — ЭТОТ PR её не трогает) не знает -# платёжные пути и требует X-Authenticated-User → 401 анониму. -# Если один из этих чек-ов вдруг перестанет быть 404/401 РАНЬШЕ мержа -# PR-D3/PR-D4 — это и есть преждевременная утечка периметра, которую ловит -# этот смоук (канарейка: осознанно станет красной, когда PR-D3/PR-D4 явно -# откроют эти пути — тогда ожидания здесь надо обновить вместе с ними). +# см. проверку 2) — 404 от Caddy, до бэкенда не доходит. Это ВСЁ ЕЩЁ +# канарейка: PR-D4 не смержен, 404 должен держаться; +# - gendsgn.ru: `checkout` по-прежнему требует X-Authenticated-User → 401 +# анониму (он не публичный и не станет им); +# - gendsgn.ru: `notify` — публичный по построению (вебхук банка), см. +# комментарий у самой проверки ниже. check "meraocenka.ru payments/notify — must 404 (Caddy не проксирует, PR-D4)" \ "$BASE_MERA/trade-in/api/v1/trade-in/payments/notify" 404 check "meraocenka.ru payments/checkout — must 404 (Caddy не проксирует, PR-D4)" \ "$BASE_MERA/trade-in/api/v1/trade-in/payments/checkout" 404 -check "trade-in payments/notify — 401 anonymous (rbac закрыт до PR-D3)" \ - "$BASE_MAIN/trade-in/api/v1/trade-in/payments/notify" 401 -check "trade-in payments/checkout — 401 anonymous (rbac закрыт до PR-D3)" \ +# notify — ЕДИНСТВЕННЫЙ платёжный путь, который PR-D3 (#3231) открыл анониму +# осознанно: это вебхук банка, он обязан быть достижим без наших заголовков, и +# потому внесён в `_PUBLIC_PATHS`. Канарейка выше отработала как задумано — 401 +# здесь стал бы теперь признаком ПОЛОМКИ (банк получил бы отказ), а не защиты. +# +# Проверяем POST и ждём 503: это строже прежнего 401 — утверждает сразу, что +# маршрут существует (не 404 — старый образ) И что приём платежей выключен +# (`payments_enabled=False`). 200 здесь означал бы, что флаг включили, не тронув +# этот смоук. GET → 405 закрепляет, что путь принимает только POST. +check_post "trade-in payments/notify — 503 anonymous (маршрут есть, приём выключен)" \ + "$BASE_MAIN/trade-in/api/v1/trade-in/payments/notify" '{}' 503 +check "trade-in payments/notify — 405 на GET (только POST)" \ + "$BASE_MAIN/trade-in/api/v1/trade-in/payments/notify" 405 +check "trade-in payments/checkout — 401 anonymous (не публичный по построению)" \ "$BASE_MAIN/trade-in/api/v1/trade-in/payments/checkout" 401 echo "========================================" -- 2.45.3