security_policy_session_store.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package repository
  2. import (
  3. "context"
  4. "strings"
  5. "time"
  6. "github.com/Wei-Shaw/sub2api/internal/service"
  7. "github.com/redis/go-redis/v9"
  8. )
  9. // securityPolicySessionStore 是 SecurityPolicySessionStore 的 Redis 实现:
  10. // HASH scope -> field(=会话 key hash),TTL 随每次命中刷新。管理端按 scope
  11. // 整体解封(DEL),无需扫描。
  12. type securityPolicySessionStore struct {
  13. rdb *redis.Client
  14. }
  15. func NewSecurityPolicySessionStore(rdb *redis.Client) service.SecurityPolicySessionStore {
  16. return &securityPolicySessionStore{rdb: rdb}
  17. }
  18. func (s *securityPolicySessionStore) MarkSessionBlocked(ctx context.Context, scope string, fields []string, ttl time.Duration) error {
  19. scope = strings.TrimSpace(scope)
  20. fields = trimSecurityPolicySessionFields(fields)
  21. if s == nil || s.rdb == nil || scope == "" || len(fields) == 0 {
  22. return nil
  23. }
  24. members := make(map[string]any, len(fields))
  25. for _, field := range fields {
  26. members[field] = 1
  27. }
  28. pipe := s.rdb.Pipeline()
  29. pipe.HSet(ctx, scope, members)
  30. if ttl > 0 {
  31. pipe.Expire(ctx, scope, ttl)
  32. }
  33. _, err := pipe.Exec(ctx)
  34. return err
  35. }
  36. func (s *securityPolicySessionStore) FindBlockedSessionField(ctx context.Context, scope string, fields []string) (string, error) {
  37. scope = strings.TrimSpace(scope)
  38. fields = trimSecurityPolicySessionFields(fields)
  39. if s == nil || s.rdb == nil || scope == "" || len(fields) == 0 {
  40. return "", nil
  41. }
  42. for _, field := range fields {
  43. exists, err := s.rdb.HExists(ctx, scope, field).Result()
  44. if err != nil {
  45. return "", err
  46. }
  47. if exists {
  48. return field, nil
  49. }
  50. }
  51. return "", nil
  52. }
  53. func (s *securityPolicySessionStore) UnblockSessionScope(ctx context.Context, scope string) (bool, error) {
  54. scope = strings.TrimSpace(scope)
  55. if s == nil || s.rdb == nil || scope == "" {
  56. return false, nil
  57. }
  58. deleted, err := s.rdb.Del(ctx, scope).Result()
  59. if err != nil {
  60. return false, err
  61. }
  62. return deleted > 0, nil
  63. }
  64. func trimSecurityPolicySessionFields(fields []string) []string {
  65. out := fields[:0]
  66. for _, field := range fields {
  67. if field = strings.TrimSpace(field); field != "" {
  68. out = append(out, field)
  69. }
  70. }
  71. return out
  72. }