github.com/dcarley/cf-cli@v6.24.1-0.20170220111324-4225ff346898+incompatible/api/uaa/wrapper/uaa_authentication_test.go (about)

     1  package wrapper_test
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"net/url"
     9  	"strings"
    10  
    11  	"code.cloudfoundry.org/cli/api/uaa"
    12  	"code.cloudfoundry.org/cli/api/uaa/uaafakes"
    13  	. "code.cloudfoundry.org/cli/api/uaa/wrapper"
    14  	"code.cloudfoundry.org/cli/api/uaa/wrapper/util"
    15  	"code.cloudfoundry.org/cli/api/uaa/wrapper/wrapperfakes"
    16  	. "github.com/onsi/ginkgo"
    17  	. "github.com/onsi/gomega"
    18  )
    19  
    20  var _ = Describe("UAA Authentication", func() {
    21  	var (
    22  		fakeConnection *uaafakes.FakeConnection
    23  		fakeClient     *wrapperfakes.FakeUAAClient
    24  		inMemoryCache  *util.InMemoryCache
    25  
    26  		wrapper uaa.Connection
    27  		request *http.Request
    28  	)
    29  
    30  	BeforeEach(func() {
    31  		fakeConnection = new(uaafakes.FakeConnection)
    32  		fakeClient = new(wrapperfakes.FakeUAAClient)
    33  		inMemoryCache = util.NewInMemoryTokenCache()
    34  
    35  		inner := NewUAAAuthentication(fakeClient, inMemoryCache)
    36  		wrapper = inner.Wrap(fakeConnection)
    37  	})
    38  
    39  	Describe("Make", func() {
    40  		Context("when the token is valid", func() {
    41  			BeforeEach(func() {
    42  				request = &http.Request{
    43  					Header: http.Header{},
    44  				}
    45  				inMemoryCache.SetAccessToken("a-ok")
    46  			})
    47  
    48  			It("adds authentication headers", func() {
    49  				wrapper.Make(request, nil)
    50  
    51  				Expect(fakeConnection.MakeCallCount()).To(Equal(1))
    52  				authenticatedRequest, _ := fakeConnection.MakeArgsForCall(0)
    53  				headers := authenticatedRequest.Header
    54  				Expect(headers["Authorization"]).To(ConsistOf([]string{"a-ok"}))
    55  			})
    56  
    57  			Context("when the request already has headers", func() {
    58  				It("preserves existing headers", func() {
    59  					request.Header.Add("Existing", "header")
    60  					wrapper.Make(request, nil)
    61  
    62  					Expect(fakeConnection.MakeCallCount()).To(Equal(1))
    63  					authenticatedRequest, _ := fakeConnection.MakeArgsForCall(0)
    64  					headers := authenticatedRequest.Header
    65  					Expect(headers["Existing"]).To(ConsistOf([]string{"header"}))
    66  				})
    67  			})
    68  
    69  			Context("when the wrapped connection returns nil", func() {
    70  				It("returns nil", func() {
    71  					fakeConnection.MakeReturns(nil)
    72  
    73  					err := wrapper.Make(request, nil)
    74  					Expect(err).ToNot(HaveOccurred())
    75  				})
    76  			})
    77  
    78  			Context("when the wrapped connection returns an error", func() {
    79  				It("returns the error", func() {
    80  					innerError := errors.New("inner error")
    81  					fakeConnection.MakeReturns(innerError)
    82  
    83  					err := wrapper.Make(request, nil)
    84  					Expect(err).To(Equal(innerError))
    85  				})
    86  			})
    87  		})
    88  
    89  		Context("when the token is invalid", func() {
    90  			var expectedBody string
    91  
    92  			BeforeEach(func() {
    93  				expectedBody = "this body content should be preserved"
    94  				request, err := http.NewRequest(
    95  					http.MethodGet,
    96  					server.URL(),
    97  					ioutil.NopCloser(strings.NewReader(expectedBody)),
    98  				)
    99  				Expect(err).NotTo(HaveOccurred())
   100  
   101  				makeCount := 0
   102  				fakeConnection.MakeStub = func(request *http.Request, response *uaa.Response) error {
   103  					body, err := ioutil.ReadAll(request.Body)
   104  					Expect(err).NotTo(HaveOccurred())
   105  					Expect(string(body)).To(Equal(expectedBody))
   106  
   107  					if makeCount == 0 {
   108  						makeCount += 1
   109  						return uaa.InvalidAuthTokenError{}
   110  					} else {
   111  						return nil
   112  					}
   113  				}
   114  
   115  				fakeClient.RefreshAccessTokenReturns(
   116  					uaa.RefreshToken{
   117  						AccessToken:  "foobar-2",
   118  						RefreshToken: "bananananananana",
   119  						Type:         "bearer",
   120  					},
   121  					nil,
   122  				)
   123  
   124  				inMemoryCache.SetAccessToken("what")
   125  
   126  				err = wrapper.Make(request, nil)
   127  				Expect(err).ToNot(HaveOccurred())
   128  			})
   129  
   130  			It("should refresh the token", func() {
   131  				Expect(fakeClient.RefreshAccessTokenCallCount()).To(Equal(1))
   132  			})
   133  
   134  			It("should resend the request", func() {
   135  				Expect(fakeConnection.MakeCallCount()).To(Equal(2))
   136  
   137  				request, _ := fakeConnection.MakeArgsForCall(1)
   138  				Expect(request.Header.Get("Authorization")).To(Equal("bearer foobar-2"))
   139  			})
   140  
   141  			It("should save the refresh token", func() {
   142  				Expect(inMemoryCache.RefreshToken()).To(Equal("bananananananana"))
   143  			})
   144  		})
   145  
   146  		Context("when refreshing the token", func() {
   147  			BeforeEach(func() {
   148  				body := strings.NewReader(url.Values{
   149  					"grant_type": {"refresh_token"},
   150  				}.Encode())
   151  
   152  				request, err := http.NewRequest("POST", fmt.Sprintf("%s/oauth/token", server.URL()), body)
   153  				Expect(err).NotTo(HaveOccurred())
   154  
   155  				wrapper.Make(request, nil)
   156  			})
   157  
   158  			It("should not set the 'Authorization' header", func() {
   159  				Expect(fakeConnection.MakeCallCount()).To(Equal(1))
   160  
   161  				request, _ := fakeConnection.MakeArgsForCall(0)
   162  				Expect(request.Header.Get("Authorization")).To(BeEmpty())
   163  			})
   164  		})
   165  	})
   166  })