fix: 系统性修复安全问题、性能问题和错误处理

安全问题修复:
- X-Forwarded-For越界检查(auth.go)
- checkTokenStatus Context参数传递(auth.go)
- Type Assertion安全检查(auth.go)

性能问题修复:
- TokenCache过期清理机制
- BruteForceProtection过期清理
- InMemoryIdempotencyStore过期清理

错误处理修复:
- AuditStore.Emit返回error
- domain层emitAudit辅助方法
- List方法返回空slice而非nil
- 金额/价格负数验证

架构一致性:
- 统一使用model.RoleHierarchyLevels

新增功能:
- Alert API完整实现(CRUD+Resolve)
- pkg/error错误码集中管理
This commit is contained in:
Your Name
2026-04-07 07:41:25 +08:00
parent 12ce4913cd
commit d5b5a8ece0
21 changed files with 2321 additions and 83 deletions

View File

@@ -3,6 +3,7 @@ package domain
import (
"context"
"errors"
"log"
"net/netip"
"time"
@@ -132,6 +133,14 @@ func NewPackageService(store PackageStore, accountStore AccountStore, auditStore
}
}
// emitAudit 安全记录审计日志(失败只记录错误,不影响主流程)
func (s *packageService) emitAudit(ctx context.Context, event audit.Event) {
if err := s.auditStore.Emit(ctx, event); err != nil {
log.Printf("[AUDIT_ERROR] failed to emit audit event: %v, object_type=%s, object_id=%d, action=%s",
err, event.ObjectType, event.ObjectID, event.Action)
}
}
func (s *packageService) CreateDraft(ctx context.Context, supplierID int64, req *CreatePackageDraftRequest) (*Package, error) {
pkg := &Package{
SupplierID: supplierID,
@@ -154,7 +163,7 @@ func (s *packageService) CreateDraft(ctx context.Context, supplierID int64, req
return nil, err
}
s.auditStore.Emit(ctx, audit.Event{
s.emitAudit(ctx, audit.Event{
TenantID: supplierID,
ObjectType: "supply_package",
ObjectID: pkg.ID,
@@ -183,7 +192,7 @@ func (s *packageService) Publish(ctx context.Context, supplierID, packageID int6
return nil, err
}
s.auditStore.Emit(ctx, audit.Event{
s.emitAudit(ctx, audit.Event{
TenantID: supplierID,
ObjectType: "supply_package",
ObjectID: packageID,
@@ -212,7 +221,7 @@ func (s *packageService) Pause(ctx context.Context, supplierID, packageID int64)
return nil, err
}
s.auditStore.Emit(ctx, audit.Event{
s.emitAudit(ctx, audit.Event{
TenantID: supplierID,
ObjectType: "supply_package",
ObjectID: packageID,
@@ -237,7 +246,7 @@ func (s *packageService) Unlist(ctx context.Context, supplierID, packageID int64
return nil, err
}
s.auditStore.Emit(ctx, audit.Event{
s.emitAudit(ctx, audit.Event{
TenantID: supplierID,
ObjectType: "supply_package",
ObjectID: packageID,
@@ -275,7 +284,7 @@ func (s *packageService) Clone(ctx context.Context, supplierID, packageID int64)
return nil, err
}
s.auditStore.Emit(ctx, audit.Event{
s.emitAudit(ctx, audit.Event{
TenantID: supplierID,
ObjectType: "supply_package",
ObjectID: clone.ID,
@@ -292,6 +301,17 @@ func (s *packageService) BatchUpdatePrice(ctx context.Context, supplierID int64,
}
for _, item := range req.Items {
// 验证价格不能为负数
if item.PricePer1MInput < 0 || item.PricePer1MOutput < 0 {
resp.FailedCount++
resp.Failures = append(resp.Failures, BatchPriceFailure{
PackageID: item.PackageID,
ErrorCode: "SUP_PKG_4004",
Message: "price cannot be negative",
})
continue
}
pkg, err := s.store.GetByID(ctx, supplierID, item.PackageID)
if err != nil {
resp.FailedCount++