1 package autorest
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import (
18 "fmt"
19 "net/http"
20 "reflect"
21 "strings"
22 "testing"
23
24 "github.com/Azure/go-autorest/autorest/adal"
25 "github.com/Azure/go-autorest/autorest/mocks"
26 )
27
28 const (
29 TestTenantID = "TestTenantID"
30 TestAuxTenent1 = "aux1"
31 TestAuxTenent2 = "aux2"
32 TestAuxTenent3 = "aux3"
33 TestActiveDirectoryEndpoint = "https://login/test.com/"
34 )
35
36 func TestWithAuthorizer(t *testing.T) {
37 r1 := mocks.NewRequest()
38
39 na := &NullAuthorizer{}
40 r2, err := Prepare(r1,
41 na.WithAuthorization())
42 if err != nil {
43 t.Fatalf("autorest: NullAuthorizer#WithAuthorization returned an unexpected error (%v)", err)
44 } else if !reflect.DeepEqual(r1, r2) {
45 t.Fatalf("autorest: NullAuthorizer#WithAuthorization modified the request -- received %v, expected %v", r2, r1)
46 }
47 }
48
49 func TestTokenWithAuthorization(t *testing.T) {
50 token := &adal.Token{
51 AccessToken: "TestToken",
52 Resource: "https://azure.microsoft.com/",
53 Type: "Bearer",
54 }
55
56 ba := NewBearerAuthorizer(token)
57 req, err := Prepare(&http.Request{}, ba.WithAuthorization())
58 if err != nil {
59 t.Fatalf("azure: BearerAuthorizer#WithAuthorization returned an error (%v)", err)
60 } else if req.Header.Get(http.CanonicalHeaderKey("Authorization")) != fmt.Sprintf("Bearer %s", token.AccessToken) {
61 t.Fatal("azure: BearerAuthorizer#WithAuthorization failed to set Authorization header")
62 }
63 }
64
65 func TestServicePrincipalTokenWithAuthorizationNoRefresh(t *testing.T) {
66 oauthConfig, err := adal.NewOAuthConfig(TestActiveDirectoryEndpoint, TestTenantID)
67 if err != nil {
68 t.Fatalf("azure: BearerAuthorizer#WithAuthorization returned an error (%v)", err)
69 }
70 spt, err := adal.NewServicePrincipalToken(*oauthConfig, "id", "secret", "resource", nil)
71 if err != nil {
72 t.Fatalf("azure: BearerAuthorizer#WithAuthorization returned an error (%v)", err)
73 }
74 spt.SetAutoRefresh(false)
75 s := mocks.NewSender()
76 spt.SetSender(s)
77
78 ba := NewBearerAuthorizer(spt)
79 req, err := Prepare(mocks.NewRequest(), ba.WithAuthorization())
80 if err != nil {
81 t.Fatalf("azure: BearerAuthorizer#WithAuthorization returned an error (%v)", err)
82 } else if req.Header.Get(http.CanonicalHeaderKey("Authorization")) != fmt.Sprintf("Bearer %s", spt.OAuthToken()) {
83 t.Fatal("azure: BearerAuthorizer#WithAuthorization failed to set Authorization header")
84 }
85 }
86
87 func TestServicePrincipalTokenWithAuthorizationRefresh(t *testing.T) {
88
89 oauthConfig, err := adal.NewOAuthConfig(TestActiveDirectoryEndpoint, TestTenantID)
90 if err != nil {
91 t.Fatalf("azure: BearerAuthorizer#WithAuthorization returned an error (%v)", err)
92 }
93 refreshed := false
94 spt, err := adal.NewServicePrincipalToken(*oauthConfig, "id", "secret", "resource", func(t adal.Token) error {
95 refreshed = true
96 return nil
97 })
98 if err != nil {
99 t.Fatalf("azure: BearerAuthorizer#WithAuthorization returned an error (%v)", err)
100 }
101
102 jwt := `{
103 "access_token" : "accessToken",
104 "expires_in" : "3600",
105 "expires_on" : "12345",
106 "not_before" : "67890",
107 "resource" : "test",
108 "token_type" : "Bearer"
109 }`
110 body := mocks.NewBody(jwt)
111 resp := mocks.NewResponseWithBodyAndStatus(body, http.StatusOK, "OK")
112 c := mocks.NewSender()
113 s := DecorateSender(c,
114 (func() SendDecorator {
115 return func(s Sender) Sender {
116 return SenderFunc(func(r *http.Request) (*http.Response, error) {
117 return resp, nil
118 })
119 }
120 })())
121 spt.SetSender(s)
122
123 ba := NewBearerAuthorizer(spt)
124 req, err := Prepare(mocks.NewRequest(), ba.WithAuthorization())
125 if err != nil {
126 t.Fatalf("azure: BearerAuthorizer#WithAuthorization returned an error (%v)", err)
127 } else if req.Header.Get(http.CanonicalHeaderKey("Authorization")) != fmt.Sprintf("Bearer %s", spt.OAuthToken()) {
128 t.Fatal("azure: BearerAuthorizer#WithAuthorization failed to set Authorization header")
129 }
130
131 if !refreshed {
132 t.Fatal("azure: BearerAuthorizer#WithAuthorization must refresh the token")
133 }
134 }
135
136 func TestServicePrincipalTokenWithAuthorizationReturnsErrorIfConnotRefresh(t *testing.T) {
137 oauthConfig, err := adal.NewOAuthConfig(TestActiveDirectoryEndpoint, TestTenantID)
138 if err != nil {
139 t.Fatalf("azure: BearerAuthorizer#WithAuthorization returned an error (%v)", err)
140 }
141 spt, err := adal.NewServicePrincipalToken(*oauthConfig, "id", "secret", "resource", nil)
142 if err != nil {
143 t.Fatalf("azure: BearerAuthorizer#WithAuthorization returned an error (%v)", err)
144 }
145
146 s := mocks.NewSender()
147 s.AppendResponse(mocks.NewResponseWithStatus("400 Bad Request", http.StatusBadRequest))
148 spt.SetSender(s)
149
150 ba := NewBearerAuthorizer(spt)
151 _, err = Prepare(mocks.NewRequest(), ba.WithAuthorization())
152 if err == nil {
153 t.Fatal("azure: BearerAuthorizer#WithAuthorization failed to return an error when refresh fails")
154 }
155 }
156
157 func TestBearerAuthorizerCallback(t *testing.T) {
158 tenantString := "123-tenantID-456"
159 resourceString := "https://fake.resource.net"
160
161 s := mocks.NewSender()
162 resp := mocks.NewResponseWithStatus("401 Unauthorized", http.StatusUnauthorized)
163 mocks.SetResponseHeader(resp, bearerChallengeHeader, bearer+" \"authorization\"=\"https://fake.net/"+tenantString+"\",\"resource\"=\""+resourceString+"\"")
164 s.AppendResponse(resp)
165
166 auth := NewBearerAuthorizerCallback(s, func(tenantID, resource string) (*BearerAuthorizer, error) {
167 if tenantID != tenantString {
168 t.Fatal("BearerAuthorizerCallback: bad tenant ID")
169 }
170 if resource != resourceString {
171 t.Fatal("BearerAuthorizerCallback: bad resource")
172 }
173
174 oauthConfig, err := adal.NewOAuthConfig(TestActiveDirectoryEndpoint, tenantID)
175 if err != nil {
176 t.Fatalf("azure: NewOAuthConfig returned an error (%v)", err)
177 }
178
179 spt, err := adal.NewServicePrincipalToken(*oauthConfig, "id", "secret", resource)
180 if err != nil {
181 t.Fatalf("azure: NewServicePrincipalToken returned an error (%v)", err)
182 }
183
184 spt.SetSender(s)
185 return NewBearerAuthorizer(spt), nil
186 })
187
188 _, err := Prepare(mocks.NewRequest(), auth.WithAuthorization())
189 if err == nil {
190 t.Fatal("azure: BearerAuthorizerCallback#WithAuthorization failed to return an error when refresh fails")
191 }
192 }
193
194 func TestApiKeyAuthorization(t *testing.T) {
195
196 headers := make(map[string]interface{})
197 queryParameters := make(map[string]interface{})
198
199 dummyAuthHeader := "dummyAuthHeader"
200 dummyAuthHeaderValue := "dummyAuthHeaderValue"
201
202 dummyAuthQueryParameter := "dummyAuthQueryParameter"
203 dummyAuthQueryParameterValue := "dummyAuthQueryParameterValue"
204
205 headers[dummyAuthHeader] = dummyAuthHeaderValue
206 queryParameters[dummyAuthQueryParameter] = dummyAuthQueryParameterValue
207
208 aka := NewAPIKeyAuthorizer(headers, queryParameters)
209
210 req, err := Prepare(mocks.NewRequest(), aka.WithAuthorization())
211
212 if err != nil {
213 t.Fatalf("azure: APIKeyAuthorizer#WithAuthorization returned an error (%v)", err)
214 } else if req.Header.Get(http.CanonicalHeaderKey(dummyAuthHeader)) != dummyAuthHeaderValue {
215 t.Fatalf("azure: APIKeyAuthorizer#WithAuthorization failed to set %s header", dummyAuthHeader)
216
217 } else if req.URL.Query().Get(dummyAuthQueryParameter) != dummyAuthQueryParameterValue {
218 t.Fatalf("azure: APIKeyAuthorizer#WithAuthorization failed to set %s query parameter", dummyAuthQueryParameterValue)
219 }
220 }
221
222 func TestCognitivesServicesAuthorization(t *testing.T) {
223 subscriptionKey := "dummyKey"
224 csa := NewCognitiveServicesAuthorizer(subscriptionKey)
225 req, err := Prepare(mocks.NewRequest(), csa.WithAuthorization())
226
227 if err != nil {
228 t.Fatalf("azure: CognitiveServicesAuthorizer#WithAuthorization returned an error (%v)", err)
229 } else if req.Header.Get(http.CanonicalHeaderKey(bingAPISdkHeader)) != golangBingAPISdkHeaderValue {
230 t.Fatalf("azure: CognitiveServicesAuthorizer#WithAuthorization failed to set %s header", bingAPISdkHeader)
231 } else if req.Header.Get(http.CanonicalHeaderKey(apiKeyAuthorizerHeader)) != subscriptionKey {
232 t.Fatalf("azure: CognitiveServicesAuthorizer#WithAuthorization failed to set %s header", apiKeyAuthorizerHeader)
233 }
234 }
235
236 func TestBasicAuthorization(t *testing.T) {
237 ba := NewBasicAuthorizer("Aladdin", "open sesame")
238 req, err := Prepare(mocks.NewRequest(), ba.WithAuthorization())
239
240 if err != nil {
241 t.Fatalf("BasicAuthorizer#WithAuthorization returned an error (%v)", err)
242 } else if req.Header.Get(http.CanonicalHeaderKey(authorization)) != basic+" QWxhZGRpbjpvcGVuIHNlc2FtZQ==" {
243 t.Fatalf("BasicAuthorizer#WithAuthorization failed to set %s header", authorization)
244 }
245 }
246
247 func TestBasicAuthorizationPasswordOnly(t *testing.T) {
248 ba := NewBasicAuthorizer("", "dummyKey")
249 req, err := Prepare(mocks.NewRequest(), ba.WithAuthorization())
250
251 if err != nil {
252 t.Fatalf("BasicAuthorizer#WithAuthorization returned an error (%v)", err)
253 } else if req.Header.Get(http.CanonicalHeaderKey(authorization)) != basic+" OmR1bW15S2V5" {
254 t.Fatalf("BasicAuthorizer#WithAuthorization failed to set %s header", authorization)
255 }
256 }
257
258 type mockMTSPTProvider struct {
259 p string
260 a []string
261 }
262
263 func (m mockMTSPTProvider) PrimaryOAuthToken() string {
264 return m.p
265 }
266
267 func (m mockMTSPTProvider) AuxiliaryOAuthTokens() []string {
268 return m.a
269 }
270
271 func TestMultitenantAuthorizationOne(t *testing.T) {
272 mtSPTProvider := mockMTSPTProvider{
273 p: "primary",
274 a: []string{TestAuxTenent1},
275 }
276 mt := NewMultiTenantServicePrincipalTokenAuthorizer(mtSPTProvider)
277 req, err := Prepare(mocks.NewRequest(), mt.WithAuthorization())
278 if err != nil {
279 t.Fatalf("unexpected error: %v", err)
280 }
281 if primary := req.Header.Get(headerAuthorization); primary != "Bearer primary" {
282 t.Fatalf("bad primary authorization header %s", primary)
283 }
284 if aux := req.Header.Get(headerAuxAuthorization); aux != "Bearer aux1" {
285 t.Fatalf("bad auxiliary authorization header %s", aux)
286 }
287 }
288
289 func TestMultitenantAuthorizationThree(t *testing.T) {
290 mtSPTProvider := mockMTSPTProvider{
291 p: "primary",
292 a: []string{TestAuxTenent1, TestAuxTenent2, TestAuxTenent3},
293 }
294 mt := NewMultiTenantBearerAuthorizer(mtSPTProvider)
295 req, err := Prepare(mocks.NewRequest(), mt.WithAuthorization())
296 if err != nil {
297 t.Fatalf("unexpected error: %v", err)
298 }
299 if primary := mt.TokenProvider().PrimaryOAuthToken(); primary != mtSPTProvider.p {
300 t.Fatalf("bad primary authorization token %s", primary)
301 }
302 if aux := strings.Join(mt.TokenProvider().AuxiliaryOAuthTokens(), ","); aux != strings.Join(mtSPTProvider.a, ",") {
303 t.Fatalf("bad auxiliary authorization tokens %s", aux)
304 }
305 if primary := req.Header.Get(headerAuthorization); primary != "Bearer primary" {
306 t.Fatalf("bad primary authorization header %s", primary)
307 }
308 if aux := req.Header.Get(headerAuxAuthorization); aux != "Bearer aux1, Bearer aux2, Bearer aux3" {
309 t.Fatalf("bad auxiliary authorization header %s", aux)
310 }
311 }
312
313 func TestMultiTenantServicePrincipalTokenWithAuthorizationRefresh(t *testing.T) {
314 multiTenantCfg, err := adal.NewMultiTenantOAuthConfig(TestActiveDirectoryEndpoint, TestTenantID, []string{TestAuxTenent1, TestAuxTenent2, TestAuxTenent3}, adal.OAuthOptions{})
315 if err != nil {
316 t.Fatalf("azure: adal#NewMultiTenantOAuthConfig returned an error (%v)", err)
317 }
318 mtSpt, err := adal.NewMultiTenantServicePrincipalToken(multiTenantCfg, "id", "secret", "resource")
319 if err != nil {
320 t.Fatalf("azure: adal#NewMultiTenantServicePrincipalToken returned an error (%v)", err)
321 }
322
323 primaryToken := `{
324 "access_token" : "primary token refreshed",
325 "expires_in" : "3600",
326 "expires_on" : "12345",
327 "not_before" : "67890",
328 "resource" : "test",
329 "token_type" : "Bearer"
330 }`
331
332 auxToken1 := `{
333 "access_token" : "aux token 1 refreshed",
334 "expires_in" : "3600",
335 "expires_on" : "12345",
336 "not_before" : "67890",
337 "resource" : "test",
338 "token_type" : "Bearer"
339 }`
340
341 auxToken2 := `{
342 "access_token" : "aux token 2 refreshed",
343 "expires_in" : "3600",
344 "expires_on" : "12345",
345 "not_before" : "67890",
346 "resource" : "test",
347 "token_type" : "Bearer"
348 }`
349
350 auxToken3 := `{
351 "access_token" : "aux token 3 refreshed",
352 "expires_in" : "3600",
353 "expires_on" : "12345",
354 "not_before" : "67890",
355 "resource" : "test",
356 "token_type" : "Bearer"
357 }`
358
359 s := mocks.NewSender()
360 s.AppendResponse(mocks.NewResponseWithBodyAndStatus(mocks.NewBody(primaryToken), http.StatusOK, "OK"))
361 s.AppendResponse(mocks.NewResponseWithBodyAndStatus(mocks.NewBody(auxToken1), http.StatusOK, "OK"))
362 s.AppendResponse(mocks.NewResponseWithBodyAndStatus(mocks.NewBody(auxToken2), http.StatusOK, "OK"))
363 s.AppendResponse(mocks.NewResponseWithBodyAndStatus(mocks.NewBody(auxToken3), http.StatusOK, "OK"))
364
365 mtSpt.PrimaryToken.SetSender(s)
366 for _, aux := range mtSpt.AuxiliaryTokens {
367 aux.SetSender(s)
368 }
369
370 mta := NewMultiTenantServicePrincipalTokenAuthorizer(mtSpt)
371 req, err := Prepare(mocks.NewRequest(), mta.WithAuthorization())
372 if err != nil {
373 t.Fatalf("azure: multiTenantSPTAuthorizer#WithAuthorization returned an error (%v)", err)
374 }
375 if ah := req.Header.Get(http.CanonicalHeaderKey("Authorization")); ah != fmt.Sprintf("Bearer %s", mtSpt.PrimaryOAuthToken()) {
376 t.Fatal("azure: multiTenantSPTAuthorizer#WithAuthorization failed to set Authorization header for primary token")
377 } else if ah != "Bearer primary token refreshed" {
378 t.Fatal("azure: multiTenantSPTAuthorizer#WithAuthorization primary token value doesn't match")
379 }
380 auxTokens := mtSpt.AuxiliaryOAuthTokens()
381 for i := range auxTokens {
382 auxTokens[i] = fmt.Sprintf("Bearer %s", auxTokens[i])
383 }
384 auxHeader := req.Header.Get(http.CanonicalHeaderKey(headerAuxAuthorization))
385 if auxHeader != strings.Join(auxTokens, ", ") {
386 t.Fatal("azure: multiTenantSPTAuthorizer#WithAuthorization failed to set Authorization header for auxiliary tokens")
387 }
388 for i := range auxTokens {
389 if auxTokens[i] != fmt.Sprintf("Bearer aux token %d refreshed", i+1) {
390 t.Fatal("azure: multiTenantSPTAuthorizer#WithAuthorization auxiliary token value doesn't match")
391 }
392 }
393 }
394
395 func TestMultiTenantServicePrincipalTokenWithAuthorizationRefreshFail1(t *testing.T) {
396 multiTenantCfg, err := adal.NewMultiTenantOAuthConfig(TestActiveDirectoryEndpoint, TestTenantID, []string{TestAuxTenent1, TestAuxTenent2, TestAuxTenent3}, adal.OAuthOptions{})
397 if err != nil {
398 t.Fatalf("azure: adal#NewMultiTenantOAuthConfig returned an error (%v)", err)
399 }
400 mtSpt, err := adal.NewMultiTenantServicePrincipalToken(multiTenantCfg, "id", "secret", "resource")
401 if err != nil {
402 t.Fatalf("azure: adal#NewMultiTenantServicePrincipalToken returned an error (%v)", err)
403 }
404
405 s := mocks.NewSender()
406 s.AppendResponse(mocks.NewResponseWithStatus("access denied", http.StatusForbidden))
407
408 mtSpt.PrimaryToken.SetSender(s)
409 for _, aux := range mtSpt.AuxiliaryTokens {
410 aux.SetSender(s)
411 }
412
413 mta := NewMultiTenantServicePrincipalTokenAuthorizer(mtSpt)
414 _, err = Prepare(mocks.NewRequest(), mta.WithAuthorization())
415 if err == nil {
416 t.Fatalf("azure: multiTenantSPTAuthorizer#WithAuthorization unexpected nil error")
417 }
418 }
419
420 func TestMultiTenantServicePrincipalTokenWithAuthorizationRefreshFail2(t *testing.T) {
421 multiTenantCfg, err := adal.NewMultiTenantOAuthConfig(TestActiveDirectoryEndpoint, TestTenantID, []string{TestAuxTenent1, TestAuxTenent2, TestAuxTenent3}, adal.OAuthOptions{})
422 if err != nil {
423 t.Fatalf("azure: adal#NewMultiTenantOAuthConfig returned an error (%v)", err)
424 }
425 mtSpt, err := adal.NewMultiTenantServicePrincipalToken(multiTenantCfg, "id", "secret", "resource")
426 if err != nil {
427 t.Fatalf("azure: adal#NewMultiTenantServicePrincipalToken returned an error (%v)", err)
428 }
429
430 primaryToken := `{
431 "access_token" : "primary token refreshed",
432 "expires_in" : "3600",
433 "expires_on" : "test",
434 "not_before" : "test",
435 "resource" : "test",
436 "token_type" : "Bearer"
437 }`
438
439 s := mocks.NewSender()
440 s.AppendResponse(mocks.NewResponseWithBodyAndStatus(mocks.NewBody(primaryToken), http.StatusOK, "OK"))
441 s.AppendResponse(mocks.NewResponseWithStatus("access denied", http.StatusForbidden))
442
443 mtSpt.PrimaryToken.SetSender(s)
444 for _, aux := range mtSpt.AuxiliaryTokens {
445 aux.SetSender(s)
446 }
447
448 mta := NewMultiTenantServicePrincipalTokenAuthorizer(mtSpt)
449 _, err = Prepare(mocks.NewRequest(), mta.WithAuthorization())
450 if err == nil {
451 t.Fatalf("azure: multiTenantSPTAuthorizer#WithAuthorization unexpected nil error")
452 }
453 }
454
View as plain text