From e42178e876176bdac7def0f325136a682628c9d2 Mon Sep 17 00:00:00 2001 From: wasrusgen Date: Tue, 12 May 2026 21:56:53 +0300 Subject: [PATCH] =?UTF-8?q?cleanup:=20drop=20debug=20prints=20=E2=80=94=20?= =?UTF-8?q?auth=20fallback=20verified=20working?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend-py/app/auth.py | 18 +----------------- backend-py/app/main.py | 13 ------------- 2 files changed, 1 insertion(+), 30 deletions(-) diff --git a/backend-py/app/auth.py b/backend-py/app/auth.py index b9e8c4d..afa4f27 100644 --- a/backend-py/app/auth.py +++ b/backend-py/app/auth.py @@ -15,43 +15,27 @@ def verify_init_data(init_data: str, bot_token: str, max_age_sec: int = 86400) - Спецификация: https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app """ - import sys if not init_data: - print("[AUTH] empty init_data", flush=True, file=sys.stderr) return None parsed = dict(parse_qsl(init_data, keep_blank_values=True)) received_hash = parsed.pop("hash", None) if not received_hash: - print(f"[AUTH] no hash in initData. keys={list(parsed.keys())}", flush=True, file=sys.stderr) return None # data_check_string: ключ=значение, отсортированы алфавитно, разделитель \n data_check_string = "\n".join(f"{k}={parsed[k]}" for k in sorted(parsed)) - # Trim token to handle accidental whitespace in env - token_clean = bot_token.strip() # secret_key = HMAC-SHA-256(key="WebAppData", data=BOT_TOKEN) - secret_key = hmac.new(b"WebAppData", token_clean.encode(), hashlib.sha256).digest() + secret_key = hmac.new(b"WebAppData", bot_token.strip().encode(), hashlib.sha256).digest() expected_hash = hmac.new(secret_key, data_check_string.encode(), hashlib.sha256).hexdigest() if not hmac.compare_digest(expected_hash, received_hash): - print( - f"[AUTH] HASH MISMATCH\n" - f" token_len={len(bot_token)} clean_len={len(token_clean)} " - f"head={token_clean[:6]}... tail=...{token_clean[-6:]}\n" - f" data_check_string={data_check_string!r}\n" - f" received_hash={received_hash}\n" - f" expected_hash={expected_hash}", - flush=True, file=sys.stderr, - ) return None # Свежесть подписи (24 часа по умолчанию) auth_date = int(parsed.get("auth_date", "0")) if time.time() - auth_date > max_age_sec: - print(f"[AUTH] auth_date too old: {auth_date}, now={time.time()}", flush=True, file=sys.stderr) return None - print(f"[AUTH] OK auth_date={auth_date}", flush=True, file=sys.stderr) user = None if "user" in parsed: diff --git a/backend-py/app/main.py b/backend-py/app/main.py index 632e58f..506b1f0 100644 --- a/backend-py/app/main.py +++ b/backend-py/app/main.py @@ -422,22 +422,17 @@ def api_catalog_preview_ai(cats: str = "fridge", tiers: str = ""): # ================================================================= def _handle_me(body: dict[str, Any]) -> dict[str, Any]: - import sys - print(f"[ME] entry: body keys={list(body.keys())} role_in_body={body.get('role')!r}", flush=True, file=sys.stderr) cfg = get_config() init_data = body.get("initData") or "" auth = verify_init_data(init_data, cfg.bot_token) - print(f"[ME] auth result: ok={bool(auth)} user_present={bool(auth and auth.get('user'))}", flush=True, file=sys.stderr) # Fallback для Telegram Desktop side-panel — initData может приходить пустым. # Доверяем initDataUnsafe.user (НЕпроверенным данным) — только для UI-режима. # Все endpoint-ы, выполняющие действия, продолжают требовать подписанный initData. if not auth or not auth.get("user"): unsafe = body.get("initDataUnsafe") or {} - print(f"[ME] fallback inspect: initDataUnsafe type={type(unsafe).__name__} keys={list(unsafe.keys()) if isinstance(unsafe, dict) else 'N/A'} value={str(unsafe)[:300]}", flush=True, file=sys.stderr) unsafe_user = unsafe.get("user") if isinstance(unsafe, dict) else None if unsafe_user and unsafe_user.get("id"): - print(f"[ME] FALLBACK: using initDataUnsafe.user id={unsafe_user.get('id')}", flush=True, file=sys.stderr) auth = { "user": unsafe_user, "auth_date": int(time.time()), @@ -445,7 +440,6 @@ def _handle_me(body: dict[str, Any]) -> dict[str, Any]: "_unsafe": True, } else: - print(f"[ME] fallback FAILED: unsafe_user={unsafe_user}", flush=True, file=sys.stderr) return {"error": "invalid_init_data"} tg_user = auth["user"] @@ -456,13 +450,6 @@ def _handle_me(body: dict[str, Any]) -> dict[str, Any]: # Берём roles из словаря если они уже распарсены (после grant_role), # иначе fallback на парсинг сырой CSV-колонки roles = user.get("roles") or sheets.parse_roles(user.get("role", "")) - import sys - print( - f"[ME] tg_id={tg_id} admin_id={cfg.admin_tg_id} " - f"explicit_role={explicit_role!r} user.role={user.get('role')!r} " - f"roles={roles}", - flush=True, file=sys.stderr, - ) # Staff (замерщик / сборщик) — отдельный кабинет, доступен только тем у кого роль выдана if explicit_role == "staff":