mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-18 04:47:28 +00:00
R64: cap metadata cache grace by configured limits
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestMetadataSetGraceCappedByMaxGrace verifies that MetadataCache.Set caps the
|
||||
// applied grace period by the configured MaxGracePeriod (and, for
|
||||
// security-critical metadata containing an operator-listed field, by
|
||||
// SecurityCriticalMaxGracePeriod). Previously only GracePeriod was applied and
|
||||
// the caps were configured but never read, so stale discovery metadata
|
||||
// (issuer, jwks_uri) could be served fresh beyond the intended bound.
|
||||
func TestMetadataSetGraceCappedByMaxGrace(t *testing.T) {
|
||||
t.Run("grace capped by MaxGracePeriod", func(t *testing.T) {
|
||||
base := New(DefaultConfig())
|
||||
defer base.Close()
|
||||
|
||||
mc := NewMetadataCache(base, MetadataConfig{
|
||||
GracePeriod: time.Hour,
|
||||
MaxGracePeriod: 5 * time.Minute,
|
||||
})
|
||||
|
||||
start := time.Now()
|
||||
baseTTL := time.Minute
|
||||
if err := mc.Set("https://issuer.example", &ProviderMetadata{Issuer: "https://issuer.example"}, baseTTL); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
item, ok := base.items["metadata:https://issuer.example"]
|
||||
if !ok {
|
||||
t.Fatalf("metadata not cached")
|
||||
}
|
||||
// Grace must be capped at 5m, not the full 1h.
|
||||
want := start.Add(baseTTL + 5*time.Minute)
|
||||
if item.ExpiresAt.After(want.Add(2 * time.Second)) {
|
||||
t.Fatalf("grace not capped by MaxGracePeriod: ExpiresAt=%v want ~%v", item.ExpiresAt, want)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("security-critical metadata uses tighter cap", func(t *testing.T) {
|
||||
base := New(DefaultConfig())
|
||||
defer base.Close()
|
||||
|
||||
mc := NewMetadataCache(base, MetadataConfig{
|
||||
GracePeriod: time.Hour,
|
||||
MaxGracePeriod: 5 * time.Minute,
|
||||
SecurityCriticalMaxGracePeriod: time.Minute,
|
||||
SecurityCriticalFields: []string{"issuer", "jwks_uri"},
|
||||
})
|
||||
|
||||
start := time.Now()
|
||||
baseTTL := time.Minute
|
||||
// Metadata carries the security-critical issuer field.
|
||||
if err := mc.Set("https://secure.example", &ProviderMetadata{Issuer: "https://secure.example", JWKSUri: "https://secure.example/jwks"}, baseTTL); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
item, ok := base.items["metadata:https://secure.example"]
|
||||
if !ok {
|
||||
t.Fatalf("metadata not cached")
|
||||
}
|
||||
// Grace must be capped at 1m (the security-critical cap), not 5m or 1h.
|
||||
want := start.Add(baseTTL + time.Minute)
|
||||
if item.ExpiresAt.After(want.Add(2 * time.Second)) {
|
||||
t.Fatalf("security-critical grace not capped by SecurityCriticalMaxGracePeriod: ExpiresAt=%v want ~%v", item.ExpiresAt, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user