fix(qqbot): authorize approval clicks on dm-spelled session keys - #98296
LanccBy2016 wants to merge 1 commit into
Conversation
C2C DMs build their gateway session key with chat_type="dm" (build_source in _on_c2c_message), but _is_authorized_interaction_for_session only accepted the literal "c2c". Every approval-button click on a 1:1 QQ DM was therefore rejected as unauthorized, the waiting agent stalled until its 5-minute approval timeout, and multi-turn sessions appeared frozen. Accept "dm" as a synonym of "c2c" — both name the same private chat whose chat_id is the owner's user_openid, so the operator match still gates authorization. Existing tests only ever exercised c2c-spelled keys, so the producer/consumer format drift went unnoticed; add regression tests for both the dm happy path and cross-user rejection.
|
Heads-up on the cluster around this line: this is one of several open PRs proposing the same one-line relaxation for Also noting: this is orthogonal to #98294 (namespace slot |
Duplicate of #31593: both patches authorize dm-spelled QQ C2C session keys through the same owner-equality branch. |
|
Closing as directed by triage — deferring to the canonical #31593 for the dm-spelled key authorization. (Local fork branch will be deleted.) |
Problem
On a 1:1 QQ C2C DM, every approval-button click is rejected as unauthorized, so the agent waits until its 5-minute approval timeout and multi-turn sessions appear frozen (
response ready: time=1118.9swith repeatedRejected unauthorized approval click … (operator=…)warnings where operator is the session owner).Root cause
Producer/consumer format drift on the session key:
_on_c2c_messagebuilds the gateway session source withbuild_source(chat_type="dm", …)(adapter.py:1327), so the key looks likeagent:main:qqbot:dm:<user_openid>._is_authorized_interaction_for_sessiononly matches the literal"c2c"(adapter.py:1134)."dm"falls through toreturn False.The existing tests all hand-craft
c2c-spelled keys (test_qqbot.py:922), so the drift is invisible to the suite.Fix
Treat
"dm"as a synonym ofc2cin the authorization check. Both name the same private chat whosechat_idsegment IS the owner'suser_openid, so theoperator == chat_idmatch still gates authorization — the relaxation adds no attack surface: a non-owner clicking the button still fails the check.Tests
test_approval_click_on_dm_key_from_c2c_operator_resolves— regression reproducing the field bug (fails on current main, passes with the fix).test_approval_click_on_dm_key_rejects_other_operator— asserts the cross-user rejection still holds on thedmspelling.test_qqbot.py(65) +test_qqbot_credential_isolation.py/test_qqbot_scope_paths.py(19).