Files
user-system/docs/code-review/HERMES_FULL_REVIEW_2026-05-27.md
2026-05-28 15:18:49 +08:00

12 KiB
Raw Blame History

Hermes Full Review — 2026-05-27

  • 仓库:/home/long/project/user-system
  • 分支:main
  • 基线提交:82109ec Merge branch 'fix/status-review-sync-20260409'
  • 审查方式:文档对齐 + 代码静态复核 + 本地构建/测试/审计实测 + 二次复核补查
  • 结论: Not Ready / 当前不建议发布

1. Executive Summary

当前仓库不是“完全不可运行”,但不满足诚实发布条件。阻断原因主要有三类:

  1. 安全 / 权限 P0 问题

    • 普通登录用户可枚举全部用户并读取任意用户详情
    • TOTP 二次验证被降级成可单独换取登录态的入口
    • 多个“未配置”认证/绑定接口返回 200 + code:0,形成假成功
  2. 后端 clean-state 基线不绿

    • go build ./cmd/server
    • go vet ./...
    • go test ./... -count=1
    • 三者在当前提交态均失败,并提示 go mod tidy
  3. 文档状态比代码现实更乐观

    • README / 状态文档存在“已闭环 / 已完成”表述
    • 但实际仍有主链路契约漂移、假成功与 clean-state 基线不干净问题

2. 审查范围与方法

2.1 读取的关键文件

  • AGENTS.md
  • README.md
  • docs/PRD.md
  • docs/status/REAL_PROJECT_STATUS.md
  • go.mod
  • frontend/admin/package.json

2.2 执行的关键命令

后端:

  • go version
  • go build ./cmd/server
  • go vet ./...
  • go test ./... -count=1
  • go test -mod=mod ./internal/repository -count=1
  • go test -mod=mod ./... -count=1
  • go test ./... -coverprofile=/tmp/user-system-cover.out -count=1
  • go tool cover -func=/tmp/user-system-cover.out

前端:

  • npm ci
  • env -u NODE_ENV npm ci
  • env -u NODE_ENV npm run lint
  • env -u NODE_ENV npm run build
  • env -u NODE_ENV npm run test:run
  • env -u NODE_ENV npm run test:coverage
  • env -u NODE_ENV npm audit --omit=dev --json
  • env -u NODE_ENV npm audit --json

3. 验证快照

3.1 环境事实

  • Gogo1.26.3 linux/amd64
  • Nodev22.22.0
  • npm10.9.4
  • 观察到默认 shell 存在:NODE_ENV=production

3.2 环境风险

默认 NODE_ENV=production 会导致第一次 npm ci 只安装生产依赖,进而出现:

  • eslint: not found
  • tsc: not found
  • @vitejs/plugin-react not found

这说明 runbook / CI 若不显式控制环境变量,前端验证容易误判。

3.3 后端实测

当前提交态 / clean-state

以下命令均失败:

  • go build ./cmd/server
  • go vet ./...
  • go test ./... -count=1

统一报错:

go: updates to go.mod needed; to update it:
    go mod tidy

探索性验证

为了区分“代码问题”与“模块清单漂移问题”,额外执行:

  • go test -mod=mod ./internal/repository -count=1PASS
  • go test -mod=mod ./... -count=1PASS

说明:核心代码不是全部跑不起来,但提交态本身不干净

覆盖率

  • go tool cover -func=/tmp/user-system-cover.out
  • 总覆盖率:52.4%

3.4 前端实测

在显式移除 NODE_ENV=production 影响后:

  • env -u NODE_ENV npm ciPASS
  • env -u NODE_ENV npm run lintPASS
  • env -u NODE_ENV npm run buildPASS
  • env -u NODE_ENV npm run test:runPASS
    • 82 个 test files
    • 518 个 tests
  • env -u NODE_ENV npm run test:coveragePASS

前端 coverage

  • Statements: 89.83%
  • Branch: 80.38%
  • Funcs: 88.24%
  • Lines: 90.36%

3.5 前端依赖审计

  • env -u NODE_ENV npm audit --omit=dev --json0 漏洞
  • env -u NODE_ENV npm audit --json5 漏洞
    • 1 个 highvite 8.0.3

4. Blockers必须修复

