github.com/dcarley/cf-cli@v6.24.1-0.20170220111324-4225ff346898+incompatible/api/cloudcontroller/wrapper/uaa_authentication.go (about) 1 package wrapper 2 3 import ( 4 "bytes" 5 "io/ioutil" 6 "net/http" 7 8 "code.cloudfoundry.org/cli/api/cloudcontroller" 9 "code.cloudfoundry.org/cli/api/uaa" 10 ) 11 12 //go:generate counterfeiter . UAAClient 13 14 // UAAClient is the interface for getting a valid access token 15 type UAAClient interface { 16 RefreshAccessToken(refreshToken string) (uaa.RefreshToken, error) 17 } 18 19 //go:generate counterfeiter . TokenCache 20 21 // TokenCache is where the UAA token information is stored. 22 type TokenCache interface { 23 AccessToken() string 24 RefreshToken() string 25 SetAccessToken(token string) 26 SetRefreshToken(token string) 27 } 28 29 // UAAAuthentication wraps connections and adds authentication headers to all 30 // requests 31 type UAAAuthentication struct { 32 connection cloudcontroller.Connection 33 client UAAClient 34 cache TokenCache 35 } 36 37 // NewUAAAuthentication returns a pointer to a UAAAuthentication wrapper with 38 // the client and a token cache. 39 func NewUAAAuthentication(client UAAClient, cache TokenCache) *UAAAuthentication { 40 return &UAAAuthentication{ 41 client: client, 42 cache: cache, 43 } 44 } 45 46 // Wrap sets the connection on the UAAAuthentication and returns itself 47 func (t *UAAAuthentication) Wrap(innerconnection cloudcontroller.Connection) cloudcontroller.Connection { 48 t.connection = innerconnection 49 return t 50 } 51 52 // Make adds authentication headers to the passed in request and then calls the 53 // wrapped connection's Make 54 func (t *UAAAuthentication) Make(request *http.Request, passedResponse *cloudcontroller.Response) error { 55 var ( 56 err error 57 rawRequestBody []byte 58 ) 59 60 if request.Body != nil { 61 rawRequestBody, err = ioutil.ReadAll(request.Body) 62 defer request.Body.Close() 63 if err != nil { 64 return err 65 } 66 request.Body = ioutil.NopCloser(bytes.NewBuffer(rawRequestBody)) 67 } 68 69 request.Header.Set("Authorization", t.cache.AccessToken()) 70 71 err = t.connection.Make(request, passedResponse) 72 if _, ok := err.(cloudcontroller.InvalidAuthTokenError); ok { 73 var token uaa.RefreshToken 74 token, err = t.client.RefreshAccessToken(t.cache.RefreshToken()) 75 if err != nil { 76 return err 77 } 78 79 t.cache.SetAccessToken(token.AuthorizationToken()) 80 t.cache.SetRefreshToken(token.RefreshToken) 81 82 if rawRequestBody != nil { 83 request.Body = ioutil.NopCloser(bytes.NewBuffer(rawRequestBody)) 84 } 85 request.Header.Set("Authorization", t.cache.AccessToken()) 86 err = t.connection.Make(request, passedResponse) 87 } 88 89 return err 90 }