OoO d276853e54 fix(post-3.5g): restore _is_authorized fail-closed for callback + message (CRIT-2 + HIGH-3)
從 4349db2~1 撈回 _is_authorized() 並重新套用到 callback 與 message handler。

問題:
- CRIT-2 (callback fail-open):原本只擋 group/supergroup 不匹配,
  private chat 任何人都能觸發 callback 指令(按鈕 menu/await/cmd)。
- HIGH-3 (message short-circuit fail):`if ALLOWED_USERS and _uid not in ALLOWED_USERS`
  在 OPENCLAW_ALLOWED_USERS 環境變數未設時 → ALLOWED_USERS 為空 set →
  `if False and ...` 整段不執行 → 所有 private 訊息都通過。

修法(fail-closed 三檢查):
1. 在頂部 import 區下方還原 `_is_authorized(chat_type, chat_id, user_id)`:
   - group/supergroup:chat_id 必須等於 ALLOWED_GROUP
   - private:user_id 必須在 ALLOWED_USERS(空 set → 全拒)
   - channel / 未知 / 缺欄位 → 拒絕
2. callback handler 替換為 `if not _is_authorized(chat_type, chat_id, cq_from_id)`
   並從 cq.get('from') 取 user_id(之前完全沒取)。
3. message handler 替換為統一檢查,未授權回 403 + 靜默(不回 Telegram 避免偵察)。

驗證:
- AST parse OK
- 模擬測試:999999 私訊 → False;111(在白名單)私訊 → True;
  錯誤群組 → False;channel → False;None → False
- grep 結果:剩下兩處 `_is_authorized` 呼叫(callback 5195, message 5255),
  舊的 `ALLOWED_USERS and _uid not in ALLOWED_USERS` 已移除(只留註解描述歷史)。

Critic findings: CRIT-2 + HIGH-3
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 14:40:22 +08:00
Description
EwoooC — 商品看板 + 業績報表 + AI KM (Flask + pgvector, Docker Compose on 188)
37 MiB
Languages
PostScript 59.7%
Python 30.9%
HTML 4.2%
CSS 2.1%
JavaScript 1.9%
Other 1.1%