Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gateway/platforms/qqbot/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,7 @@ def _is_authorized_interaction_for_session(

chat_type = parsed.get("chat_type", "")
chat_id = parsed.get("chat_id", "")
if chat_type == "c2c":
if chat_type in {"c2c", "dm"}:
return bool(chat_id) and operator == chat_id

if chat_type in {"group", "guild"}:
Expand Down
53 changes: 53 additions & 0 deletions tests/gateway/test_qqbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -1576,6 +1576,59 @@ def fake_resolve(session_key, choice, resolve_all=False):

assert resolve_calls == [("agent:main:qqbot:c2c:u-42", "once", False)]

@pytest.mark.asyncio
async def test_dm_approval_click_once_maps_to_once(self):
"""DM session approval clicks authorize when operator matches chat id."""
adapter = self._make_adapter()

resolve_calls = []

def fake_resolve(session_key, choice, resolve_all=False):
resolve_calls.append((session_key, choice, resolve_all))
return 1

import tools.approval
orig = tools.approval.resolve_gateway_approval
tools.approval.resolve_gateway_approval = fake_resolve
try:
from gateway.platforms.qqbot.keyboards import parse_interaction_event
event = parse_interaction_event({
"id": "i",
"chat_type": 2,
"user_openid": "u-42",
"data": {"resolved": {"button_data": "approve:agent:main:qqbot:dm:u-42:allow-once"}},
})
await adapter._default_interaction_dispatch(event)
finally:
tools.approval.resolve_gateway_approval = orig

assert resolve_calls == [("agent:main:qqbot:dm:u-42", "once", False)]

@pytest.mark.asyncio
async def test_dm_approval_click_rejects_mismatched_operator(self):
"""DM session approval clicks still require operator == chat_id."""
adapter = self._make_adapter()
resolve_calls = []

def fake_resolve(session_key, choice, resolve_all=False):
resolve_calls.append((session_key, choice, resolve_all))
return 1

import tools.approval
orig = tools.approval.resolve_gateway_approval
tools.approval.resolve_gateway_approval = fake_resolve
try:
from gateway.platforms.qqbot.keyboards import parse_interaction_event
event = parse_interaction_event({
"id": "i", "chat_type": 2, "user_openid": "attacker",
"data": {"resolved": {"button_data": "approve:agent:main:qqbot:dm:u-42:allow-once"}},
})
await adapter._default_interaction_dispatch(event)
finally:
tools.approval.resolve_gateway_approval = orig

assert resolve_calls == []

@pytest.mark.asyncio
async def test_approval_click_always_maps_to_always(self):
adapter = self._make_adapter()
Expand Down
Loading