...
1 package keyfunc_test
2
3 import (
4 "errors"
5 "github.com/golang-jwt/jwt/v5"
6 "net/http"
7 "net/http/httptest"
8 "sync"
9 "testing"
10
11 "github.com/MicahParks/keyfunc/v2"
12 )
13
14 func TestResponseExtractorStatusOK(t *testing.T) {
15 var mux sync.Mutex
16 statusCode := http.StatusOK
17
18 server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
19 mux.Lock()
20 writer.WriteHeader(statusCode)
21 mux.Unlock()
22 _, _ = writer.Write([]byte(jwksJSON))
23 }))
24 defer server.Close()
25
26 options := keyfunc.Options{
27 ResponseExtractor: keyfunc.ResponseExtractorStatusOK,
28 }
29 jwks, err := keyfunc.Get(server.URL, options)
30 if err != nil {
31 t.Fatalf("Failed to get JWK Set from server.\nError: %s", err)
32 }
33
34 if len(jwks.ReadOnlyKeys()) == 0 {
35 t.Fatalf("Expected JWK Set to have keys.")
36 }
37
38 mux.Lock()
39 statusCode = http.StatusInternalServerError
40 mux.Unlock()
41
42 _, err = keyfunc.Get(server.URL, options)
43 if !errors.Is(err, keyfunc.ErrInvalidHTTPStatusCode) {
44 t.Fatalf("Expected error to be ErrInvalidHTTPStatusCode.\nError: %s", err)
45 }
46 }
47
48 func TestResponseExtractorStatusAny(t *testing.T) {
49 var mux sync.Mutex
50 statusCode := http.StatusOK
51
52 server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
53 mux.Lock()
54 writer.WriteHeader(statusCode)
55 mux.Unlock()
56 _, _ = writer.Write([]byte(jwksJSON))
57 }))
58 defer server.Close()
59
60 options := keyfunc.Options{
61 ResponseExtractor: keyfunc.ResponseExtractorStatusAny,
62 }
63 jwks, err := keyfunc.Get(server.URL, options)
64 if err != nil {
65 t.Fatalf("Failed to get JWK Set from server.\nError: %s", err)
66 }
67
68 if len(jwks.ReadOnlyKeys()) == 0 {
69 t.Fatalf("Expected JWK Set to have keys.")
70 }
71
72 mux.Lock()
73 statusCode = http.StatusInternalServerError
74 mux.Unlock()
75
76 _, err = keyfunc.Get(server.URL, options)
77 if err != nil {
78 t.Fatalf("Expected error no error for 500 status code.\nError: %s", err)
79 }
80 }
81
82 func TestTolerateStartupFailure(t *testing.T) {
83 var mux sync.Mutex
84 shouldError := true
85
86 server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
87 mux.Lock()
88 defer mux.Unlock()
89 if shouldError {
90 writer.WriteHeader(http.StatusInternalServerError)
91 } else {
92 writer.WriteHeader(http.StatusOK)
93 _, _ = writer.Write([]byte(jwksJSON))
94 }
95 }))
96 defer server.Close()
97
98 options := keyfunc.Options{
99 TolerateInitialJWKHTTPError: true,
100 RefreshUnknownKID: true,
101 }
102 jwks, err := keyfunc.Get(server.URL, options)
103 if err != nil {
104 t.Fatalf("TolerateInitialJWKHTTPError should not return error on bad HTTP startup.\nError: %s", err)
105 }
106
107 if len(jwks.ReadOnlyKeys()) != 0 {
108 t.Fatalf("Expected JWK Set to have no keys.")
109 }
110
111 const token = "eyJhbGciOiJFUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJDR3QwWldTNExjNWZhaUtTZGkwdFUwZmpDQWR2R1JPUVJHVTlpUjd0VjBBIn0.eyJleHAiOjE2MTU0MDY4NjEsImlhdCI6MTYxNTQwNjgwMSwianRpIjoiYWVmOWQ5YjItN2EyYy00ZmQ4LTk4MzktODRiMzQ0Y2VmYzZhIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL21hc3RlciIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiJhZDEyOGRmMS0xMTQwLTRlNGMtYjA5Ny1hY2RjZTcwNWJkOWIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJ0b2tlbmRlbG1lIiwiYWNyIjoiMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiY2xpZW50SG9zdCI6IjE3Mi4yMC4wLjEiLCJjbGllbnRJZCI6InRva2VuZGVsbWUiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6InNlcnZpY2UtYWNjb3VudC10b2tlbmRlbG1lIiwiY2xpZW50QWRkcmVzcyI6IjE3Mi4yMC4wLjEifQ.iQ77QGoPDNjR2oWLu3zT851mswP8J-h_nrGhs3fpa_tFB3FT1deKPGkjef9JOTYFI-CIVxdCFtW3KODOaw9Nrw"
112 _, err = jwt.Parse(token, jwks.Keyfunc)
113 if !errors.Is(err, keyfunc.ErrKIDNotFound) {
114 t.Fatalf("Expected error to be ErrKIDNotFound.\nError: %s", err)
115 }
116
117 mux.Lock()
118 shouldError = false
119 mux.Unlock()
120
121 _, err = jwt.Parse(token, jwks.Keyfunc)
122 if !errors.Is(err, jwt.ErrTokenExpired) {
123 t.Fatalf("Expected error to be jwt.ErrTokenExpired.\nError: %s", err)
124 }
125
126 if len(jwks.ReadOnlyKeys()) == 0 {
127 t.Fatalf("Expected JWK Set to have keys.")
128 }
129 }
130
View as plain text