fix: 修复代码审查中发现的P0/P1/P2问题

修复内容:
1. P0-01/P0-02: IAM Handler硬编码userID=1问题
   - getUserIDFromContext现在从认证中间件的context获取真实userID
   - 添加middleware.GetOperatorID公开函数
   - CheckScope方法添加未认证检查

2. P1-01: 审计服务幂等竞态条件
   - 重构锁保护范围,整个检查和插入过程在锁保护下
   - 使用defer确保锁正确释放

3. P1-02: 幂等中间件响应码硬编码
   - 添加statusCapturingResponseWriter包装器
   - 捕获实际的状态码和响应体用于幂等记录

4. P2-01: 事件ID时间戳冲突
   - generateEventID改用UUID替代时间戳

5. P2-02: ListScopes硬编码
   - 使用model.PredefinedScopes替代硬编码列表

所有supply-api测试通过
This commit is contained in:
Your Name
2026-04-03 12:25:22 +08:00
parent cb3c503152
commit f34333dc09
5 changed files with 85 additions and 33 deletions

View File

@@ -171,8 +171,11 @@ func (m *IdempotencyMiddleware) Wrap(handler IdempotentHandler) http.HandlerFunc
lockedRecord.PayloadHash = payloadHash
}
// 执行实际业务处理
err = handler(ctx, w, r, lockedRecord)
// 创建包装器以捕获实际的状态码和响应体
wrappedWriter := &statusCapturingResponseWriter{ResponseWriter: w}
// 执行实际业务处理,使用包装器捕获响应
err = handler(ctx, wrappedWriter, r, lockedRecord)
// 根据处理结果更新幂等记录
if err != nil {
@@ -182,11 +185,12 @@ func (m *IdempotencyMiddleware) Wrap(handler IdempotentHandler) http.HandlerFunc
return
}
// 业务处理成功,更新为成功状态
// 注意这里需要从w中获取实际的响应码和body
// 简化处理使用200
successBody, _ := json.Marshal(map[string]interface{}{"status": "ok"})
_ = m.idempotencyRepo.UpdateSuccess(ctx, lockedRecord.ID, http.StatusOK, successBody)
// 业务处理成功,使用捕获的实际状态码和body更新幂等记录
successBody := wrappedWriter.body
if len(successBody) == 0 {
successBody, _ = json.Marshal(map[string]interface{}{"status": "ok"})
}
_ = m.idempotencyRepo.UpdateSuccess(ctx, lockedRecord.ID, wrappedWriter.statusCode, successBody)
}
}
@@ -230,6 +234,23 @@ func writeIdempotentReplay(w http.ResponseWriter, status int, body json.RawMessa
}
}
// statusCapturingResponseWriter 包装http.ResponseWriter以捕获状态码
type statusCapturingResponseWriter struct {
http.ResponseWriter
statusCode int
body []byte
}
func (w *statusCapturingResponseWriter) WriteHeader(statusCode int) {
w.statusCode = statusCode
w.ResponseWriter.WriteHeader(statusCode)
}
func (w *statusCapturingResponseWriter) Write(b []byte) (int, error) {
w.body = append(w.body, b...)
return w.ResponseWriter.Write(b)
}
// context keys
type contextKey string
@@ -265,3 +286,8 @@ func getOperatorID(ctx context.Context) int64 {
}
return 0
}
// GetOperatorID 公开函数从context获取操作者ID
func GetOperatorID(ctx context.Context) int64 {
return getOperatorID(ctx)
}