新增六边形架构核心代码包,包含: 1. 协议适配器层:HTTP/SMTP/IMAP/SSH/GRPC等多协议适配器实现 2. 认证插件体系:基础认证、API密钥、HMAC等多类型认证插件 3. 执行编排框架:工具执行器、上下文构建、运行时治理组件 4. 用例端口与DTO:定义领域服务端口与数据传输对象 5. 厂商集成包框架:支持第三方系统集成扩展 6. 基础设施装配层:实现依赖注入与服务装配 所有代码遵循六边形架构设计原则,实现端口与适配器解耦,支持动态扩展与自动发现。
55 lines
2.2 KiB
Python
55 lines
2.2 KiB
Python
"""Microsoft 365 厂商专属凭证 Pydantic 模型。
|
||
|
||
定义两个 ``AuthCredential`` 子类,分别对应应用权限(client_credentials)与
|
||
委托权限(authorization_code + PKCE)两种认证方式。
|
||
|
||
字段与 ``token_refresh.py`` 中刷新策略函数读取的 ``auth_config`` 字段一一对齐:
|
||
|
||
- ``Microsoft365ClientCredential`` ↔ ``_refresh_microsoft365_client_credentials``
|
||
- ``Microsoft365AuthCodeCredential`` ↔ ``_refresh_microsoft365_authorization_code``
|
||
|
||
``cloud`` 字段不在凭证中——它属于 ``connection_config``(见 ``cloud_endpoints.py``
|
||
模块注释),由刷新策略从 ``auth_config["connection_config"]["cloud"]`` 读取。
|
||
``scope`` 也不在凭证中——它由刷新策略根据 ``cloud`` 推导为
|
||
``{graph_host}/.default``。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from pydantic import ConfigDict
|
||
|
||
from yuxi.external_systems.framework.auth_plugins.credentials import AuthCredential
|
||
|
||
|
||
class Microsoft365ClientCredential(AuthCredential):
|
||
"""Microsoft 365 应用权限凭证(client_credentials 流)。
|
||
|
||
scope 由 ``cloud_endpoints`` 推导为 ``{graph_host}/.default``,不暴露为凭证字段。
|
||
cloud 从 ``connection_config`` 读取,不放在凭证中(见模块注释)。
|
||
"""
|
||
|
||
model_config = ConfigDict(populate_by_name=True, extra="ignore")
|
||
|
||
auth_type: str = "microsoft365_client_credentials"
|
||
tenant_id: str
|
||
client_id: str
|
||
client_secret: str
|
||
|
||
|
||
class Microsoft365AuthCodeCredential(AuthCredential):
|
||
"""Microsoft 365 委托权限凭证(authorization_code + PKCE)。
|
||
|
||
凭证存储的是首次授权码交换后回填的 ``refresh_token``,用于后续刷新。
|
||
``code_verifier`` 仅在首次 token 交换时使用,刷新阶段不携带。
|
||
首次授权码交换由前端 PKCE 流程完成,交换成功后 ``refresh_token`` 持久化到本凭证。
|
||
"""
|
||
|
||
model_config = ConfigDict(populate_by_name=True, extra="ignore")
|
||
|
||
auth_type: str = "microsoft365_authorization_code"
|
||
tenant_id: str
|
||
client_id: str
|
||
client_secret: str = "" # 公开客户端(SPA/移动端)可为空
|
||
refresh_token: str # 首次授权码交换后回填,后续刷新使用
|
||
code_verifier: str | None = None # 仅首次 token 交换使用,刷新阶段不携带
|