chore(security,refactor): extract sanitization and improve code quality (#41)

* chore(security,refactor): extract sanitization and improve code quality

- [x] Extract sanitization functions to dedicated sanitization.go module
- [x] Add comprehensive golangci-lint v2 configuration with security rules
- [x] Replace interface{} with any type throughout codebase
- [x] Add admin API authentication security warning
- [x] Extract WebSocket and stats streaming constants
- [x] Add best-effort error handling comments for resource cleanup
- [x] Expand sensitive field patterns for improved PII redaction
- [x] Simplify safety checks and remove redundant nil validations
- [x] Improve test coverage for password field redaction patterns

* refactor: replace interface{} with any type alias

- [x] Replace all `map[string]interface{}` with `map[string]any`
- [x] Replace all `interface{}` with `any` in function signatures and type definitions
- [x] Update sync.Pool New function returns from `interface{}` to `any`
- [x] Add package documentation comments to 8 package files
- [x] Update type assertions and casts to work with `any` type
This commit is contained in:
2026-01-17 00:04:12 +00:00
committed by GitHub
parent caeae62236
commit 3aa83d4480
42 changed files with 815 additions and 618 deletions
+11 -8
View File
@@ -1,3 +1,6 @@
// Package libpack_cache provides a unified caching interface that supports
// both in-memory and Redis backends. It handles response caching for GraphQL
// queries with automatic compression and TTL management.
package libpack_cache
import (
@@ -117,7 +120,7 @@ func EnableCache(cfg *CacheConfig) {
if err != nil {
cfg.Logger.Error(&libpack_logger.LogMessage{
Message: "Failed to create Redis client",
Pairs: map[string]interface{}{"error": err.Error()},
Pairs: map[string]any{"error": err.Error()},
})
// Fall back to memory cache
cfg.Client = libpack_cache_memory.New(time.Duration(cfg.TTL) * time.Second)
@@ -143,7 +146,7 @@ func EnableCache(cfg *CacheConfig) {
cfg.Logger.Debug(&libpack_logger.LogMessage{
Message: "Using in-memory cache",
Pairs: map[string]interface{}{
Pairs: map[string]any{
"type": cacheType,
"max_memory_size_bytes": maxMemory,
"max_entries": maxEntries,
@@ -179,7 +182,7 @@ func CacheLookup(hash string) []byte {
if err != nil {
config.Logger.Error(&libpack_logger.LogMessage{
Message: "Failed to create gzip reader for cached data",
Pairs: map[string]interface{}{"error": err.Error(), "hash": hash},
Pairs: map[string]any{"error": err.Error(), "hash": hash},
})
return nil
}
@@ -188,7 +191,7 @@ func CacheLookup(hash string) []byte {
if closeErr := reader.Close(); closeErr != nil {
config.Logger.Error(&libpack_logger.LogMessage{
Message: "Failed to close gzip reader",
Pairs: map[string]interface{}{"error": closeErr.Error(), "hash": hash},
Pairs: map[string]any{"error": closeErr.Error(), "hash": hash},
})
}
}()
@@ -197,7 +200,7 @@ func CacheLookup(hash string) []byte {
if err != nil {
config.Logger.Error(&libpack_logger.LogMessage{
Message: "Failed to decompress cached data",
Pairs: map[string]interface{}{"error": err.Error(), "hash": hash},
Pairs: map[string]any{"error": err.Error(), "hash": hash},
})
return nil
}
@@ -215,7 +218,7 @@ func CacheDelete(hash string) {
}
config.Logger.Debug(&libpack_logger.LogMessage{
Message: "Deleting data from cache",
Pairs: map[string]interface{}{"hash": hash},
Pairs: map[string]any{"hash": hash},
})
// Use atomic operations with validation to prevent inconsistent statistics
for {
@@ -240,7 +243,7 @@ func CacheStore(hash string, data []byte) {
}
config.Logger.Debug(&libpack_logger.LogMessage{
Message: "Storing data in cache",
Pairs: map[string]interface{}{"hash": hash},
Pairs: map[string]any{"hash": hash},
})
atomic.AddInt64(&cacheStats.CachedQueries, 1)
config.Client.Set(hash, data, time.Duration(config.TTL)*time.Second)
@@ -252,7 +255,7 @@ func CacheStoreWithTTL(hash string, data []byte, ttl time.Duration) {
}
config.Logger.Debug(&libpack_logger.LogMessage{
Message: "Storing data in cache with TTL",
Pairs: map[string]interface{}{"hash": hash, "ttl": ttl},
Pairs: map[string]any{"hash": hash, "ttl": ttl},
})
atomic.AddInt64(&cacheStats.CachedQueries, 1)
config.Client.Set(hash, data, ttl)
+4 -4
View File
@@ -38,12 +38,12 @@ func NewLRUMemoryCache(maxMemorySize, maxEntries int64) *LRUMemoryCache {
entries: make(map[string]*lruEntry),
evictList: list.New(),
gzipWriterPool: &sync.Pool{
New: func() interface{} {
New: func() any {
return gzip.NewWriter(nil)
},
},
gzipReaderPool: &sync.Pool{
New: func() interface{} {
New: func() any {
return &gzip.Reader{}
},
},
@@ -257,11 +257,11 @@ func (c *LRUMemoryCache) decompress(data []byte) ([]byte, error) {
}
// GetStats returns cache statistics
func (c *LRUMemoryCache) GetStats() map[string]interface{} {
func (c *LRUMemoryCache) GetStats() map[string]any {
c.mu.RLock()
defer c.mu.RUnlock()
return map[string]interface{}{
return map[string]any{
"entries": atomic.LoadInt64(&c.currentCount),
"memory_bytes": atomic.LoadInt64(&c.currentMemory),
"max_entries": c.maxEntries,
+9 -6
View File
@@ -1,3 +1,6 @@
// Package libpack_cache_memory provides an in-memory LRU cache implementation
// with automatic compression for large values, memory limits, and background
// eviction of expired entries.
package libpack_cache_memory
import (
@@ -61,12 +64,12 @@ func NewWithSize(globalTTL time.Duration, maxMemorySize int64, maxCacheSize int6
ctx: ctx,
cancel: cancel,
compressPool: sync.Pool{
New: func() interface{} {
New: func() any {
return gzip.NewWriter(nil)
},
},
decompressPool: sync.Pool{
New: func() interface{} {
New: func() any {
r, _ := gzip.NewReader(bytes.NewReader([]byte{}))
return r
},
@@ -204,7 +207,7 @@ func (c *Cache) Delete(key string) {
}
func (c *Cache) Clear() {
c.entries.Range(func(key, value interface{}) bool {
c.entries.Range(func(key, value any) bool {
c.entries.Delete(key)
return true
})
@@ -255,7 +258,7 @@ func (c *Cache) decompress(data []byte) ([]byte, error) {
func (c *Cache) CleanExpiredEntries() {
now := time.Now()
c.entries.Range(func(key, value interface{}) bool {
c.entries.Range(func(key, value any) bool {
entry := value.(CacheEntry)
if entry.ExpiresAt.Before(now) {
if _, exists := c.entries.LoadAndDelete(key); exists {
@@ -276,7 +279,7 @@ func (c *Cache) evictOldest(n int) {
// Collect all entries with their expiry times
entries := make([]keyExpiry, 0, n*2)
c.entries.Range(func(k, v interface{}) bool {
c.entries.Range(func(k, v any) bool {
key := k.(string)
entry := v.(CacheEntry)
entries = append(entries, keyExpiry{entry.ExpiresAt, key})
@@ -316,7 +319,7 @@ func (c *Cache) evictToFreeMemory(bytesToFree int64) {
// Collect entries to consider for eviction
entries := make([]keyMemorySize, 0, int(c.maxCacheSize/5))
c.entries.Range(func(k, v interface{}) bool {
c.entries.Range(func(k, v any) bool {
key := k.(string)
entry := v.(CacheEntry)
entries = append(entries, keyMemorySize{entry.ExpiresAt, key, entry.MemorySize})
+4 -1
View File
@@ -1,3 +1,6 @@
// Package libpack_cache_redis provides a Redis-backed cache implementation
// for distributed caching across multiple proxy instances. Supports key
// prefixing for multi-tenant isolation.
package libpack_cache_redis
import (
@@ -42,7 +45,7 @@ func New(redisClientConfig *RedisClientConfig) (*RedisConfig, error) {
ctx: context.Background(),
prefix: redisClientConfig.Prefix,
builderPool: &sync.Pool{
New: func() interface{} {
New: func() any {
return &strings.Builder{}
},
},
+5 -5
View File
@@ -29,7 +29,7 @@ func (w *CacheWrapper) Set(key string, value []byte, ttl time.Duration) {
if err := w.redis.Set(key, value, ttl); err != nil {
w.logger.Error(&libpack_logger.LogMessage{
Message: "Redis set error",
Pairs: map[string]interface{}{
Pairs: map[string]any{
"error": err.Error(),
"key": key,
},
@@ -43,7 +43,7 @@ func (w *CacheWrapper) Get(key string) ([]byte, bool) {
if err != nil {
w.logger.Error(&libpack_logger.LogMessage{
Message: "Redis get error",
Pairs: map[string]interface{}{
Pairs: map[string]any{
"error": err.Error(),
"key": key,
},
@@ -58,7 +58,7 @@ func (w *CacheWrapper) Delete(key string) {
if err := w.redis.Delete(key); err != nil {
w.logger.Error(&libpack_logger.LogMessage{
Message: "Redis delete error",
Pairs: map[string]interface{}{
Pairs: map[string]any{
"error": err.Error(),
"key": key,
},
@@ -71,7 +71,7 @@ func (w *CacheWrapper) Clear() {
if err := w.redis.Clear(); err != nil {
w.logger.Error(&libpack_logger.LogMessage{
Message: "Redis clear error",
Pairs: map[string]interface{}{
Pairs: map[string]any{
"error": err.Error(),
},
})
@@ -84,7 +84,7 @@ func (w *CacheWrapper) CountQueries() int64 {
if err != nil {
w.logger.Error(&libpack_logger.LogMessage{
Message: "Redis count queries error",
Pairs: map[string]interface{}{
Pairs: map[string]any{
"error": err.Error(),
},
})