@@ -10,7 +10,6 @@ import (
1010 "crypto/x509"
1111 "encoding/base64"
1212 "encoding/json"
13- "errors"
1413 "fmt"
1514 "io"
1615 "net/http"
@@ -25,6 +24,7 @@ import (
2524 "github.com/kylelemons/godebug/pretty"
2625
2726 "github.com/AzureAD/microsoft-authentication-library-for-go/apps/cache"
27+ "github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors"
2828 "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/exported"
2929 internalTime "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/types/time"
3030 "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/mock"
@@ -35,6 +35,7 @@ import (
3535
3636// errorClient is an HTTP client for tests that should fail when confidential.Client sends a request
3737type errorClient struct {}
38+ type contextKey struct {}
3839
3940func (* errorClient ) Do (req * http.Request ) (* http.Response , error ) {
4041 return nil , fmt .Errorf ("expected no requests but received one for %s" , req .URL .String ())
@@ -138,7 +139,7 @@ func TestAcquireTokenByCredential(t *testing.T) {
138139 }
139140 client , err := fakeClient (accesstokens.TokenResponse {
140141 AccessToken : token ,
141- ExpiresOn : internalTime. DurationTime { T : time .Now ().Add (1 * time .Hour )} ,
142+ ExpiresOn : time .Now ().Add (1 * time .Hour ),
142143 ExtExpiresOn : internalTime.DurationTime {T : time .Now ().Add (1 * time .Hour )},
143144 GrantedScopes : accesstokens.Scopes {Slice : tokenScope },
144145 TokenType : "Bearer" ,
@@ -305,7 +306,7 @@ func TestAcquireTokenOnBehalfOf(t *testing.T) {
305306
306307func TestAcquireTokenByAssertionCallback (t * testing.T ) {
307308 calls := 0
308- key := struct {} {}
309+ key := contextKey {}
309310 ctx := context .WithValue (context .Background (), key , true )
310311 getAssertion := func (c context.Context , o AssertionRequestOptions ) (string , error ) {
311312 if v := c .Value (key ); v == nil || ! v .(bool ) {
@@ -358,7 +359,7 @@ func TestAcquireTokenByAuthCode(t *testing.T) {
358359 tr := accesstokens.TokenResponse {
359360 AccessToken : token ,
360361 RefreshToken : refresh ,
361- ExpiresOn : internalTime. DurationTime { T : time .Now ().Add (1 * time .Hour )} ,
362+ ExpiresOn : time .Now ().Add (1 * time .Hour ),
362363 ExtExpiresOn : internalTime.DurationTime {T : time .Now ().Add (1 * time .Hour )},
363364 GrantedScopes : accesstokens.Scopes {Slice : tokenScope },
364365 IDToken : accesstokens.IDToken {
@@ -427,6 +428,40 @@ func TestAcquireTokenByAuthCode(t *testing.T) {
427428 }
428429}
429430
431+ func TestInvalidJsonErrFromResponse (t * testing.T ) {
432+ cred , err := NewCredFromSecret (fakeSecret )
433+ if err != nil {
434+ t .Fatal (err )
435+ }
436+ tenant := "A"
437+ lmo := "login.microsoftonline.com"
438+ mockClient := mock.Client {}
439+ mockClient .AppendResponse (mock .WithBody (mock .GetInstanceDiscoveryBody (lmo , tenant )))
440+ client , err := New (fmt .Sprintf (authorityFmt , lmo , tenant ), fakeClientID , cred , WithHTTPClient (& mockClient ))
441+ if err != nil {
442+ t .Fatal (err )
443+ }
444+ ctx := context .Background ()
445+ // cache an access token for each tenant. To simplify determining their provenance below, the value of each token is the ID of the tenant that provided it.
446+ if _ , err = client .AcquireTokenSilent (ctx , tokenScope , WithTenantID (tenant )); err == nil {
447+ t .Fatal ("silent auth should fail because the cache is empty" )
448+ }
449+ mockClient .AppendResponse (mock .WithBody (mock .GetTenantDiscoveryBody (lmo , tenant )))
450+ body := fmt .Sprintf (
451+ `{"access_token": "%s","expires_in": %d,"expires_on": %d,"token_type": "Bearer"` ,
452+ tenant , 3600 , time .Now ().Add (time .Duration (3600 )* time .Second ).Unix (),
453+ )
454+ mockClient .AppendResponse (mock .WithBody ([]byte (body )))
455+ _ , err = client .AcquireTokenByCredential (ctx , tokenScope , WithTenantID (tenant ))
456+ if err == nil {
457+ t .Fatal ("should have failed with InvalidJsonErr Response" )
458+ }
459+ var ie errors.InvalidJsonErr
460+ if ! errors .As (err , & ie ) {
461+ t .Fatal ("should have revieved a InvalidJsonErr, but got" , err )
462+ }
463+ }
464+
430465func TestAcquireTokenSilentTenants (t * testing.T ) {
431466 cred , err := NewCredFromSecret (fakeSecret )
432467 if err != nil {
@@ -478,7 +513,7 @@ func TestADFSTokenCaching(t *testing.T) {
478513 AccessToken : "at1" ,
479514 RefreshToken : "rt" ,
480515 TokenType : "bearer" ,
481- ExpiresOn : internalTime. DurationTime { T : time .Now ().Add (time .Hour )} ,
516+ ExpiresOn : time .Now ().Add (time .Hour ),
482517 ExtExpiresOn : internalTime.DurationTime {T : time .Now ().Add (time .Hour )},
483518 GrantedScopes : accesstokens.Scopes {Slice : tokenScope },
484519 IDToken : accesstokens.IDToken {
@@ -608,7 +643,7 @@ func TestNewCredFromCert(t *testing.T) {
608643 t .Run (fmt .Sprintf ("%s/%v" , filepath .Base (file .path ), sendX5c ), func (t * testing.T ) {
609644 client , err := fakeClient (accesstokens.TokenResponse {
610645 AccessToken : token ,
611- ExpiresOn : internalTime. DurationTime { T : time .Now ().Add (time .Hour )} ,
646+ ExpiresOn : time .Now ().Add (time .Hour ),
612647 GrantedScopes : accesstokens.Scopes {Slice : tokenScope },
613648 }, cred , fakeAuthority , opts ... )
614649 if err != nil {
@@ -724,7 +759,7 @@ func TestNewCredFromTokenProvider(t *testing.T) {
724759 expectedToken := "expected token"
725760 called := false
726761 expiresIn := 4200
727- key := struct {} {}
762+ key := contextKey {}
728763 ctx := context .WithValue (context .Background (), key , true )
729764 cred := NewCredFromTokenProvider (func (c context.Context , tp exported.TokenProviderParameters ) (exported.TokenProviderResult , error ) {
730765 if called {
@@ -982,7 +1017,7 @@ func TestWithClaims(t *testing.T) {
9821017 case "password" :
9831018 ar , err = client .AcquireTokenByUsernamePassword (ctx , tokenScope , "username" , "password" , WithClaims (test .claims ))
9841019 default :
985- t .Fatalf ("test bug: no test for " + method )
1020+ t .Fatalf ("test bug: no test for %s" , method )
9861021 }
9871022 if err != nil {
9881023 t .Fatal (err )
@@ -1092,7 +1127,7 @@ func TestWithTenantID(t *testing.T) {
10921127 case "obo" :
10931128 ar , err = client .AcquireTokenOnBehalfOf (ctx , "assertion" , tokenScope , WithTenantID (test .tenant ))
10941129 default :
1095- t .Fatalf ("test bug: no test for " + method )
1130+ t .Fatalf ("test bug: no test for %s" , method )
10961131 }
10971132 if err != nil {
10981133 if test .expectError {
@@ -1402,7 +1437,7 @@ func TestWithAuthenticationScheme(t *testing.T) {
14021437 }
14031438 client , err := fakeClient (accesstokens.TokenResponse {
14041439 AccessToken : token ,
1405- ExpiresOn : internalTime. DurationTime { T : time .Now ().Add (1 * time .Hour )} ,
1440+ ExpiresOn : time .Now ().Add (1 * time .Hour ),
14061441 ExtExpiresOn : internalTime.DurationTime {T : time .Now ().Add (1 * time .Hour )},
14071442 GrantedScopes : accesstokens.Scopes {Slice : tokenScope },
14081443 TokenType : "TokenType" ,
@@ -1442,7 +1477,7 @@ func TestAcquireTokenByCredentialFromDSTS(t *testing.T) {
14421477 }
14431478 client , err := fakeClient (accesstokens.TokenResponse {
14441479 AccessToken : token ,
1445- ExpiresOn : internalTime. DurationTime { T : time .Now ().Add (1 * time .Hour )} ,
1480+ ExpiresOn : time .Now ().Add (1 * time .Hour ),
14461481 ExtExpiresOn : internalTime.DurationTime {T : time .Now ().Add (1 * time .Hour )},
14471482 GrantedScopes : accesstokens.Scopes {Slice : tokenScope },
14481483 TokenType : "Bearer" ,
0 commit comments