P0-1 普通登录用户可枚举全部用户并读取任意用户详情

证据

  • internal/api/router/router.go:206-215
  • internal/api/handler/user_handler.go:90-165

问题

  • GET /api/v1/users
  • GET /api/v1/users/:id

当前仅挂在 protected.Use(r.authMiddleware.Required()) 下,未加:

  • AdminOnly
  • RequirePermission
  • 本人访问约束

影响 普通用户可读取其他用户列表 / 详情 / 邮箱等信息,属于明确数据越权。


P0-2 TOTP 验证接口可单独换取登录态,二次验证被降级为单因子登录

证据

  • internal/api/handler/auth_handler.go:151-172
  • internal/service/auth.go:811-831

问题 POST /api/v1/auth/login/totp-verify 只依赖:

  • user_id
  • code
  • device_id

没有要求:

  • 已完成密码登录
  • 临时 challenge ticket
  • 短期 server-side login session

影响 拿到 TOTP / 恢复码即可直接换取完整 token安全模型错误。


P0-3 未实现的绑定 / OAuth 接口使用 200 + code:0 伪装成功

证据

  • internal/api/handler/auth_handler.go:316-355
  • internal/api/handler/auth_handler.go:563-660
  • frontend/admin/src/lib/http/client.ts:274-279
  • frontend/admin/src/pages/admin/ProfileSecurityPage/ContactBindingsSection.tsx:141-216

问题 后端在以下场景仍返回成功语义:

  • OAuth not configured
  • email bind not configured
  • phone bind not configured
  • social binding not configured

前端只要 code===0 就按成功处理。

影响 用户会看到“已绑定 / 已解绑 / 已发送验证码”等成功反馈,但实际无状态变化。


P0-4 Bootstrap Admin 前后端契约冲突,首个管理员初始化默认不可用

证据 前端:

  • frontend/admin/src/pages/auth/BootstrapAdminPage/BootstrapAdminPage.tsx:24-30,68-76
  • frontend/admin/src/services/auth.ts:61-63

后端:

  • internal/api/handler/auth_handler.go:504-527

问题 前端未满足后端强制契约:

  • 缺少 X-Bootstrap-Secret
  • email 前端可为空,但后端必填

影响 首次部署时最关键的 bootstrap 链路可能直接失败。


P0-5 clean-state 后端构建基线不绿

证据

  • go build ./cmd/server → fail
  • go vet ./... → fail
  • go test ./... -count=1 → fail
  • 统一要求 go mod tidy

影响 当前 main 不满足仓库 AGENTS 要求的最低验证矩阵,不能诚实宣称“始终可构建、可测试通过”。


5. High / Important Issues

P1-1 Logout fail-opentoken 失效失败也返回成功

证据

  • internal/service/auth.go:897-925
  • internal/api/handler/auth_handler.go:185-209

问题 黑名单写入错误被忽略handler 仍返回 200 logged out


P1-2 多个 handler 的管理员判断读错 context key

证据 middleware 写入:

  • internal/api/middleware/auth.go:85-91
  • 写入 role_codes, permission_codes

handler 读取:

  • internal/api/handler/user_handler.go:188-200
  • internal/api/handler/user_handler.go:374-383
  • internal/api/handler/avatar_handler.go:72-85
  • 读取的是 user_roles

影响 管理员代操作逻辑可能失效,权限模型与实际行为漂移。


P1-3 修改密码接口与注释声明不一致

证据

  • internal/api/router/router.go:211-213
  • internal/api/handler/user_handler.go:275-297

问题 注释写“仅管理员或本人”,但 handler 没有显式按该规则做校验。


P1-4 密码历史记录异步写入,事务不完整

证据

  • internal/service/user_service.go:128-145

问题 密码更新同步写库,但密码历史在 goroutine 中异步写入且错误吞掉。


P1-5 Avatar token 随机源错误未 fail-closed

证据

  • internal/api/handler/avatar_handler.go:35-39

问题 rand.Read(bytes) 错误被忽略。


6. 二次复核补充(第一次遗漏后补查)

6.1 前端测试绿,但没挡住真实 API 契约漂移

  • 前端测试:518 passed
  • 但 bootstrap-admin、contact bindings、OAuth 与真实后端契约仍不一致

判断 这是测试体系盲点,不是“测试通过即可放心”。

