feat: add controlled plugin marketplace lifecycle
This commit is contained in:
@@ -9,14 +9,17 @@
|
||||
| AUTH-05 | CSRF | 所有写请求 | `plugins/plugin-admin/main_test.go:TestMutationRequiresCSRFAndIdempotency` | passed |
|
||||
| SEC-01 | 秘密 | 浏览器、URL、HTML、JS、LocalStorage、下载、日志 | 登录/配置测试断言 token 和 secret 不回显;浏览器 DOM 未出现 Core token | passed |
|
||||
| SEC-02 | 出站 | Core URL、重定向、代理和 SSRF | `TestHealthProbeRejectsRedirectAndRequiresReadiness`;loopback URL 校验 | passed |
|
||||
| SEC-02A | 市场出站 | 索引/归档 HTTPS、精确主机 allowlist、DNS 私网拒绝、体积和重定向门禁 | `main_test.go:TestRemoteMarketplaceRequiresAllowlistAndExpiry`;`marketplace.go` 出站策略 | passed |
|
||||
| SEC-03 | 脱敏 | Core 响应和错误 | token/password/secret/cookie 不出现在响应和日志 | passed |
|
||||
| MAN-01 | 清单 | 未知字段、尾随 JSON、路径跳转 | `plugins/plugin-admin/internal/manifest/manifest_test.go`;包上传 smoke | passed |
|
||||
| MAN-02 | 签名 | Ed25519、key ID、哈希 | `manifest_test.go:TestSignatureAndKeyID`;生产不受信发布者路径 | passed |
|
||||
| MAN-03 | 兼容 | Core baseline、tested versions、capability | `manifest_test.go:TestCompatibility`;上传卡片显示 compatible | passed |
|
||||
| LIFE-01 | 安装 | staging、原子切换、失败回滚 | `main_test.go:TestPackageInspectionAndAtomicInstall`;真实上传后 active revision 可见 | passed |
|
||||
| LIFE-01A | 市场入库 | 仅从受控索引下载,校验哈希/清单后保持 disabled,不启动进程 | `main_test.go:TestMarketplaceInstallStagesPackageWithoutStartingAndDeleteSupportsHTTPDelete` | passed |
|
||||
| LIFE-02 | 启停 | enable/disable/drain | 停用路径有 SIGTERM + drain 超时逻辑;进程组清理和外部服务不误停 | passed |
|
||||
| LIFE-03 | 升级 | 新 revision 健康后切换 | 失败升级保留 active;模式切换不继承端点;成功提交后才切换进程 | passed |
|
||||
| LIFE-04 | 卸载 | 先停用再卸载 | 先提交注册表删除,成功后再清理插件资源,不删除 Core 数据 | passed |
|
||||
| LIFE-04A | 删除接口 | `DELETE /api/plugins/{id}` 与卸载语义一致 | 市场生命周期测试覆盖标准 DELETE | passed |
|
||||
| MENU-01 | 菜单 | preview/apply 自有 `custom_menu_items` | `main_test.go:TestMenuPreviewAndApplyPreserveOtherMenuItems` | passed |
|
||||
| MENU-02 | 嵌入 | iframe 和新窗口 | 本地控制面三视口登录/刷新;插件提供独立登录和新窗口入口 | passed |
|
||||
| API-01 | allowlist | 未声明路径和查询参数 | `allowedCorePath` 单元路径门禁;业务插件自身 allowlist 测试 | passed |
|
||||
|
||||
@@ -74,12 +74,16 @@ POST /logout
|
||||
GET /api/me
|
||||
GET /api/plugins
|
||||
GET /api/plugins/{id}
|
||||
GET /api/marketplace
|
||||
POST /api/marketplace/install
|
||||
POST /api/plugins/install
|
||||
POST /api/plugins/{id}/install
|
||||
POST /api/plugins/{id}/enable
|
||||
POST /api/plugins/{id}/disable
|
||||
POST /api/plugins/{id}/upgrade
|
||||
POST /api/plugins/{id}/rollback
|
||||
POST /api/plugins/{id}/uninstall
|
||||
DELETE /api/plugins/{id}
|
||||
GET /api/plugins/{id}/config
|
||||
PUT /api/plugins/{id}/config
|
||||
GET /api/audit
|
||||
@@ -92,10 +96,10 @@ POST /api/menu-items/apply
|
||||
## 6. 插件生命周期
|
||||
|
||||
```text
|
||||
discovered -> verified -> installed -> disabled -> starting -> healthy
|
||||
│ │
|
||||
│ └── error
|
||||
└── incompatible
|
||||
discovered -> verified -> staged/disabled -> starting -> healthy
|
||||
│ │
|
||||
│ └── error
|
||||
└── incompatible
|
||||
|
||||
healthy -> draining -> disabled
|
||||
healthy -> upgrading -> healthy
|
||||
@@ -104,8 +108,7 @@ healthy -> rollback_pending -> healthy
|
||||
|
||||
- `discovered`:目录或清单被发现,尚未验签。
|
||||
- `verified`:清单、签名、哈希和兼容性通过。
|
||||
- `installed`:版本包已安全写入 staging 并原子切换。
|
||||
- `disabled`:已安装但不接收业务请求,菜单默认隐藏。
|
||||
- `staged/disabled`:版本包已安全写入 staging 并原子切换,但仍是“已入库、待启用”;不接收业务请求,菜单默认隐藏。
|
||||
- `starting`:进程启动、端口和健康检查进行中。
|
||||
- `healthy`:健康端点、就绪端点和(若响应提供)版本检查通过。
|
||||
- `draining`:菜单已撤销,托管进程正在执行有界终止;在途请求由插件进程或反向代理按部署约定处理。
|
||||
@@ -132,7 +135,7 @@ ui/assets/...
|
||||
|
||||
控制面必须拒绝绝对路径、父目录跳转、重复条目、符号链接、未声明文件、超大文件和不匹配哈希。签名使用 Ed25519,签名覆盖 `manifest.json` 原始字节;清单中的 SHA-256 覆盖服务文件和 UI。发布者私钥不进入仓库、包、服务器或日志。
|
||||
|
||||
安装使用临时目录和原子 rename;失败不得破坏 active revision。包来源默认是管理员上传或受控本地目录,V1 不自动从互联网下载任意包。
|
||||
安装使用临时目录和原子 rename;失败不得破坏 active revision。包来源默认是管理员上传或受控本地目录。插件市场只允许服务端读取 schema v1 索引,并对 HTTPS 主机做精确 allowlist;浏览器只能提交索引中的 plugin ID/version,不能指定任意下载 URL。市场下载完成后仍只进入 `staged/disabled`,必须由管理员显式启用并通过健康检查。
|
||||
|
||||
## 8. Core API Adapter
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
控制面负责:
|
||||
|
||||
- 展示已登记、已安装和可升级的插件包;
|
||||
- 展示插件市场、已入库、运行中和可升级的插件包;
|
||||
- 校验清单、签名、文件哈希和 Core 兼容性;
|
||||
- 安装、启用、停用、升级、回滚、卸载和配置;
|
||||
- 下载/上传入库、启用、停用、升级、回滚、删除和配置;
|
||||
- 显示运行状态、健康检查结果和操作审计;
|
||||
- 对插件声明的管理员菜单执行预览和应用。
|
||||
|
||||
@@ -26,13 +26,13 @@
|
||||
管理员登录 plugin-admin
|
||||
|
|
||||
v
|
||||
插件目录 -> 上传/选择业务插件包
|
||||
插件市场/本地上传 -> 选择业务插件包
|
||||
|
|
||||
v
|
||||
清单 + 签名 + 哈希 + Core 兼容性校验
|
||||
|
|
||||
v
|
||||
安装到独立 revision,初始为 disabled
|
||||
下载并校验后写入独立 revision,初始为 disabled(已入库、待启用)
|
||||
|
|
||||
v
|
||||
启用 -> 启动独立服务端口 -> healthz/readyz/版本检查
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
状态:V1 通用插件控制面参考实现已落库;订阅业务插件只读适配与 Core Host Adapter/写操作仍为 Draft
|
||||
|
||||
本文规划一种不改动 Sub2API 核心代码、数据库和现有插件 ABI 的独立业务插件框架。当前 V1 控制面参考实现位于 `plugins/plugin-admin`,它负责插件清单、签名、安装、启停、升级、回滚、卸载、配置、审计和菜单注入;控制面本身不是订阅后台。每个业务插件(包括独立的 `plugins/subscription-admin`)作为可选的独立服务运行在自己的端口,通过控制面安装后再由部署层反向代理和现有“管理员可见自定义菜单”嵌入 Sub2API 页面。插件登录直接调用 Core 的现有鉴权,普通账号没有访问权限,也不复制 Core 用户表。
|
||||
本文规划一种不改动 Sub2API 核心代码、数据库和现有插件 ABI 的独立业务插件框架。当前 V1 控制面参考实现位于 `plugins/plugin-admin`,它负责插件清单、签名、插件市场、下载入库、启停、升级、回滚、卸载、配置、审计和菜单注入;控制面本身不是订阅后台。每个业务插件(包括独立的 `plugins/subscription-admin`)作为可选的独立服务运行在自己的端口,通过控制面安装后再由部署层反向代理和现有“管理员可见自定义菜单”嵌入 Sub2API 页面。插件登录直接调用 Core 的现有鉴权,普通账号没有访问权限,也不复制 Core 用户表。
|
||||
|
||||
V1 已实现范围以 `plugins/plugin-admin` 控制面和本文“当前实现范围”章节为准;本文中的订阅业务插件只是首个适配样例。Core Host Adapter、短时 Plugin Access Token、无感 SSO 和余额写操作仍是后续版本设计,不代表当前 Core 已提供这些接口。
|
||||
|
||||
@@ -241,6 +241,10 @@ Business Plugin V1 不直接套用现有 `manifest.schema.json`。建议新增
|
||||
|
||||
清单只声明能力和兼容范围,不授予数据库、路由或 secret 权限。V1 由部署脚本/反向代理保存清单、校验签名和允许的 Core API 路径;当前 Core 不会读取该清单,也没有业务插件注册表。插件发布包/容器镜像仍应签名,但签名验证属于部署门禁,不应写成现有 Core 能力。
|
||||
|
||||
### 7.1.1 受控插件市场
|
||||
|
||||
`plugin-admin` 可从本地或受控 HTTPS `schema_version=1` 索引展示市场条目。市场条目至少声明 `plugin_id`、版本、Core baseline、发布者 key ID、归档 SHA-256 和归档地址;远程索引必须有 `expires_at`,索引与归档主机必须匹配精确 allowlist,禁止重定向、凭据、查询参数和私网 DNS 地址。浏览器只能提交索引中的 ID/版本,下载、验签、哈希和清单兼容性校验全部由控制面服务端执行。下载成功只进入 `disabled`(已入库、待启用),不会启动插件;管理员显式启用并通过 health/readiness 检查后才进入 `healthy`。市场安装不隐式升级已有 ID,升级仍走升级和回滚流程。
|
||||
|
||||
### 7.2 状态机
|
||||
|
||||
```text
|
||||
|
||||
Reference in New Issue
Block a user