123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- package auth
- import (
- "context"
- "sync"
- "time"
- )
- // MemoryTokenStore implements TokenStore with in-memory storage
- type MemoryTokenStore struct {
- blacklist map[string]time.Time
- mutex sync.RWMutex
- // Optional cleaner to remove expired tokens
- cleanupInterval time.Duration
- stopCleanup chan struct{}
- }
- // NewMemoryTokenStore creates a new in-memory token store
- func NewMemoryTokenStore(cleanupInterval time.Duration) *MemoryTokenStore {
- store := &MemoryTokenStore{
- blacklist: make(map[string]time.Time),
- mutex: sync.RWMutex{},
- cleanupInterval: cleanupInterval,
- stopCleanup: make(chan struct{}),
- }
- // Start background cleanup if interval > 0
- if cleanupInterval > 0 {
- go store.startCleanupRoutine()
- }
- return store
- }
- // IsBlacklisted checks if a token is in the blacklist
- func (s *MemoryTokenStore) IsBlacklisted(ctx context.Context, token string) (bool, error) {
- s.mutex.RLock()
- defer s.mutex.RUnlock()
- expiry, exists := s.blacklist[token]
- if !exists {
- return false, nil
- }
- // If token has expired, we can remove it
- if time.Now().After(expiry) {
- // Don't remove here to avoid write lock during read operation
- return false, nil
- }
- return true, nil
- }
- // Blacklist adds a token to the blacklist
- func (s *MemoryTokenStore) Blacklist(ctx context.Context, token string, expiry time.Time) error {
- s.mutex.Lock()
- defer s.mutex.Unlock()
- s.blacklist[token] = expiry
- return nil
- }
- // startCleanupRoutine periodically removes expired tokens
- func (s *MemoryTokenStore) startCleanupRoutine() {
- ticker := time.NewTicker(s.cleanupInterval)
- defer ticker.Stop()
- for {
- select {
- case <-ticker.C:
- s.cleanup()
- case <-s.stopCleanup:
- return
- }
- }
- }
- // cleanup removes expired tokens from the blacklist
- func (s *MemoryTokenStore) cleanup() {
- now := time.Now()
- s.mutex.Lock()
- defer s.mutex.Unlock()
- for token, expiry := range s.blacklist {
- if now.After(expiry) {
- delete(s.blacklist, token)
- }
- }
- }
- // Close stops the cleanup goroutine
- func (s *MemoryTokenStore) Close() {
- if s.cleanupInterval > 0 {
- s.stopCleanup <- struct{}{}
- }
- }
|