mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-11-05 22:59:46 +08:00
fix(agent): route agent command receipts to the signed channel user (#7228)
- Agent 代渠道用户调用内部 API 时,把会话渠道与渠道用户写入宿主签发令牌的签名 声明(agent_channel、agent_channel_user),不再新增可伪造的请求头。 - /commands/run 对 Telegram 等通知渠道只使用与请求渠道一致的签名渠道用户执行命令 和投递回执;缺少该声明时明确拒绝,不再把 MoviePilot 用户表主键当作渠道 chat id。 Web、WebAgent 与无渠道调用仍按 MoviePilot 用户 ID 处理。 - 只读公共资料借用宿主身份,不携带渠道发起人声明。 - 同步依赖基线与架构总览中的内部导入边数量。 Refs #7225 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: jxxghp <jxxghp@gmail.com>
This commit is contained in:
@@ -345,3 +345,47 @@ def test_executor_keeps_ascii_session_header_verbatim() -> None:
|
||||
headers = _build_context_headers(session_id)
|
||||
|
||||
assert headers["X-MoviePilot-Agent-Session"] == session_id
|
||||
|
||||
|
||||
@pytest.mark.parametrize("channel,channel_user_id", [
|
||||
(NotificationChannel.Telegram.value, "123456789"),
|
||||
(NotificationChannel.Wechat.value, "张三"),
|
||||
(NotificationChannel.Telegram.value, None),
|
||||
(None, "123456789"),
|
||||
])
|
||||
def test_executor_signs_channel_user_into_host_token(channel, channel_user_id) -> None:
|
||||
"""
|
||||
渠道发起人只写入宿主令牌的签名声明,不再以可伪造的请求头透传。
|
||||
"""
|
||||
executor = MoviePilotApiExecutor(
|
||||
context=ApiExecutionContext(
|
||||
user_id="1",
|
||||
username="admin",
|
||||
is_admin=True,
|
||||
channel=channel,
|
||||
channel_user_id=channel_user_id,
|
||||
),
|
||||
request_factory=MagicMock(return_value=SimpleNamespace(request=AsyncMock())),
|
||||
)
|
||||
|
||||
with patch("app.agent.api.executor.create_access_token", return_value="token") as create_token:
|
||||
headers = executor._build_headers()
|
||||
|
||||
signed = bool(channel and channel_user_id)
|
||||
assert create_token.call_args.kwargs.get("agent_channel") == (channel if signed else None)
|
||||
assert create_token.call_args.kwargs.get("agent_channel_user") == (channel_user_id if signed else None)
|
||||
assert not any(name.lower() == "x-moviepilot-agent-user" for name in headers)
|
||||
|
||||
|
||||
def test_public_executor_never_signs_channel_user() -> None:
|
||||
"""
|
||||
公共只读执行器即使收到渠道上下文,也不能把个人发起人绑定到宿主身份。
|
||||
"""
|
||||
executor = MoviePilotApiExecutor(context=ApiExecutionContext(
|
||||
user_id="1", username="admin", is_admin=True, public_read_only=True,
|
||||
channel=NotificationChannel.Telegram.value, channel_user_id="123456789",
|
||||
))
|
||||
with patch("app.agent.api.executor.create_access_token", return_value="token") as create_token:
|
||||
executor._build_headers()
|
||||
|
||||
create_token.assert_called_once_with(userid=1, username="admin", super_user=True)
|
||||
|
||||
Reference in New Issue
Block a user