@@ -10,6 +10,7 @@ import (
1010 "k8s.io/client-go/rest"
1111
1212 "github.com/jetstack/preflight/api"
13+ "github.com/stretchr/testify/require"
1314)
1415
1516func makeRESTClient (t * testing.T , ts * httptest.Server ) rest.Interface {
@@ -50,72 +51,133 @@ func TestFetch_Success(t *testing.T) {
5051 g := & DataGathererOIDC {cl : rc }
5152
5253 anyRes , count , err := g .Fetch ()
53- if err != nil {
54- t .Fatalf ("Fetch returned error: %v" , err )
55- }
56- if count != 1 {
57- t .Fatalf ("expected count 1, got %d" , count )
58- }
54+ require .NoError (t , err )
55+ require .Equal (t , 1 , count )
5956
6057 res , ok := anyRes .(* api.OIDCDiscoveryData )
61- if ! ok {
62- t .Fatalf ("unexpected result type: %T" , anyRes )
63- }
58+ require .True (t , ok , "unexpected result type" )
6459
65- if res .OIDCConfig == nil {
66- t .Fatalf ("expected OIDCConfig, got nil" )
67- }
68- if iss , _ := res .OIDCConfig ["issuer" ].(string ); iss != "https://example" {
69- t .Fatalf ("unexpected issuer: %v" , res .OIDCConfig ["issuer" ])
70- }
60+ require .NotNil (t , res .OIDCConfig )
61+ require .Equal (t , "https://example" , res .OIDCConfig ["issuer" ].(string ))
62+ require .Empty (t , res .OIDCConfigError )
7163
72- if res .JWKS == nil {
73- t .Fatalf ("expected JWKS, got nil" )
74- }
75- if _ , ok := res .JWKS ["keys" ].([]any ); ! ok {
76- t .Fatalf ("expected keys to be a slice, got %#v" , res .JWKS ["keys" ])
77- }
64+ require .NotNil (t , res .JWKS )
65+ _ , ok = res .JWKS ["keys" ].([]any )
66+ require .True (t , ok , "unexpected result type" )
67+ require .Empty (t , res .JWKSError )
7868}
7969
8070func TestFetch_Errors (t * testing.T ) {
81- ts := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
82- switch r .URL .Path {
83- case "/.well-known/openid-configuration" :
84- // return server error
85- http .Error (w , "boom" , http .StatusInternalServerError )
86- case "/openid/v1/jwks" :
87- // return invalid JSON
88- w .Header ().Set ("Content-Type" , "application/json" )
89- _ , _ = w .Write ([]byte (`}{` ))
90- default :
91- http .NotFound (w , r )
92- }
93- }))
94- defer ts .Close ()
95-
96- rc := makeRESTClient (t , ts )
97- g := & DataGathererOIDC {cl : rc }
98-
99- anyRes , _ , err := g .Fetch ()
100- if err != nil {
101- t .Fatalf ("Fetch returned error: %v" , err )
102- }
103-
104- res , ok := anyRes .(* api.OIDCDiscoveryData )
105- if ! ok {
106- t .Fatalf ("unexpected result type: %T" , anyRes )
107- }
108-
109- if res .OIDCConfig != nil {
110- t .Fatalf ("expected nil OIDCConfig on error, got %#v" , res .OIDCConfig )
111- }
112- if res .OIDCConfigError != "failed to get OIDC discovery document: an error on the server (\" boom\" ) has prevented the request from succeeding" {
113- t .Fatalf ("unexpected OIDCConfigError: %q" , res .OIDCConfigError )
114- }
115- if res .JWKS != nil {
116- t .Fatalf ("expected nil JWKS on malformed JSON, got %#v" , res .JWKS )
117- }
118- if res .JWKSError != "failed to unmarshal JWKS response: invalid character '}' looking for beginning of value" {
119- t .Fatalf ("unexpected JWKSError: %q" , res .JWKSError )
71+ tests := []struct {
72+ name string
73+ openidConfigurationResponse func (w http.ResponseWriter , r * http.Request )
74+ jwksResponse func (w http.ResponseWriter , r * http.Request )
75+ expOIDCConfigError string
76+ expJWKSError string
77+ }{
78+ {
79+ name : "5xx errors" ,
80+ openidConfigurationResponse : func (w http.ResponseWriter , r * http.Request ) {
81+ http .Error (w , "boom" , http .StatusInternalServerError )
82+ },
83+ jwksResponse : func (w http.ResponseWriter , r * http.Request ) {
84+ http .Error (w , "boom" , http .StatusInternalServerError )
85+ },
86+ expOIDCConfigError : `failed to get /.well-known/openid-configuration: Error from server (InternalError): an error on the server ("boom") has prevented the request from succeeding` ,
87+ expJWKSError : `failed to get /openid/v1/jwks: Error from server (InternalError): an error on the server ("boom") has prevented the request from succeeding` ,
88+ },
89+ {
90+ name : "malformed JSON" ,
91+ openidConfigurationResponse : func (w http.ResponseWriter , r * http.Request ) {
92+ w .Header ().Set ("Content-Type" , "application/json" )
93+ _ , _ = w .Write ([]byte (`}{` ))
94+ },
95+ jwksResponse : func (w http.ResponseWriter , r * http.Request ) {
96+ w .Header ().Set ("Content-Type" , "application/json" )
97+ _ , _ = w .Write ([]byte (`}0` ))
98+ },
99+ expOIDCConfigError : "failed to unmarshal OIDC discovery document: invalid character '}' looking for beginning of value" ,
100+ expJWKSError : "failed to unmarshal JWKS response: invalid character '}' looking for beginning of value" ,
101+ },
102+ {
103+ name : "permission error (no body)" ,
104+ openidConfigurationResponse : func (w http.ResponseWriter , r * http.Request ) {
105+ http .Error (w , "forbidden" , http .StatusForbidden )
106+ },
107+ jwksResponse : func (w http.ResponseWriter , r * http.Request ) {
108+ http .Error (w , "forbidden" , http .StatusForbidden )
109+ },
110+ expOIDCConfigError : "failed to get /.well-known/openid-configuration: Error from server (Forbidden): forbidden" ,
111+ expJWKSError : "failed to get /openid/v1/jwks: Error from server (Forbidden): forbidden" ,
112+ },
113+ {
114+ name : "permission error (*metav1.Status body)" ,
115+ openidConfigurationResponse : func (w http.ResponseWriter , r * http.Request ) {
116+ w .Header ().Set ("Content-Type" , "application/json" )
117+ w .WriteHeader (http .StatusForbidden )
118+ _ , _ = w .Write ([]byte (`{
119+ "kind":"Status",
120+ "apiVersion":"v1",
121+ "metadata":{},
122+ "status":"Failure",
123+ "message":"forbidden: User \"system:serviceaccount:default:test\" cannot get path \"/.well-known/openid-configuration\"",
124+ "reason":"Forbidden",
125+ "details":{},
126+ "code":403
127+ }` ))
128+ },
129+ jwksResponse : func (w http.ResponseWriter , r * http.Request ) {
130+ w .Header ().Set ("Content-Type" , "application/json" )
131+ w .WriteHeader (http .StatusForbidden )
132+ _ , _ = w .Write ([]byte (`{
133+ "kind":"Status",
134+ "apiVersion":"v1",
135+ "metadata":{},
136+ "status":"Failure",
137+ "message":"forbidden: User \"system:serviceaccount:default:test\" cannot get path \"/openid/v1/jwks\"",
138+ "reason":"Forbidden",
139+ "details":{},
140+ "code":403
141+ }` ))
142+ },
143+ expOIDCConfigError : `failed to get /.well-known/openid-configuration: Error from server (Forbidden): forbidden: User "system:serviceaccount:default:test" cannot get path "/.well-known/openid-configuration"` ,
144+ expJWKSError : `failed to get /openid/v1/jwks: Error from server (Forbidden): forbidden: User "system:serviceaccount:default:test" cannot get path "/openid/v1/jwks"` ,
145+ },
146+ }
147+
148+ for _ , tc := range tests {
149+ t .Run (tc .name , func (t * testing.T ) {
150+ ts := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
151+ switch r .URL .Path {
152+ case "/.well-known/openid-configuration" :
153+ tc .openidConfigurationResponse (w , r )
154+ return
155+ case "/openid/v1/jwks" :
156+ tc .jwksResponse (w , r )
157+ return
158+ default :
159+ t .Fatalf ("unexpected request path: %s" , r .URL .Path )
160+ }
161+ }))
162+ defer ts .Close ()
163+
164+ rc := makeRESTClient (t , ts )
165+ g := & DataGathererOIDC {cl : rc }
166+
167+ anyRes , count , err := g .Fetch ()
168+ require .NoError (t , err )
169+ require .Equal (t , 1 , count )
170+
171+ res , ok := anyRes .(* api.OIDCDiscoveryData )
172+ require .True (t , ok , "unexpected result type" )
173+
174+ require .Nil (t , res .OIDCConfig )
175+ require .NotEmpty (t , res .OIDCConfigError )
176+ require .Equal (t , tc .expOIDCConfigError , res .OIDCConfigError )
177+
178+ require .Nil (t , res .JWKS )
179+ require .NotEmpty (t , res .JWKSError )
180+ require .Equal (t , tc .expJWKSError , res .JWKSError )
181+ })
120182 }
121183}
0 commit comments