6.2 前端开发依赖存在 1 个 high 漏洞

  • vite 8.0.3 high
  • 另有 moderate 级别依赖漏洞

6.3 NODE_ENV=production 造成验证误判风险

  • 未显式控制环境变量时devDependencies 可能缺失
  • 容易把环境问题误判为代码问题

6.4 后端总覆盖率仅 52.4%

在当前已有多条认证 / 权限高风险链路下,后端覆盖率偏低会放大回归风险。

6.5 测试 warning 噪音较多

实测出现:

  • act(...) warning
  • React Router future flag warning
  • danger 非布尔 attribute warning
  • addonAfter deprecated warning
  • React list key warning

虽然不阻断当前前端测试通过,但说明测试基线不够干净。


7. 文档真相审查

结论: 未闭环

当前 README 与 docs/status/REAL_PROJECT_STATUS.md 存在“闭环 / 已完成 / 当前绿色”等偏乐观表述,但 live review 证明:

  • 后端 clean-state 不绿
  • bootstrap-admin 主链路漂移
  • 绑定 / OAuth 存在假成功
  • 权限模型存在 P0

建议文档至少降级为:

前端 lint/build/test 当前可通过;后端代码在 -mod=mod 探索性测试下大体可运行,但 clean-state 构建基线未绿;认证 / 权限 / 绑定链路仍有 P0 阻断,不可宣称发布闭环。


8. 四类闭环判断

8.1 实现闭环

状态:

  • 权限越权未解决
  • TOTP 流程模型错误
  • bootstrap-admin 契约漂移
  • binding / OAuth 实际未闭环

8.2 证据闭环

状态:/⚠️ 部分成立

  • 前端构建 / 测试证据充分
  • 后端 clean-state 失败证据明确
  • 但这些事实尚未同步进主状态文档

8.3 文档真相闭环

状态:

  • 当前对外状态文档比代码现实更乐观

8.4 防复发闭环

状态: 尚未看到系统性防线去约束:

  • binding / OAuth 禁止 200 假成功
  • bootstrap 前后端契约对齐校验
  • /users/:id 权限回归测试
  • clean-state go build/vet/test gate
  • 真实 API contract 联调验证

9. 最终评级

维度 评级 说明
需求 / 实现一致性 C 多条主链路契约漂移
安全基线 D 存在 P0 权限 / 认证问题
构建与测试基线 C 前端绿,后端 clean-state 红
可维护性 B- 结构尚可,但存在 context key 漂移 / fail-open / 异步事务问题
文档真相 C- 文档明显乐观于代码现实
发布就绪度 D 当前不建议发布

综合评级D / Not Ready


10. 修复优先级建议

P0先修

  1. 修复 /api/v1/users/:id 越权
  2. 重构 totp-verify,必须绑定密码登录 challenge
  3. 所有未实现的 binding / OAuth 接口改为 fail-closed并同步前端处理
  4. 修复 bootstrap-admin 前后端契约
  5. 清理 go.mod/go.sum 漂移,恢复 clean-state build/vet/test 绿灯

P1紧随其后

  1. 修复 logout fail-open
  2. 修复 user_roles / role_codes context key 漂移
  3. 修复 password history 异步写入的事务缺口
  4. 修复 avatar token 生成未检查错误
  5. 升级前端 dev toolchain 漏洞(至少 vite

P2收口

  1. 清理测试 warning 噪音
  2. 补真实 API contract 集成测试
  3. 更新 README / docs/status/REAL_PROJECT_STATUS.md

11. 本次二次 Review 的新增补充摘要

相较第一次结论,本次额外明确了以下问题:

  1. 前端测试体系没有挡住真实 API 契约漂移
  2. 前端 dev toolchain 存在 1 个 high 漏洞Vite
  3. NODE_ENV=production 会导致 devDependencies 缺失runbook / CI 易误判
  4. 后端总覆盖率仅 52.4%
  5. 测试输出 warning 噪音较多,质量门禁不够干净

12. 最终结论

当前建议:不要发布;先修两个 high blocker 类问题,再推进剩余 P0 / P1。

其中最先收口的方向应是:

  • 认证 / 权限真安全
  • clean-state 构建真绿色
  • 文档真相与代码现实一致