oauth2: remove oauth2.Context type, simplify App Engine token code

You can now use the "google.golang.org/appengine" packages on both
Managed VMs and App Engine Classic(TM). The newer packages use the
context.Context instead of appengine.Context, so we no longer need the
oauth2.Context type.

Some clients will require code changes, replacing oauth2.Context or
appengine.Context with context.Context (imported from
the repository "golang.org/x/net/context").

Users of classic App Engine must switch to using the new
"google.golang.org/appengine" packages in order to use the oauth2
package.

Fixes #89

Change-Id: Ibaff3117117f9f7c5d1b3048a6e4086f62c18c3b
Reviewed-on: https://go-review.googlesource.com/6075
Reviewed-by: Burcu Dogan <jbd@google.com>
This commit is contained in:
Andrew Gerrand
2015-02-26 16:53:51 +11:00
parent a0fac97f6e
commit 96e89befdc
9 changed files with 104 additions and 193 deletions

View File

@@ -25,14 +25,9 @@ import (
"golang.org/x/net/context"
)
// Context can be an golang.org/x/net/context.Context, or an App Engine Context.
// If you don't care and aren't running on App Engine, you may use NoContext.
type Context interface{}
// NoContext is the default context. If you're not running this code
// on App Engine or not using golang.org/x/net/context.Context to provide a custom
// HTTP client, you should use NoContext.
var NoContext Context = nil
// NoContext is the default context you should supply if not using
// your own context.Context (see https://golang.org/x/net/context).
var NoContext = context.TODO()
// Config describes a typical 3-legged OAuth2 flow, with both the
// client application information and the server's endpoint URLs.
@@ -143,9 +138,9 @@ func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
// and when other authorization grant types are not available."
// See https://tools.ietf.org/html/rfc6749#section-4.3 for more info.
//
// The HTTP client to use is derived from the context. If nil,
// http.DefaultClient is used. See the Context type's documentation.
func (c *Config) PasswordCredentialsToken(ctx Context, username, password string) (*Token, error) {
// The HTTP client to use is derived from the context.
// If nil, http.DefaultClient is used.
func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) {
return retrieveToken(ctx, c, url.Values{
"grant_type": {"password"},
"username": {username},
@@ -159,12 +154,12 @@ func (c *Config) PasswordCredentialsToken(ctx Context, username, password string
// It is used after a resource provider redirects the user back
// to the Redirect URI (the URL obtained from AuthCodeURL).
//
// The HTTP client to use is derived from the context. If nil,
// http.DefaultClient is used. See the Context type's documentation.
// The HTTP client to use is derived from the context.
// If nil, http.DefaultClient is used.
//
// The code will be in the *http.Request.FormValue("code"). Before
// calling Exchange, be sure to validate FormValue("state").
func (c *Config) Exchange(ctx Context, code string) (*Token, error) {
func (c *Config) Exchange(ctx context.Context, code string) (*Token, error) {
return retrieveToken(ctx, c, url.Values{
"grant_type": {"authorization_code"},
"code": {code},
@@ -177,7 +172,7 @@ func (c *Config) Exchange(ctx Context, code string) (*Token, error) {
// given a Context value. If it returns an error, the search stops
// with that error. If it returns (nil, nil), the search continues
// down the list of registered funcs.
type contextClientFunc func(Context) (*http.Client, error)
type contextClientFunc func(context.Context) (*http.Client, error)
var contextClientFuncs []contextClientFunc
@@ -185,7 +180,7 @@ func registerContextClientFunc(fn contextClientFunc) {
contextClientFuncs = append(contextClientFuncs, fn)
}
func contextClient(ctx Context) (*http.Client, error) {
func contextClient(ctx context.Context) (*http.Client, error) {
for _, fn := range contextClientFuncs {
c, err := fn(ctx)
if err != nil {
@@ -195,15 +190,13 @@ func contextClient(ctx Context) (*http.Client, error) {
return c, nil
}
}
if xc, ok := ctx.(context.Context); ok {
if hc, ok := xc.Value(HTTPClient).(*http.Client); ok {
return hc, nil
}
if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok {
return hc, nil
}
return http.DefaultClient, nil
}
func contextTransport(ctx Context) http.RoundTripper {
func contextTransport(ctx context.Context) http.RoundTripper {
hc, err := contextClient(ctx)
if err != nil {
// This is a rare error case (somebody using nil on App Engine),
@@ -219,16 +212,15 @@ func contextTransport(ctx Context) http.RoundTripper {
// The token will auto-refresh as necessary. The underlying
// HTTP transport will be obtained using the provided context.
// The returned client and its Transport should not be modified.
func (c *Config) Client(ctx Context, t *Token) *http.Client {
func (c *Config) Client(ctx context.Context, t *Token) *http.Client {
return NewClient(ctx, c.TokenSource(ctx, t))
}
// TokenSource returns a TokenSource that returns t until t expires,
// automatically refreshing it as necessary using the provided context.
// See the the Context documentation.
//
// Most users will use Config.Client instead.
func (c *Config) TokenSource(ctx Context, t *Token) TokenSource {
func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource {
tkr := &tokenRefresher{
ctx: ctx,
conf: c,
@@ -245,7 +237,7 @@ func (c *Config) TokenSource(ctx Context, t *Token) TokenSource {
// tokenRefresher is a TokenSource that makes "grant_type"=="refresh_token"
// HTTP requests to renew a token using a RefreshToken.
type tokenRefresher struct {
ctx Context // used to get HTTP requests
ctx context.Context // used to get HTTP requests
conf *Config
refreshToken string
}
@@ -301,7 +293,7 @@ func (s *reuseTokenSource) Token() (*Token, error) {
return t, nil
}
func retrieveToken(ctx Context, c *Config, v url.Values) (*Token, error) {
func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) {
hc, err := contextClient(ctx)
if err != nil {
return nil, err
@@ -451,7 +443,7 @@ type contextKey struct{}
// As a special case, if src is nil, a non-OAuth2 client is returned
// using the provided context. This exists to support related OAuth2
// packages.
func NewClient(ctx Context, src TokenSource) *http.Client {
func NewClient(ctx context.Context, src TokenSource) *http.Client {
if src == nil {
c, err := contextClient(ctx)
if err != nil {