7.5 KiB
7.5 KiB
Business Plugin V1 验收矩阵
| ID | 类别 | 验收项 | 预期证据 | 状态 |
|---|---|---|---|---|
| AUTH-01 | 鉴权 | Core 管理员登录控制面 | plugins/plugin-admin/main_test.go:TestAdminLoginDoesNotExposeCoreTokens;本地浏览器登录 |
passed |
| AUTH-02 | 鉴权 | Core 2FA 登录 | challenge 一次性消费,成功创建会话 | passed |
| AUTH-03 | 鉴权 | 普通用户登录和 API | plugins/plugin-admin/main_test.go:TestOrdinaryCoreUserIsRejected |
passed |
| AUTH-03A | 鉴权 | Core CAPTCHA 配置与一次性 proof | TestCaptchaConfigReturnsOnlyPublicFields、TestLoginForwardsCaptchaProof;登录页按 provider 渲染挑战 |
passed |
| AUTH-04 | 会话 | 过期、撤销、登出和刷新 | plugins/plugin-admin/main_test.go:TestRefreshRevalidatesAdminRole |
passed |
| 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 |
| DEPLOY-01 | 发布完整性 | 安装提交 pin | deploy/install.sh 对 tag 要求 PLUGIN_COMMIT_SHA,并校验检出 commit;脚本可从 immutable commit URL 获取 |
passed (local) |
| DEPLOY-02 | 路径安全 | 安装/卸载根目录与父路径 | 安装路径拒绝根目录、./.. 和任一级符号链接父路径 |
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 和新窗口 | Plugin Admin 统一登录/刷新;订阅模块从统一控制面入口进入,iframe/新窗口均复用同一会话,不提供第二个登录页或 Cookie | passed |
| API-01 | allowlist | 未声明路径和查询参数 | allowedCorePath 单元路径门禁;业务插件自身 allowlist 测试 |
passed |
| API-02 | Core 错误 | 401/403/409/429/5xx | 失败关闭、刷新一次、错误脱敏和请求 ID 传播 | passed |
| UI-01 | 响应式 | 425px、900px、1440px | 本地 Browser 验收:三个视口 scrollWidth == innerWidth,插件卡片可见 |
passed |
| OPS-01 | 健康 | healthz/readyz、版本和 request ID | 控制面 HTTP smoke + 插件清单检查;健康/就绪响应含版本 | passed |
| OPS-02 | 权限 | 低权限账号、secret 文件和网络 | systemd 示例使用低权限账号、禁止提权、限制读写目录 | passed |
| REG-01 | 重建 | 清空 projection/cache | 控制面注册表可从磁盘恢复;健康 command/external 插件启动时重探 | passed |
| REG-02 | 兼容 | Core 升级/降级和旧插件 | 未测试版本保持 disabled,启动恢复再次检查 baseline | passed |
命令门禁
控制面和每个业务插件至少执行:
go test ./... -count=1
go vet ./...
node --check <all-ui-scripts>
release build (signed `.s2plugin` for business packages)
manifest verification
bash -n <all-shell-scripts>
git diff --check
浏览器验收必须保存三种视口截图、网络敏感字段扫描结果、iframe/新窗口登录结果、刷新恢复、停用、升级和回滚证据。Mock Core 只能证明契约;具备测试环境时必须追加真实 Core 登录、2FA、权限、分页和错误联调。
本轮证据
plugins/plugin-admin和plugins/subscription-admin:go test -race ./...、go vet ./...、node --check ui/app.js均通过;make check还覆盖 UI typecheck/build、全部 shell 语法和部署路径安全回归。plugins/subscription-admin/package.sh生成的.s2plugin已通过unzip -t,并通过控制面真实上传接口进入disabled状态。- 本地浏览器登录后,控制面首页、插件市场和操作记录可访问;普通登录与 Turnstile 模拟登录在 425、900、1440 视口均通过,无横向溢出或敏感响应字段。
- 仍需部署环境追加:真实生产签名密钥、发布归档/市场索引、跨实例共享会话、真实 Core iframe 刷新和跨节点升级演练;这些属于部署级门禁,不宣称已在本地完成,也不改变本地 V1 控制面契约。
浏览器脚本通过 PLUGIN_SCREENSHOT_DIR 输出 425px、900px、1440px 截图;本轮使用系统 Chrome 运行普通控制面、Turnstile fixture 和订阅模块三套验收,截图保留在本机临时证据目录。
本地生命周期硬化证据
plugins/plugin-admin/main_test.go:TestRecoverExternalPluginAfterRestart验证外部服务重启后重新探测并保持健康。plugins/plugin-admin/main_test.go:TestRecoverCommandPluginAfterRestart验证托管 command 插件重启后重新分配端口、启动进程组并探测健康/就绪。plugins/plugin-admin/main_test.go:TestPluginLockSerializesLifecycleMutations验证同一插件生命周期互斥。plugins/plugin-admin/main_test.go:TestIdempotencyKeyRejectsDifferentOperationHash和TestIdempotencyKeyReplaysSameBodyAndRetainsFailedOperation验证服务端请求体指纹、失败终态保留与冲突拒绝。plugins/plugin-admin/main_test.go:TestUpgradeDoesNotCarryEndpointAcrossServiceModes验证 command/external 模式不继承错误端点。tests/deploy-path-safety.sh验证安装、卸载和本地安装器拒绝符号链接父路径及缺失父目录,避免 root 操作越界。plugins/plugin-admin/main_test.go:TestRecoverCommandPluginAfterRestart使用有界 5 秒启动窗口,验证解释器型 command 插件在慢启动环境下仍可恢复,超时会清理进程。go test -race ./... -count=1、go vet ./...、全部 UI/测试脚本node --check、包构建、manifestcheck、unzip -t和git diff --check已通过。