mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-06-05 22:44:17 +00:00
9402f1bca5
TokenBlacklist Improvements: Fixed size limit enforcement to properly maintain max size of 1000 tokens Improved eviction strategy to remove expired tokens first before removing oldest Added proper cleanup of tokens during Add operation to prevent size overflow Fixed oldest token eviction logic to ensure correct token removal Added proper locking mechanisms to prevent race conditions Cache Improvements: Fixed cleanup mechanism to only remove truly expired items Improved eviction strategy in LRU cache to prioritize expired items Added smarter eviction in evictOldest to scan for expired items first Fixed aggressive cleanup that was removing valid items Maintained proper LRU ordering while handling evictions MetadataCache: Verified proper implementation of metadata caching with hourly refresh Confirmed proper handling of cache extension on fetch failures Validated thread-safe operations with proper RWMutex usage
111 lines
2.5 KiB
Go
111 lines
2.5 KiB
Go
package traefikoidc
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// TokenBlacklist manages a thread-safe list of revoked tokens with expiration.
|
|
type TokenBlacklist struct {
|
|
tokens map[string]time.Time
|
|
mutex sync.RWMutex
|
|
}
|
|
|
|
// NewTokenBlacklist creates a new token blacklist instance.
|
|
func NewTokenBlacklist() *TokenBlacklist {
|
|
return &TokenBlacklist{
|
|
tokens: make(map[string]time.Time),
|
|
}
|
|
}
|
|
|
|
// Add adds a token to the blacklist with an expiration time.
|
|
func (b *TokenBlacklist) Add(token string, expiry time.Time) {
|
|
b.mutex.Lock()
|
|
defer b.mutex.Unlock()
|
|
|
|
// Clean up expired tokens if we're at capacity
|
|
if len(b.tokens) >= 1000 {
|
|
now := time.Now()
|
|
futureThreshold := now.Add(time.Minute)
|
|
for t, exp := range b.tokens {
|
|
if now.After(exp) || futureThreshold.After(exp) {
|
|
delete(b.tokens, t)
|
|
}
|
|
}
|
|
|
|
// If still at capacity, remove oldest token
|
|
if len(b.tokens) >= 1000 {
|
|
var oldestToken string
|
|
var oldestTime time.Time
|
|
first := true
|
|
for t, exp := range b.tokens {
|
|
if first || exp.Before(oldestTime) {
|
|
oldestToken = t
|
|
oldestTime = exp
|
|
first = false
|
|
}
|
|
}
|
|
if oldestToken != "" {
|
|
delete(b.tokens, oldestToken)
|
|
}
|
|
}
|
|
}
|
|
|
|
b.tokens[token] = expiry
|
|
}
|
|
|
|
// IsBlacklisted checks if a token is in the blacklist and not expired.
|
|
func (b *TokenBlacklist) IsBlacklisted(token string) bool {
|
|
b.mutex.RLock()
|
|
defer b.mutex.RUnlock()
|
|
|
|
expiry, exists := b.tokens[token]
|
|
if !exists {
|
|
return false
|
|
}
|
|
|
|
// If token is expired, remove it and return false
|
|
if time.Now().After(expiry) {
|
|
// Switch to write lock to remove expired token
|
|
b.mutex.RUnlock()
|
|
b.mutex.Lock()
|
|
delete(b.tokens, token)
|
|
b.mutex.Unlock()
|
|
b.mutex.RLock()
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// Cleanup removes expired tokens from the blacklist.
|
|
// Also removes tokens that will expire within the next minute to prevent edge cases.
|
|
func (b *TokenBlacklist) Cleanup() {
|
|
b.mutex.Lock()
|
|
defer b.mutex.Unlock()
|
|
|
|
now := time.Now()
|
|
futureThreshold := now.Add(time.Minute)
|
|
|
|
for token, expiry := range b.tokens {
|
|
// Remove tokens that are expired or will expire soon
|
|
if now.After(expiry) || futureThreshold.After(expiry) {
|
|
delete(b.tokens, token)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove removes a token from the blacklist regardless of its expiration.
|
|
func (b *TokenBlacklist) Remove(token string) {
|
|
b.mutex.Lock()
|
|
defer b.mutex.Unlock()
|
|
delete(b.tokens, token)
|
|
}
|
|
|
|
// Count returns the current number of tokens in the blacklist.
|
|
func (b *TokenBlacklist) Count() int {
|
|
b.mutex.RLock()
|
|
defer b.mutex.RUnlock()
|
|
return len(b.tokens)
|
|
}
|