From 8524783bd7412d650422ad029c932449ea4c8c91 Mon Sep 17 00:00:00 2001 From: Burcu Dogan Date: Tue, 2 Sep 2014 14:06:51 -0700 Subject: [PATCH 1/2] Allow configs to be initialised with zero values for Client and Transport. --- google/appengine.go | 16 ++++++++++------ google/appenginevm.go | 16 +++++++++++----- google/google.go | 24 +++++++++++++++++------- jwt.go | 30 +++++++++++++++++++++--------- oauth2.go | 22 ++++++++++++++++++---- 5 files changed, 77 insertions(+), 31 deletions(-) diff --git a/google/appengine.go b/google/appengine.go index 4a99ffc..2e37d6b 100644 --- a/google/appengine.go +++ b/google/appengine.go @@ -3,6 +3,8 @@ package google import ( + "net/http" + "github.com/golang/oauth2" "appengine" @@ -25,11 +27,6 @@ type AppEngineConfig struct { // provided auth scopes. func NewAppEngineConfig(context appengine.Context, scopes []string) *AppEngineConfig { return &AppEngineConfig{ - Transport: &urlfetch.Transport{ - Context: context, - Deadline: 0, - AllowInvalidServerCertificate: false, - }, context: context, scopes: scopes, } @@ -38,7 +35,7 @@ func NewAppEngineConfig(context appengine.Context, scopes []string) *AppEngineCo // NewTransport returns a transport that authorizes // the requests with the application's service account. func (c *AppEngineConfig) NewTransport() *oauth2.Transport { - return oauth2.NewTransport(c.Transport, c, nil) + return oauth2.NewTransport(c.transport(), c, nil) } // FetchToken fetches a new access token for the provided scopes. @@ -52,3 +49,10 @@ func (c *AppEngineConfig) FetchToken(existing *oauth2.Token) (*oauth2.Token, err Expiry: expiry, }, nil } + +func (c *AppEngineConfig) transport() http.RoundTripper { + if c.Transport != nil { + return c.Transport + } + return &urlfetch.Transport{Context: c.context} +} diff --git a/google/appenginevm.go b/google/appenginevm.go index ea9acc3..dd2acfc 100644 --- a/google/appenginevm.go +++ b/google/appenginevm.go @@ -12,7 +12,7 @@ import ( // AppEngineConfig represents a configuration for an // App Engine application's Google service account. type AppEngineConfig struct { - // Transport is the round tripper to be used + // Transport is the http.RoundTripper to be used // to construct new oauth2.Transport instances from // this configuration. Transport http.RoundTripper @@ -25,16 +25,15 @@ type AppEngineConfig struct { // provided auth scopes. func NewAppEngineConfig(context appengine.Context, scopes []string) *AppEngineConfig { return &AppEngineConfig{ - Transport: http.DefaultTransport, - context: context, - scopes: scopes, + context: context, + scopes: scopes, } } // NewTransport returns a transport that authorizes // the requests with the application's service account. func (c *AppEngineConfig) NewTransport() *oauth2.Transport { - return oauth2.NewTransport(c.Transport, c, nil) + return oauth2.NewTransport(c.transport(), c, nil) } // FetchToken fetches a new access token for the provided scopes. @@ -48,3 +47,10 @@ func (c *AppEngineConfig) FetchToken(existing *oauth2.Token) (*oauth2.Token, err Expiry: expiry, }, nil } + +func (c *AppEngineConfig) transport() http.RoundTripper { + if c.Transport != nil { + return c.Transport + } + return http.DefaultTransport +} diff --git a/google/google.go b/google/google.go index e170415..b8031de 100644 --- a/google/google.go +++ b/google/google.go @@ -65,16 +65,12 @@ func NewServiceAccountConfig(opts *oauth2.JWTOptions) (*oauth2.JWTConfig, error) // from Google Compute Engine instance's metaserver. If no account is // provided, default is used. func NewComputeEngineConfig(account string) *ComputeEngineConfig { - return &ComputeEngineConfig{ - Client: http.DefaultClient, - Transport: http.DefaultTransport, - account: account, - } + return &ComputeEngineConfig{account: account} } // NewTransport creates an authorized transport. func (c *ComputeEngineConfig) NewTransport() *oauth2.Transport { - return oauth2.NewTransport(c.Transport, c, nil) + return oauth2.NewTransport(c.transport(), c, nil) } // FetchToken retrieves a new access token via metadata server. @@ -89,7 +85,7 @@ func (c *ComputeEngineConfig) FetchToken(existing *oauth2.Token) (token *oauth2. return } req.Header.Add("X-Google-Metadata-Request", "True") - resp, err := c.Client.Do(req) + resp, err := c.client().Do(req) if err != nil { return } @@ -106,3 +102,17 @@ func (c *ComputeEngineConfig) FetchToken(existing *oauth2.Token) (token *oauth2. } return } + +func (c *ComputeEngineConfig) transport() http.RoundTripper { + if c.Transport != nil { + return c.Transport + } + return http.DefaultTransport +} + +func (c *ComputeEngineConfig) client() *http.Client { + if c.Client != nil { + return c.Client + } + return http.DefaultClient +} diff --git a/jwt.go b/jwt.go index e34ef8c..f98769f 100644 --- a/jwt.go +++ b/jwt.go @@ -56,11 +56,9 @@ func NewJWTConfig(opts *JWTOptions, aud string) (*JWTConfig, error) { return nil, err } return &JWTConfig{ - Client: http.DefaultClient, - Transport: http.DefaultTransport, - opts: opts, - aud: audURL, - key: parsedKey, + opts: opts, + aud: audURL, + key: parsedKey, }, nil } @@ -71,7 +69,7 @@ type JWTConfig struct { // tokens from the OAuth 2.0 provider. Client *http.Client - // Transport is the round tripper to be used + // Transport is the http.RoundTripper to be used // to construct new oauth2.Transport instances from // this configuration. Transport http.RoundTripper @@ -84,13 +82,13 @@ type JWTConfig struct { // NewTransport creates a transport that is authorize with the // parent JWT configuration. func (c *JWTConfig) NewTransport() *Transport { - return NewTransport(c.Transport, c, &Token{}) + return NewTransport(c.transport(), c, &Token{}) } // NewTransportWithUser creates a transport that is authorized by // the client and impersonates the specified user. func (c *JWTConfig) NewTransportWithUser(user string) *Transport { - return NewTransport(c.Transport, c, &Token{Subject: user}) + return NewTransport(c.transport(), c, &Token{Subject: user}) } // fetchToken retrieves a new access token and updates the existing token @@ -122,7 +120,7 @@ func (c *JWTConfig) FetchToken(existing *Token) (token *Token, err error) { v.Set("assertion", payload) // Make a request with assertion to get a new token. - resp, err := c.Client.PostForm(c.aud.String(), v) + resp, err := c.client().PostForm(c.aud.String(), v) if err != nil { return nil, err } @@ -160,6 +158,20 @@ func (c *JWTConfig) FetchToken(existing *Token) (token *Token, err error) { return } +func (c *JWTConfig) transport() http.RoundTripper { + if c.Transport != nil { + return c.Transport + } + return http.DefaultTransport +} + +func (c *JWTConfig) client() *http.Client { + if c.Client != nil { + return c.Client + } + return http.DefaultClient +} + // parseKey converts the binary contents of a private key file // to an *rsa.PrivateKey. It detects whether the private key is in a // PEM container or not. If so, it extracts the the private key diff --git a/oauth2.go b/oauth2.go index 6441316..c0fd1e8 100644 --- a/oauth2.go +++ b/oauth2.go @@ -115,7 +115,7 @@ type Config struct { // tokens from the OAuth 2.0 provider. Client *http.Client - // Transport is the round tripper to be used + // Transport is the http.RoundTripper to be used // to construct new oauth2.Transport instances from // this configuration. Transport http.RoundTripper @@ -166,7 +166,7 @@ func (c *Config) AuthCodeURL(state string) (authURL string) { // t.SetToken(validToken) // func (c *Config) NewTransport() *Transport { - return NewTransport(c.Transport, c, nil) + return NewTransport(c.transport(), c, nil) } // NewTransportWithCode exchanges the OAuth 2.0 authorization code with @@ -178,7 +178,7 @@ func (c *Config) NewTransportWithCode(code string) (*Transport, error) { if err != nil { return nil, err } - return NewTransport(c.Transport, c, token), nil + return NewTransport(c.transport(), c, token), nil } // FetchToken retrieves a new access token and updates the existing token @@ -231,7 +231,7 @@ func (c *Config) retrieveToken(v url.Values) (*Token, error) { // Dropbox accepts either, but not both. // The spec requires servers to always support the Authorization header, // so that's all we use. - r, err := c.Client.PostForm(c.tokenURL.String(), v) + r, err := c.client().PostForm(c.tokenURL.String(), v) if err != nil { return nil, err } @@ -286,3 +286,17 @@ func (c *Config) retrieveToken(v url.Values) (*Token, error) { } return token, nil } + +func (c *Config) transport() http.RoundTripper { + if c.Transport != nil { + return c.Transport + } + return http.DefaultTransport +} + +func (c *Config) client() *http.Client { + if c.Client != nil { + return c.Client + } + return http.DefaultClient +} From 9d55d5b30b3f81f3c554e1ac957fac018fe6fd74 Mon Sep 17 00:00:00 2001 From: Burcu Dogan Date: Wed, 3 Sep 2014 17:20:29 -0700 Subject: [PATCH 2/2] Relax AppEngineConfig to allow RoundTrippers. --- google/appengine.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google/appengine.go b/google/appengine.go index 2e37d6b..0c3b80a 100644 --- a/google/appengine.go +++ b/google/appengine.go @@ -14,10 +14,10 @@ import ( // AppEngineConfig represents a configuration for an // App Engine application's Google service account. type AppEngineConfig struct { - // Transport is the transport to be used + // Transport is the http.RoundTripper to be used // to construct new oauth2.Transport instances from // this configuration. - Transport *urlfetch.Transport + Transport http.RoundTripper context appengine.Context scopes []string