ContainerImage.Pinniped/internal/federationdomain/endpoints/jwks/jwks_handler_test.go

117 lines
3.2 KiB
Go
Raw Normal View History

// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package jwks
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/require"
"gopkg.in/square/go-jose.v2"
"go.pinniped.dev/internal/here"
)
func TestJWKSEndpoint(t *testing.T) {
testJWKSJSONString := here.Doc(`
{
"keys": [
{
"use": "sig",
"kty": "EC",
"kid": "pinniped-supervisor-key",
"crv": "P-256",
"alg": "ES256",
"x": "awmmj6CIMhSoJyfsqH7sekbTeY72GGPLEy16tPWVz2U",
"y": "FcMh06uXLaq9b2MOixlLVidUkycO1u7IHOkrTi7N0aw"
}
]
}
`)
tests := []struct {
name string
issuer string
provider DynamicJWKSProvider
method string
path string
wantStatus int
wantContentType string
wantBodyJSONString string
wantBodyString string
}{
{
name: "happy path",
issuer: "https://some-issuer.com/some/path",
provider: newDynamicJWKSProvider(t, "https://some-issuer.com/some/path", testJWKSJSONString),
method: http.MethodGet,
path: "/some/path",
wantStatus: http.StatusOK,
wantContentType: "application/json",
wantBodyJSONString: testJWKSJSONString,
},
{
name: "bad method",
issuer: "https://some-issuer.com",
provider: newDynamicJWKSProvider(t, "https://some-issuer.com", testJWKSJSONString),
method: http.MethodPost,
path: "/some/path",
wantStatus: http.StatusMethodNotAllowed,
wantContentType: "text/plain; charset=utf-8",
wantBodyString: "Method not allowed (try GET)\n",
},
{
name: "no JWKS found in provider's cache for this issuer",
issuer: "https://some-issuer.com",
provider: newDynamicJWKSProvider(t, "https://some-other-unrelated-issuer.com", testJWKSJSONString),
method: http.MethodGet,
path: "/some/path",
wantStatus: http.StatusNotFound,
wantContentType: "text/plain; charset=utf-8",
wantBodyString: "JWKS not found for requested issuer\n",
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
handler := NewHandler(test.issuer, test.provider)
req := httptest.NewRequest(test.method, test.path, nil)
rsp := httptest.NewRecorder()
handler.ServeHTTP(rsp, req)
require.Equal(t, test.wantStatus, rsp.Code)
require.Equal(t, test.wantContentType, rsp.Header().Get("Content-Type"))
if test.wantBodyJSONString != "" {
require.JSONEq(t, test.wantBodyJSONString, rsp.Body.String())
}
if test.wantBodyString != "" {
require.Equal(t, test.wantBodyString, rsp.Body.String())
}
})
}
}
func newDynamicJWKSProvider(t *testing.T, issuer string, jwksJSON string) DynamicJWKSProvider {
t.Helper()
jwksProvider := NewDynamicJWKSProvider()
var keySet jose.JSONWebKeySet
err := json.Unmarshal([]byte(jwksJSON), &keySet)
require.NoError(t, err)
issuerToJWKSMap := map[string]*jose.JSONWebKeySet{
issuer: &keySet,
}
issuerToActiveJWKMap := map[string]*jose.JSONWebKey{
issuer: &keySet.Keys[0],
}
jwksProvider.SetIssuerToJWKSMap(issuerToJWKSMap, issuerToActiveJWKMap)
return jwksProvider
}