- 在 REAL_PROJECT_STATUS.md 开头追加 2026-05-10 最新验证快照
- 将 /uploads 路径遍历标记为 ✅ 已修复
- 创建 docs/sprints/SPRINT_17_COMPLETION_REPORT.md
92 lines
3.7 KiB
Markdown
92 lines
3.7 KiB
Markdown
# Sprint 17 完成报告(2026-05-08 ~ 2026-05-10)
|
||
|
||
## 概述
|
||
|
||
本 Sprint 聚焦于生产就绪收口:安全项全部落地、代码质量债务清理、单元测试补齐。全量测试通过,代码质量评分从 7.5 提升至 8.0+。
|
||
|
||
## 提交记录
|
||
|
||
| Commit | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| `3f3bb82` | fix | v6 code review P0 auth/IDOR fixes + frontend regression patches |
|
||
| `9b1cea2` | feat | permissions CRUD browser integration + E2E enhancements |
|
||
| `2a18a6f` | fix | N+1 查询:批量查询替代循环单查 |
|
||
| `d4ec8a1` | security | Argon2id 校准下限提升至 OWASP 阈值(SEC-ARGON2) |
|
||
| `8665c97` | fix | X-Forwarded-For IP 伪造防护 |
|
||
| `61692e4` | fix | /uploads 目录路径遍历防护 |
|
||
| `202b396` | docs | 更新生产就绪评审报告 — 安全项全部修复 |
|
||
| `1f7a223` | refactor | 提取分页魔法数字为 pagination 常量 |
|
||
| `9ad7b5c` | refactor | 提取 avatar handler 魔法数字为具名常量 |
|
||
| `2ecd1fe` | refactor | 提取 service 层 best-effort 超时常量 |
|
||
| `b3374dc` | refactor | 使用 pagination.ClampPageSize 简化 handler 分页代码 |
|
||
| `b8e9af0` | refactor | 提取公共分页解析函数 parsePageAndSize |
|
||
| `2801214` | test | 补齐 handler/repository/domain 层单元测试 |
|
||
|
||
## 完成项
|
||
|
||
### 1. 安全修复(P0 全部收口)
|
||
|
||
| 问题 | 修复内容 |
|
||
|------|----------|
|
||
| `/uploads` 路径遍历 | 替换 Static 为受控文件服务 handler,添加 `filepath.Clean` + `..` 检测 + 范围限制 |
|
||
| X-Forwarded-For IP 伪造 | `isTrustedProxy` 空列表默认不信任,`realIP` 从右到左跳过可信代理 |
|
||
| Argon2id 校准下限 | iterations 最低 2→3,memory 16MB→19MB(OWASP 最低要求) |
|
||
| N+1 查询(auth_capabilities) | `IsAdminBootstrapRequired` 中 `userRepo.GetByID` 循环 → `GetByIDs` 批量 |
|
||
| N+1 查询(AssignRoles) | `AssignRoles` 中 `roleRepo.GetByID` 循环 → `GetByIDs` 批量 |
|
||
|
||
### 2. 技术债务清理
|
||
|
||
| 问题 | 修复内容 |
|
||
|------|----------|
|
||
| 魔法数字 | `avatar_handler.go` 提取 5 个具名常量;`pagination` 包提取 `DefaultPageSize`/`MaxPageSize`/`ClampPageSize` |
|
||
| 分页代码重复 | `common.go` 新增 `parsePageAndSize(c)` 统一解析函数,消除 3 个 handler 的重复代码 |
|
||
| Best-effort 超时 | `auth.go` 提取 `defaultBETimeout = 5 * time.Second`,消除 6 处硬编码 |
|
||
|
||
### 3. 单元测试补齐
|
||
|
||
新增 **20 个测试文件**,覆盖:
|
||
|
||
| 模块 | 文件数 | 测试用例数 |
|
||
|------|--------|-----------|
|
||
| handler | 10 | ~200+ |
|
||
| middleware | 4 | ~80+ |
|
||
| repository | 3 | 21 |
|
||
| domain | 2 | 10 |
|
||
| pkg/pagination | 1 | 5 |
|
||
|
||
**TOTP 测试修复**:修复 6 个 `totp-verify` 登录流程测试,根因是 `temp_token` 未从登录响应提取并传递,`device_id` 在登录和验证时不一致。
|
||
|
||
### 4. 代码质量评分
|
||
|
||
| 维度 | Sprint 16 | Sprint 17 | 变化 |
|
||
|------|-----------|-----------|------|
|
||
| 代码质量 | 7.0 | 8.0 | +1.0 |
|
||
| 安全强度 | 8.5 | 9.0 | +0.5 |
|
||
| 运维简洁性 | 6.5 | 7.5 | +1.0 |
|
||
| **综合** | **7.5** | **8.0+** | **+0.5** |
|
||
|
||
## 验证结果
|
||
|
||
| Command | Result |
|
||
|---------|--------|
|
||
| `go test -short ./...` | ✅ 0 失败 |
|
||
| `go vet ./...` | ✅ 0 问题 |
|
||
| `go build ./cmd/server` | ✅ 编译通过 |
|
||
| `go test -short ./internal/api/handler/` | ✅ 全部通过(42s) |
|
||
|
||
## 剩余缺口(低优先级)
|
||
|
||
以下包无测试文件,属于基础设施/常量,非核心业务逻辑:
|
||
- `internal/api/router` — 路由注册
|
||
- `internal/pkg/httputil` — HTTP 工具
|
||
- `internal/pkg/ctxkey` — 上下文键
|
||
- `internal/pkg/claude` — Claude 常量
|
||
- `internal/pkg/sysutil` — 系统工具
|
||
- `pkg/errors` — 错误包
|
||
|
||
## 分支状态
|
||
|
||
- **分支**:`fix/report-v6-p0-auth-and-idor`
|
||
- **领先 main**:14 commits
|
||
- **PR**:待合并至 main
|