review fixes apr 2026 (#130)

* Multiple fixes

- refresh coordinator dedup + memory pressure wire
- middleware sse consolidation + timer leak + claim cache
- universal cache sync backfill + isDebug gate
- lazy background task race
- memory monitor stw cached + refresh() api

* fix(auth): suppress OIDC redirects on non-navigation requests

- [x] Add isNonNavigationRequest using Sec-Fetch-Mode and Accept headers
- [x] Add comprehensive TestIsNonNavigationRequest
- [x] Update ServeHTTP to 401 non-navigation and AJAX requests

Fixes #129

* feat(config): add custom CA and insecure skip verify for OIDC TLS

- [x] Add CACertPath, CACertPEM, InsecureSkipVerify to Config
- [x] Implement loadCACertPool for CA bundle loading
- [x] Update HTTPClientConfig with RootCAs and InsecureSkipVerify
- [x] Apply CA pool and skip verify to pooled HTTP clients
- [x] Enhance configKey to distinguish TLS configs
- [x] Add comprehensive ca_cert_test.go

Fixes #125

* feat(oidc): add custom CA certificate support for private OIDC providers

- [x] Add caCertPath, caCertPEM, insecureSkipVerify config options
- [x] Update traefik.yml with new OIDC client config fields
- [x] Add configuration schema descriptions for new options
- [x] Update README table and add Custom CA Certificates section

* Fix the documentation.

* test(redis): add oversized argument rejection test

- [x] Add TestRedisConn_RejectOversizedArgumentBytes
- [x] Import strings package

* Dependencies cleanup
This commit is contained in:
2026-04-19 10:12:00 +01:00
committed by GitHub
parent ccbb98b9dd
commit 2d1b04c637
72 changed files with 1464 additions and 5981 deletions
+53
View File
@@ -1216,6 +1216,18 @@ type SessionData struct {
dirty bool
inUse bool
// cachedClaimsToken is the ID token string whose claims were last parsed and
// cached. A lazy, per-request cache to avoid re-parsing the JWT on every
// authenticated request (e.g. for headerTemplates). Protected by sessionMutex.
cachedClaimsToken string
// cachedClaims holds the parsed claims for cachedClaimsToken.
cachedClaims map[string]interface{}
// cachedClaimsErr holds the parse error (if any) for cachedClaimsToken so
// failures are not retried within the same request.
cachedClaimsErr error
}
// IsDirty returns true if the session data has been modified since it was last loaded or saved.
@@ -1737,6 +1749,12 @@ func (sd *SessionData) Reset() {
sd.request = nil
sd.useCombinedStorage = true // Reset to use combined storage by default
// Drop any cached claims so pooled SessionData does not leak claim data
// between requests/users.
sd.cachedClaimsToken = ""
sd.cachedClaims = nil
sd.cachedClaimsErr = nil
// Reset the refresh mutex to ensure clean state
// Note: We don't need to lock it since sessionMutex is already held
// and this session is not in use by any request
@@ -2514,6 +2532,41 @@ func (sd *SessionData) GetIDToken() string {
return sd.getIDTokenUnsafe()
}
// GetIDTokenClaims returns claims parsed from the current ID token, caching
// the result on the SessionData so repeated callers within the same request
// do not re-parse the JWT. The cache is keyed on the ID token string and is
// cleared when the SessionData is reset (see Reset) or when the ID token
// changes (e.g. after a refresh).
//
// The parser parameter is typically the TraefikOidc.extractClaimsFunc, which
// lets tests inject mocks just like the direct call it replaces.
//
// Returns an empty claims map and a nil error when the session has no ID
// token, matching the existing "no-op" behavior of the caller sites.
func (sd *SessionData) GetIDTokenClaims(parser func(string) (map[string]interface{}, error)) (map[string]interface{}, error) {
sd.sessionMutex.Lock()
defer sd.sessionMutex.Unlock()
token := sd.getIDTokenUnsafe()
if token == "" {
// Invalidate any stale cache without running the parser.
sd.cachedClaimsToken = ""
sd.cachedClaims = nil
sd.cachedClaimsErr = nil
return nil, nil
}
if sd.cachedClaimsToken == token && (sd.cachedClaims != nil || sd.cachedClaimsErr != nil) {
return sd.cachedClaims, sd.cachedClaimsErr
}
claims, err := parser(token)
sd.cachedClaimsToken = token
sd.cachedClaims = claims
sd.cachedClaimsErr = err
return claims, err
}
// getIDTokenUnsafe retrieves the ID token without acquiring locks.
// Enhanced ID token retrieval with comprehensive integrity checks and chunking support.
// Used when the session mutex is already held to prevent deadlocks.