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

@@ -2,6 +2,7 @@ package audit
import (
"context"
"fmt"
"sync"
"time"
)
@@ -23,8 +24,10 @@ type Event struct {
// 审计存储接口
type AuditStore interface {
Emit(ctx context.Context, event Event)
Emit(ctx context.Context, event Event) error
Query(ctx context.Context, filter EventFilter) ([]Event, error)
QueryWithTotal(ctx context.Context, filter EventFilter) ([]Event, int64, error)
GetByID(ctx context.Context, eventID string) (Event, error)
}
// 事件过滤器
@@ -52,13 +55,14 @@ func NewMemoryAuditStore() *MemoryAuditStore {
}
}
func (s *MemoryAuditStore) Emit(ctx context.Context, event Event) {
func (s *MemoryAuditStore) Emit(ctx context.Context, event Event) error {
s.mu.Lock()
defer s.mu.Unlock()
event.EventID = generateEventID()
event.CreatedAt = time.Now()
s.events = append(s.events, event)
return nil
}
func (s *MemoryAuditStore) Query(ctx context.Context, filter EventFilter) ([]Event, error) {
@@ -90,6 +94,52 @@ func (s *MemoryAuditStore) Query(ctx context.Context, filter EventFilter) ([]Eve
return result, nil
}
// QueryWithTotal 查询事件并返回总数
func (s *MemoryAuditStore) QueryWithTotal(ctx context.Context, filter EventFilter) ([]Event, int64, error) {
s.mu.RLock()
defer s.mu.RUnlock()
var result []Event
total := int64(0)
for _, event := range s.events {
total++
if filter.TenantID > 0 && event.TenantID != filter.TenantID {
continue
}
if filter.ObjectType != "" && event.ObjectType != filter.ObjectType {
continue
}
if filter.ObjectID > 0 && event.ObjectID != filter.ObjectID {
continue
}
if filter.Action != "" && event.Action != filter.Action {
continue
}
result = append(result, event)
}
// 限制返回数量
if filter.Limit > 0 && len(result) > filter.Limit {
result = result[:filter.Limit]
}
return result, total, nil
}
// GetByID 根据事件ID获取单个事件
func (s *MemoryAuditStore) GetByID(ctx context.Context, eventID string) (Event, error) {
s.mu.RLock()
defer s.mu.RUnlock()
for _, event := range s.events {
if event.EventID == eventID {
return event, nil
}
}
return Event{}, fmt.Errorf("event not found")
}
func generateEventID() string {
return time.Now().Format("20060102150405") + "-evt"
}