* Add ability to disable replay protection. - This is useful for runs with multiple traefik replicas to avoid false positives and tokens re-creation.
* Enhance the CI/CD pipelines
* Increase test coverage.
* Update vendored dependencies.
* Update behaviour on forceHTTPS as per issue #82
This commit is contained in:
2025-10-16 10:56:28 +01:00
committed by GitHub
parent 79e9b164f9
commit ae59a5e88a
74 changed files with 10748 additions and 234 deletions
+1 -1
View File
@@ -355,7 +355,7 @@ func (c *Cache) removeItem(key string, item *Item) {
func (c *Cache) evictLRU() {
if elem := c.lruList.Back(); elem != nil {
item := elem.Value.(*Item)
item, _ := elem.Value.(*Item) // Safe to ignore: type assertion from known type
c.removeItem(item.Key, item)
atomic.AddInt64(&c.evictions, 1)
c.logger.Debugf("Cache: Evicted LRU item key=%s", item.Key)
+2
View File
@@ -1,3 +1,5 @@
// Package cache provides high-performance caching implementations for OIDC tokens, metadata, and JWKs.
// It includes compatibility wrappers for backward compatibility with existing cache interfaces.
package cache
import (
+2 -1
View File
@@ -91,7 +91,8 @@ func (e *OIDCError) ToJSON() map[string]any {
}
if e.Details != "" {
result["error"].(map[string]any)["details"] = e.Details
errorMap, _ := result["error"].(map[string]any) // Safe to ignore: type assertion from known type
errorMap["details"] = e.Details
}
return result
+1 -1
View File
@@ -130,7 +130,7 @@ func (h *AuthFlowHandler) waitForInitialization(req *http.Request) bool {
}
return true
case <-req.Context().Done():
h.logger.Debug("Request cancelled while waiting for OIDC initialization")
h.logger.Debug("Request canceled while waiting for OIDC initialization")
return false
case <-time.After(30 * time.Second):
h.logger.Error("Timeout waiting for OIDC initialization")
+1 -1
View File
@@ -246,7 +246,7 @@ func TestAuthFlowHandler_waitForInitialization(t *testing.T) {
expectedResult: false,
},
{
name: "Request cancelled",
name: "Request canceled",
setupHandler: func() (*AuthFlowHandler, context.CancelFunc) {
initComplete := make(chan struct{})
handler := &AuthFlowHandler{
+2 -2
View File
@@ -215,12 +215,12 @@ func (h *SessionHandler) SendErrorResponse(rw http.ResponseWriter, req *http.Req
// For AJAX requests, send JSON response
rw.Header().Set("Content-Type", "application/json")
rw.WriteHeader(statusCode)
fmt.Fprintf(rw, `{"error": "%s"}`, message)
_, _ = fmt.Fprintf(rw, `{"error": "%s"}`, message) // Safe to ignore: writing error response
} else {
// For browser requests, send HTML response
rw.Header().Set("Content-Type", "text/html")
rw.WriteHeader(statusCode)
fmt.Fprintf(rw, `<html><body><h1>Error %d</h1><p>%s</p></body></html>`, statusCode, message)
_, _ = fmt.Fprintf(rw, `<html><body><h1>Error %d</h1><p>%s</p></body></html>`, statusCode, message) // Safe to ignore: writing error response
}
}
+2 -2
View File
@@ -81,8 +81,8 @@ func (rp *RequestProcessor) WaitForInitialization(req *http.Request, initComplet
case <-initComplete:
return nil
case <-req.Context().Done():
rp.logger.Debug("Request cancelled while waiting for OIDC initialization")
return fmt.Errorf("request cancelled")
rp.logger.Debug("Request canceled while waiting for OIDC initialization")
return fmt.Errorf("request canceled")
case <-time.After(30 * time.Second):
rp.logger.Error("Timeout waiting for OIDC initialization")
return fmt.Errorf("timeout waiting for OIDC provider initialization")
+5 -5
View File
@@ -383,7 +383,7 @@ func TestWaitForInitialization(t *testing.T) {
}
})
t.Run("Request context cancelled", func(t *testing.T) {
t.Run("Request context canceled", func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
req := httptest.NewRequest("GET", "http://example.com/test", nil)
req = req.WithContext(ctx)
@@ -396,15 +396,15 @@ func TestWaitForInitialization(t *testing.T) {
err := processor.WaitForInitialization(req, initComplete)
if err == nil {
t.Error("Expected error when request context is cancelled")
t.Error("Expected error when request context is canceled")
}
if !strings.Contains(err.Error(), "request cancelled") {
t.Errorf("Expected 'request cancelled' error, got: %v", err)
if !strings.Contains(err.Error(), "request canceled") {
t.Errorf("Expected 'request canceled' error, got: %v", err)
}
if len(logger.DebugCalls) == 0 {
t.Error("Expected debug log when request is cancelled")
t.Error("Expected debug log when request is canceled")
}
})
+20 -12
View File
@@ -119,7 +119,7 @@ func newManager() *Manager {
// Initialize compression pools
m.gzipWriterPool = &sync.Pool{
New: func() interface{} {
w, _ := gzip.NewWriterLevel(nil, gzip.BestSpeed)
w, _ := gzip.NewWriterLevel(nil, gzip.BestSpeed) // Safe to ignore: factory function
return w
},
}
@@ -178,13 +178,17 @@ func (m *Manager) GetBuffer(sizeHint int) *bytes.Buffer {
switch {
case sizeHint <= 1024:
return m.smallBufferPool.Get().(*bytes.Buffer)
buf, _ := m.smallBufferPool.Get().(*bytes.Buffer) // Safe to ignore: pool return is best-effort
return buf
case sizeHint <= 4096:
return m.mediumBufferPool.Get().(*bytes.Buffer)
buf, _ := m.mediumBufferPool.Get().(*bytes.Buffer) // Safe to ignore: pool return is best-effort
return buf
case sizeHint <= 8192:
return m.largeBufferPool.Get().(*bytes.Buffer)
buf, _ := m.largeBufferPool.Get().(*bytes.Buffer) // Safe to ignore: pool return is best-effort
return buf
case sizeHint <= 16384:
return m.xlBufferPool.Get().(*bytes.Buffer)
buf, _ := m.xlBufferPool.Get().(*bytes.Buffer) // Safe to ignore: pool return is best-effort
return buf
default:
// For very large buffers, create new ones
return bytes.NewBuffer(make([]byte, 0, sizeHint))
@@ -225,7 +229,8 @@ func (m *Manager) PutBuffer(buf *bytes.Buffer) {
// GetGzipWriter returns a gzip writer from the pool
func (m *Manager) GetGzipWriter() *gzip.Writer {
atomic.AddUint64(&m.stats.GzipGets, 1)
return m.gzipWriterPool.Get().(*gzip.Writer)
w, _ := m.gzipWriterPool.Get().(*gzip.Writer) // Safe to ignore: pool return is best-effort
return w
}
// PutGzipWriter returns a gzip writer to the pool
@@ -245,7 +250,8 @@ func (m *Manager) GetGzipReader() *gzip.Reader {
if r == nil {
return nil
}
return r.(*gzip.Reader)
reader, _ := r.(*gzip.Reader) // Safe to ignore: pool return is best-effort
return reader
}
// PutGzipReader returns a gzip reader to the pool
@@ -254,14 +260,14 @@ func (m *Manager) PutGzipReader(r *gzip.Reader) {
return
}
atomic.AddUint64(&m.stats.GzipPuts, 1)
r.Reset(nil)
_ = r.Reset(nil) // Safe to ignore: resetting to nil reader for pool reuse
m.gzipReaderPool.Put(r)
}
// GetStringBuilder returns a string builder from the pool
func (m *Manager) GetStringBuilder() *strings.Builder {
atomic.AddUint64(&m.stats.StringGets, 1)
sb := m.stringBuilderPool.Get().(*strings.Builder)
sb, _ := m.stringBuilderPool.Get().(*strings.Builder) // Safe to ignore: pool return is best-effort
sb.Reset()
return sb
}
@@ -287,7 +293,8 @@ func (m *Manager) PutStringBuilder(sb *strings.Builder) {
// GetJWTBuffer returns JWT parsing buffers from the pool
func (m *Manager) GetJWTBuffer() *JWTBuffer {
atomic.AddUint64(&m.stats.JWTGets, 1)
return m.jwtBufferPool.Get().(*JWTBuffer)
buf, _ := m.jwtBufferPool.Get().(*JWTBuffer) // Safe to ignore: pool return is best-effort
return buf
}
// PutJWTBuffer returns JWT parsing buffers to the pool
@@ -314,7 +321,8 @@ func (m *Manager) PutJWTBuffer(buf *JWTBuffer) {
// GetHTTPResponseBuffer returns an HTTP response buffer from the pool
func (m *Manager) GetHTTPResponseBuffer() []byte {
atomic.AddUint64(&m.stats.HTTPGets, 1)
return *m.httpResponsePool.Get().(*[]byte)
buf, _ := m.httpResponsePool.Get().(*[]byte) // Safe to ignore: pool return is best-effort
return *buf
}
// PutHTTPResponseBuffer returns an HTTP response buffer to the pool
@@ -363,7 +371,7 @@ func (m *Manager) GetByteSlice(size int) []byte {
m.poolMu.Unlock()
}
b := pool.Get().(*[]byte)
b, _ := pool.Get().(*[]byte) // Safe to ignore: pool return is best-effort
return (*b)[:size]
}
+1 -1
View File
@@ -381,7 +381,7 @@ func NewTestSuite() *TestSuite {
func (ts *TestSuite) Setup() {
// Common test setup
ts.Logger.Clear()
ts.Session.Clear(nil, nil)
_ = ts.Session.Clear(nil, nil) // Safe to ignore: test helper function
ts.TokenCache.Clear()
ts.TokenVerifier.ShouldFail = false
ts.TokenVerifier.Error = nil