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:
@@ -66,7 +66,7 @@ func (s *InMemoryAccountStore) List(ctx context.Context, supplierID int64) ([]*d
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
var result []*domain.Account
|
||||
result := make([]*domain.Account, 0)
|
||||
for _, account := range s.accounts {
|
||||
if account.SupplierID == supplierID {
|
||||
result = append(result, account)
|
||||
@@ -129,7 +129,7 @@ func (s *InMemoryPackageStore) List(ctx context.Context, supplierID int64) ([]*d
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
var result []*domain.Package
|
||||
result := make([]*domain.Package, 0)
|
||||
for _, pkg := range s.packages {
|
||||
if pkg.SupplierID == supplierID {
|
||||
result = append(result, pkg)
|
||||
@@ -192,7 +192,7 @@ func (s *InMemorySettlementStore) List(ctx context.Context, supplierID int64) ([
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
var result []*domain.Settlement
|
||||
result := make([]*domain.Settlement, 0)
|
||||
for _, settlement := range s.settlements {
|
||||
if settlement.SupplierID == supplierID {
|
||||
result = append(result, settlement)
|
||||
@@ -264,8 +264,9 @@ func (s *InMemoryEarningStore) GetBillingSummary(ctx context.Context, supplierID
|
||||
|
||||
// 内存幂等存储
|
||||
type InMemoryIdempotencyStore struct {
|
||||
mu sync.RWMutex
|
||||
records map[string]*IdempotencyRecord
|
||||
mu sync.RWMutex
|
||||
records map[string]*IdempotencyRecord
|
||||
cleanupCounter int64 // 清理触发计数器
|
||||
}
|
||||
|
||||
type IdempotencyRecord struct {
|
||||
@@ -303,6 +304,7 @@ func (s *InMemoryIdempotencyStore) SetProcessing(key string, ttl time.Duration)
|
||||
CreatedAt: time.Now(),
|
||||
ExpiresAt: time.Now().Add(ttl),
|
||||
}
|
||||
s.triggerCleanupLocked()
|
||||
}
|
||||
|
||||
func (s *InMemoryIdempotencyStore) SetSuccess(key string, response interface{}, ttl time.Duration) {
|
||||
@@ -316,4 +318,39 @@ func (s *InMemoryIdempotencyStore) SetSuccess(key string, response interface{},
|
||||
CreatedAt: time.Now(),
|
||||
ExpiresAt: time.Now().Add(ttl),
|
||||
}
|
||||
s.triggerCleanupLocked()
|
||||
}
|
||||
|
||||
// triggerCleanupLocked 触发清理(每100次操作清理一次过期记录)
|
||||
// 调用时必须持有锁
|
||||
func (s *InMemoryIdempotencyStore) triggerCleanupLocked() {
|
||||
s.cleanupCounter++
|
||||
if s.cleanupCounter >= 100 {
|
||||
s.cleanupCounter = 0
|
||||
s.cleanupExpiredLocked()
|
||||
}
|
||||
}
|
||||
|
||||
// cleanupExpiredLocked 清理过期记录(需要持有锁)
|
||||
func (s *InMemoryIdempotencyStore) cleanupExpiredLocked() {
|
||||
now := time.Now()
|
||||
for key, record := range s.records {
|
||||
if record.ExpiresAt.Before(now) {
|
||||
delete(s.records, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CleanExpired 主动清理过期记录(可由外部定期调用)
|
||||
func (s *InMemoryIdempotencyStore) CleanExpired() {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.cleanupExpiredLocked()
|
||||
}
|
||||
|
||||
// Len 返回当前记录数量(用于监控)
|
||||
func (s *InMemoryIdempotencyStore) Len() int {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return len(s.records)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user