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