@@ -34,7 +34,8 @@ import (
3434
3535func Test_AddsDefaultFunctionForCustomConfigFiles (t * testing.T ) {
3636 t .Run ("should load default config files (without given command line)" , func (t * testing.T ) {
37- engine := CreateAppEngine ()
37+ localConfig := configuration .NewWithOpts ()
38+ engine := CreateAppEngineWithOptions (WithConfiguration (localConfig ))
3839 conf := engine .GetConfiguration ()
3940
4041 actual := conf .GetStringSlice (configuration .CUSTOM_CONFIG_FILES )
@@ -50,7 +51,8 @@ func Test_AddsDefaultFunctionForCustomConfigFiles(t *testing.T) {
5051 })
5152
5253 t .Run ("should load default config files (with given command line)" , func (t * testing.T ) {
53- engine := CreateAppEngine ()
54+ localConfig := configuration .NewWithOpts ()
55+ engine := CreateAppEngineWithOptions (WithConfiguration (localConfig ))
5456 conf := engine .GetConfiguration ()
5557 conf .Set ("configfile" , "abc/d" )
5658
@@ -98,12 +100,143 @@ func Test_CreateAppEngine_config_replaceV1inApi(t *testing.T) {
98100 assert .Equal (t , expectApiUrl , actualApiUrl )
99101}
100102
103+ func Test_EnsureAuthConfigurationPrecedence (t * testing.T ) {
104+ tests := []struct {
105+ name string
106+ patPayload string
107+ oauthJWTPayload string
108+ userDefinedApiUrl interface {}
109+ expectedURL string
110+ }{
111+ {
112+ name : "no user-specified input, should default to the hard-coded default URL" ,
113+ patPayload : "" ,
114+ oauthJWTPayload : "" ,
115+ userDefinedApiUrl : "" ,
116+ expectedURL : constants .SNYK_DEFAULT_API_URL ,
117+ },
118+ {
119+ name : "broken user-defined API URL is defined, should default to the hard-coded default URL" ,
120+ patPayload : "" ,
121+ oauthJWTPayload : "" ,
122+ userDefinedApiUrl : 123 ,
123+ expectedURL : constants .SNYK_DEFAULT_API_URL ,
124+ },
125+ {
126+ name : "only user-defined API URL is defined, use that" ,
127+ patPayload : "" ,
128+ oauthJWTPayload : "" ,
129+ userDefinedApiUrl : "https://api.user" ,
130+ expectedURL : "https://api.user" ,
131+ },
132+ {
133+ name : "with a broken PAT configured and a user-defined API URL, user-defined API URL should take precedence" ,
134+ patPayload : `{broken` ,
135+ oauthJWTPayload : "" ,
136+ userDefinedApiUrl : "https://api.user" ,
137+ expectedURL : "https://api.user" ,
138+ },
139+ {
140+ name : "with an empty PAT configured and a user-defined API URL, user-defined API URL should take precedence" ,
141+ patPayload : `{}` ,
142+ oauthJWTPayload : "" ,
143+ userDefinedApiUrl : "https://api.user" ,
144+ expectedURL : "https://api.user" ,
145+ },
146+ {
147+ name : "with a PAT configured and a user-defined API URL, PAT host should take precedence" ,
148+ patPayload : `{"h":"api.pat"}` ,
149+ oauthJWTPayload : "" ,
150+ userDefinedApiUrl : "https://api.user" ,
151+ expectedURL : "https://api.pat" ,
152+ },
153+ {
154+ name : "with a broken OAuth with no host configured and a user-defined API URL, user-defined API URL should take precedence" ,
155+ patPayload : "" ,
156+ oauthJWTPayload : `{broken` ,
157+ userDefinedApiUrl : "https://api.user" ,
158+ expectedURL : "https://api.user" ,
159+ },
160+ {
161+ name : "with OAuth with no host configured and a user-defined API URL, user-defined API URL should take precedence" ,
162+ patPayload : "" ,
163+ oauthJWTPayload : `{"sub":"1234567890","name":"John Doe","iat":1516239022,"aud":[]}` ,
164+ userDefinedApiUrl : "https://api.user" ,
165+ expectedURL : "https://api.user" ,
166+ },
167+ {
168+ name : "with OAuth configured and a user-defined API URL, OAuth audience should take precedence" ,
169+ patPayload : "" ,
170+ oauthJWTPayload : `{"sub":"1234567890","name":"John Doe","iat":1516239022,"aud":["https://api.oauth"]}` ,
171+ userDefinedApiUrl : "https://api.user" ,
172+ expectedURL : "https://api.oauth" ,
173+ },
174+ {
175+ name : "with only PAT configured, use PAT host" ,
176+ patPayload : `{"h":"api.pat"}` ,
177+ oauthJWTPayload : "" ,
178+ userDefinedApiUrl : "" ,
179+ expectedURL : "https://api.pat" ,
180+ },
181+ {
182+ name : "with only OAuth configured, use OAuth audience" ,
183+ patPayload : "" ,
184+ oauthJWTPayload : `{"sub":"1234567890","name":"John Doe","iat":1516239022,"aud":["https://api.oauth"]}` ,
185+ userDefinedApiUrl : "" ,
186+ expectedURL : "https://api.oauth" ,
187+ },
188+ // This is not a likely scenario, as you cannot define both at the same time. However, it will potentially
189+ // catch regressions if this test starts to fail.
190+ {
191+ name : "with PAT, OAuth and user-defined API URL, PAT should take precedence over OAuth" ,
192+ patPayload : `{"h":"api.pat"}` ,
193+ oauthJWTPayload : `{"sub":"1234567890","name":"John Doe","iat":1516239022,"aud":["https://api.oauth"]}` ,
194+ userDefinedApiUrl : "https://api.user" ,
195+ expectedURL : "https://api.pat" ,
196+ },
197+ }
198+
199+ for _ , tt := range tests {
200+ t .Run (tt .name , func (t * testing.T ) {
201+ config := configuration .NewWithOpts ()
202+ engine := CreateAppEngineWithOptions (WithConfiguration (config ))
203+ assert .NotNil (t , engine )
204+
205+ if tt .userDefinedApiUrl != "" {
206+ config .Set (configuration .API_URL , tt .userDefinedApiUrl )
207+ }
208+
209+ if tt .patPayload != "" {
210+ pat := createMockPAT (t , tt .patPayload )
211+ config .Set (configuration .AUTHENTICATION_TOKEN , pat )
212+ }
213+
214+ if tt .oauthJWTPayload != "" {
215+ jwtHeader := `{"alg":"HS256","typ":"JWT"}`
216+ encodedHeader := base64 .RawURLEncoding .EncodeToString ([]byte (jwtHeader ))
217+ encodedPayload := base64 .RawURLEncoding .EncodeToString ([]byte (tt .oauthJWTPayload ))
218+ signature := "hWq0fKukObQSkphAdyEC7-m4jXIb4VdWyQySmmgy0GU"
219+
220+ jwtToken := fmt .Sprintf ("%s.%s.%s" , encodedHeader , encodedPayload , signature )
221+ oauthTokenJSON := fmt .Sprintf (`{"access_token": "%s"}` , jwtToken )
222+
223+ config .Set (auth .CONFIG_KEY_OAUTH_TOKEN , oauthTokenJSON )
224+ }
225+
226+ actualApiUrl := config .GetString (configuration .API_URL )
227+ assert .Equal (t , tt .expectedURL , actualApiUrl )
228+ })
229+ }
230+ }
231+
101232func Test_CreateAppEngine_config_PAT_autoRegionDetection (t * testing.T ) {
102233 t .Run ("default" , func (t * testing.T ) {
103234 apiUrl := "api.snyk.io"
104235 euPAT := createMockPAT (t , fmt .Sprintf (`{"h":"%s"}` , apiUrl ))
105- engine := CreateAppEngine ()
106- config := engine .GetConfiguration ()
236+ config := configuration .NewWithOpts ()
237+ engine := CreateAppEngineWithOptions (WithConfiguration (config ))
238+ assert .NotNil (t , engine )
239+
107240 config .Set (configuration .AUTHENTICATION_TOKEN , euPAT )
108241
109242 actualApiUrl := config .GetString (configuration .API_URL )
@@ -113,8 +246,10 @@ func Test_CreateAppEngine_config_PAT_autoRegionDetection(t *testing.T) {
113246 t .Run ("eu" , func (t * testing.T ) {
114247 apiUrl := "api.eu.snyk.io"
115248 euPAT := createMockPAT (t , fmt .Sprintf (`{"h":"%s"}` , apiUrl ))
116- engine := CreateAppEngine ()
117- config := engine .GetConfiguration ()
249+ config := configuration .NewWithOpts ()
250+ engine := CreateAppEngineWithOptions (WithConfiguration (config ))
251+ assert .NotNil (t , engine )
252+
118253 config .Set (configuration .AUTHENTICATION_TOKEN , euPAT )
119254
120255 actualApiUrl := config .GetString (configuration .API_URL )
@@ -123,8 +258,10 @@ func Test_CreateAppEngine_config_PAT_autoRegionDetection(t *testing.T) {
123258
124259 t .Run ("invalid PAT reverts to default API URL (with wrong payload)" , func (t * testing.T ) {
125260 patWithExtraSegments := "snyk_uat.12345678.payload.signature.extra"
126- engine := CreateAppEngine ()
127- config := engine .GetConfiguration ()
261+ config := configuration .NewWithOpts ()
262+ engine := CreateAppEngineWithOptions (WithConfiguration (config ))
263+ assert .NotNil (t , engine )
264+
128265 config .Set (configuration .AUTHENTICATION_TOKEN , patWithExtraSegments )
129266
130267 actualApiUrl := config .GetString (configuration .API_URL )
@@ -133,8 +270,10 @@ func Test_CreateAppEngine_config_PAT_autoRegionDetection(t *testing.T) {
133270
134271 t .Run ("invalid PAT reverts to default API URL (with no hostname in claim)" , func (t * testing.T ) {
135272 pat := createMockPAT (t , `{}` )
136- engine := CreateAppEngine ()
137- config := engine .GetConfiguration ()
273+ config := configuration .NewWithOpts ()
274+ engine := CreateAppEngineWithOptions (WithConfiguration (config ))
275+ assert .NotNil (t , engine )
276+
138277 config .Set (configuration .AUTHENTICATION_TOKEN , pat )
139278
140279 actualApiUrl := config .GetString (configuration .API_URL )
@@ -609,7 +748,10 @@ func TestDefaultInputDirectory(t *testing.T) {
609748
610749func Test_auth_oauth (t * testing.T ) {
611750 mockCtl := gomock .NewController (t )
612- engine := CreateAppEngine ()
751+ config := configuration .NewWithOpts ()
752+ engine := CreateAppEngineWithOptions (WithConfiguration (config ))
753+ assert .NotNil (t , engine )
754+
613755 logger := engine .GetLogger ()
614756 analytics := analytics .New ()
615757
0 commit comments