Files
MoviePilot/app/schemas/token.py
Cat 87561a90d1 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>
2026-10-28 19:05:52 +08:00

53 lines
1.9 KiB
Python

"""
访问令牌、认证结果及令牌载荷的数据结构。
"""
from typing import Optional
from pydantic import BaseModel, Field
from app.schemas.user import UserPermissions
class MfaChallenge(BaseModel):
"""
密码认证通过后需要继续完成的二次验证信息。
"""
mfa_methods: list[str] = Field(default_factory=list, description="可用的二次验证方式")
class Token(BaseModel):
"""
OAuth2 登录成功后返回的访问令牌。
"""
access_token: str = Field(description="令牌")
token_type: str = Field(description="令牌类型")
super_user: bool = Field(description="超级用户")
user_id: int = Field(description="用户ID")
user_name: str = Field(description="用户名")
avatar: Optional[str] = Field(default=None, description="头像")
level: int = Field(default=1, description="权限级别")
permissions: Optional[UserPermissions] = Field(default_factory=UserPermissions, description="详细权限")
class TokenPayload(BaseModel):
"""
访问令牌中携带的用户身份与授权信息。
"""
sub: Optional[int] = Field(default=None, description="用户ID")
username: Optional[str] = Field(default=None, description="用户名")
super_user: Optional[bool] = Field(default=None, description="超级用户")
level: Optional[int] = Field(default=None, description="权限级别")
purpose: Optional[str] = Field(default=None, description="令牌用途 authentication\\resource")
agent_channel: Optional[str] = Field(
default=None,
description="宿主 Agent 签发令牌时绑定的消息渠道;仅宿主内部调用的令牌携带",
)
agent_channel_user: Optional[str] = Field(
default=None,
description="宿主 Agent 签发令牌时绑定的渠道发起用户标识;仅宿主内部调用的令牌携带",
)