Deflake supported key ack

This commit is contained in:
Jordan Liggitt 2024-11-07 14:14:39 -05:00
parent dc41c91a07
commit c68a11a09f
No known key found for this signature in database
2 changed files with 33 additions and 18 deletions

View File

@ -28,7 +28,6 @@ import (
"net" "net"
"os" "os"
"sync" "sync"
"sync/atomic"
"testing" "testing"
"time" "time"
@ -48,10 +47,12 @@ type MockSigner struct {
SigningKeyID string SigningKeyID string
SigningAlg string SigningAlg string
TokenType string TokenType string
SupportedKeys atomic.Pointer[map[string]KeyT]
AckKeyFetch chan bool
MaxTokenExpirationSeconds int64 MaxTokenExpirationSeconds int64
supportedKeys map[string]KeyT
supportedKeysLock sync.RWMutex
supportedKeysFetched *sync.Cond
FetchError error FetchError error
MetadataError error MetadataError error
errorLock sync.RWMutex errorLock sync.RWMutex
@ -70,9 +71,9 @@ func NewMockSigner(t *testing.T, socketPath string) *MockSigner {
m := &MockSigner{ m := &MockSigner{
socketPath: socketPath, socketPath: socketPath,
server: server, server: server,
AckKeyFetch: make(chan bool),
MaxTokenExpirationSeconds: 10 * 60, // 10m MaxTokenExpirationSeconds: 10 * 60, // 10m
} }
m.supportedKeysFetched = sync.NewCond(&m.supportedKeysLock)
if err := m.Reset(); err != nil { if err := m.Reset(); err != nil {
t.Fatalf("failed to load keys for mock signer: %v", err) t.Fatalf("failed to load keys for mock signer: %v", err)
@ -91,6 +92,22 @@ func NewMockSigner(t *testing.T, socketPath string) *MockSigner {
return m return m
} }
func (m *MockSigner) GetSupportedKeys() map[string]KeyT {
m.supportedKeysLock.RLock()
defer m.supportedKeysLock.RUnlock()
return m.supportedKeys
}
func (m *MockSigner) SetSupportedKeys(keys map[string]KeyT) {
m.supportedKeysLock.Lock()
defer m.supportedKeysLock.Unlock()
m.supportedKeys = keys
}
func (m *MockSigner) WaitForSupportedKeysFetch() {
m.supportedKeysLock.Lock()
defer m.supportedKeysLock.Unlock()
m.supportedKeysFetched.Wait()
}
func (m *MockSigner) Sign(ctx context.Context, req *v1alpha1.SignJWTRequest) (*v1alpha1.SignJWTResponse, error) { func (m *MockSigner) Sign(ctx context.Context, req *v1alpha1.SignJWTRequest) (*v1alpha1.SignJWTResponse, error) {
header := &struct { header := &struct {
@ -132,18 +149,16 @@ func (m *MockSigner) FetchKeys(ctx context.Context, req *v1alpha1.FetchKeysReque
keys := []*v1alpha1.Key{} keys := []*v1alpha1.Key{}
for id, k := range *m.SupportedKeys.Load() { m.supportedKeysLock.RLock()
for id, k := range m.supportedKeys {
keys = append(keys, &v1alpha1.Key{ keys = append(keys, &v1alpha1.Key{
KeyId: id, KeyId: id,
Key: k.Key, Key: k.Key,
ExcludeFromOidcDiscovery: k.ExcludeFromOidcDiscovery, ExcludeFromOidcDiscovery: k.ExcludeFromOidcDiscovery,
}) })
} }
m.supportedKeysFetched.Broadcast()
select { m.supportedKeysLock.RUnlock()
case <-m.AckKeyFetch:
default:
}
return &v1alpha1.FetchKeysResponse{ return &v1alpha1.FetchKeysResponse{
RefreshHintSeconds: 5, RefreshHintSeconds: 5,
@ -185,7 +200,7 @@ func (m *MockSigner) Reset() error {
m.SigningKeyID = "kid-1" m.SigningKeyID = "kid-1"
m.SigningAlg = "RS256" m.SigningAlg = "RS256"
m.TokenType = "JWT" m.TokenType = "JWT"
m.SupportedKeys.Store(&map[string]KeyT{ m.SetSupportedKeys(map[string]KeyT{
"kid-1": {Key: pub1}, "kid-1": {Key: pub1},
"kid-2": {Key: pub2}, "kid-2": {Key: pub2},
"kid-3": {Key: pub3}, "kid-3": {Key: pub3},

View File

@ -121,14 +121,14 @@ func TestExternalJWTSigningAndAuth(t *testing.T) {
mockSigner.SigningKeyID = "updated-kid-1" mockSigner.SigningKeyID = "updated-kid-1"
cpy := make(map[string]v1alpha1testing.KeyT) cpy := make(map[string]v1alpha1testing.KeyT)
for key, value := range *mockSigner.SupportedKeys.Load() { for key, value := range mockSigner.GetSupportedKeys() {
cpy[key] = value cpy[key] = value
} }
cpy["updated-kid-1"] = v1alpha1testing.KeyT{ cpy["updated-kid-1"] = v1alpha1testing.KeyT{
Key: pubKey1Bytes, Key: pubKey1Bytes,
ExcludeFromOidcDiscovery: true, ExcludeFromOidcDiscovery: true,
} }
mockSigner.SupportedKeys.Store(&cpy) mockSigner.SetSupportedKeys(cpy)
}, },
preValidationSignerUpdate: func() { /*no-op*/ }, preValidationSignerUpdate: func() { /*no-op*/ },
wantTokenReqErr: fmt.Errorf("failed to generate token: while validating header: key used for signing JWT (kid: updated-kid-1) is excluded from OIDC discovery docs"), wantTokenReqErr: fmt.Errorf("failed to generate token: while validating header: key used for signing JWT (kid: updated-kid-1) is excluded from OIDC discovery docs"),
@ -163,7 +163,7 @@ func TestExternalJWTSigningAndAuth(t *testing.T) {
mockSigner.SigningKey = key1 mockSigner.SigningKey = key1
}, },
preValidationSignerUpdate: func() { preValidationSignerUpdate: func() {
mockSigner.SupportedKeys.Store(&map[string]v1alpha1testing.KeyT{}) mockSigner.SetSupportedKeys(map[string]v1alpha1testing.KeyT{})
}, },
shouldPassAuth: false, shouldPassAuth: false,
}, },
@ -174,12 +174,12 @@ func TestExternalJWTSigningAndAuth(t *testing.T) {
}, },
preValidationSignerUpdate: func() { preValidationSignerUpdate: func() {
cpy := make(map[string]v1alpha1testing.KeyT) cpy := make(map[string]v1alpha1testing.KeyT)
for key, value := range *mockSigner.SupportedKeys.Load() { for key, value := range mockSigner.GetSupportedKeys() {
cpy[key] = value cpy[key] = value
} }
cpy["kid-1"] = v1alpha1testing.KeyT{Key: pubKey1Bytes} cpy["kid-1"] = v1alpha1testing.KeyT{Key: pubKey1Bytes}
mockSigner.SupportedKeys.Store(&cpy) mockSigner.SetSupportedKeys(cpy)
mockSigner.AckKeyFetch <- true mockSigner.WaitForSupportedKeysFetch()
}, },
shouldPassAuth: true, shouldPassAuth: true,
}, },
@ -192,7 +192,7 @@ func TestExternalJWTSigningAndAuth(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("failed to reset signer for the test %q: %v", tc.desc, err) t.Fatalf("failed to reset signer for the test %q: %v", tc.desc, err)
} }
mockSigner.AckKeyFetch <- true mockSigner.WaitForSupportedKeysFetch()
// Adjust parameters on mock signer for the test. // Adjust parameters on mock signer for the test.
tc.preTestSignerUpdate() tc.preTestSignerUpdate()