diff options
| author | Paul Zabelin | 2016-04-17 03:22:31 -0700 | 
|---|---|---|
| committer | Paul Zabelin | 2016-04-17 03:22:31 -0700 | 
| commit | b5eb2866cfceb69b0d4dd4948273d679a884fbb2 (patch) | |
| tree | 1fdb61a7138642a1612bb201434e8ebda141cc8a /vendor/golang.org/x/oauth2/oauth2.go | |
| parent | 8de8e05c483c6b5f23b14742315f1860211dcef7 (diff) | |
| download | gdrive-b5eb2866cfceb69b0d4dd4948273d679a884fbb2.tar.bz2 | |
add Go dependencies by godep
see https://github.com/tools/godep
Diffstat (limited to 'vendor/golang.org/x/oauth2/oauth2.go')
| -rw-r--r-- | vendor/golang.org/x/oauth2/oauth2.go | 337 | 
1 files changed, 337 insertions, 0 deletions
| diff --git a/vendor/golang.org/x/oauth2/oauth2.go b/vendor/golang.org/x/oauth2/oauth2.go new file mode 100644 index 0000000..9b7b977 --- /dev/null +++ b/vendor/golang.org/x/oauth2/oauth2.go @@ -0,0 +1,337 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package oauth2 provides support for making +// OAuth2 authorized and authenticated HTTP requests. +// It can additionally grant authorization with Bearer JWT. +package oauth2 + +import ( +	"bytes" +	"errors" +	"net/http" +	"net/url" +	"strings" +	"sync" + +	"golang.org/x/net/context" +	"golang.org/x/oauth2/internal" +) + +// 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() + +// RegisterBrokenAuthHeaderProvider registers an OAuth2 server +// identified by the tokenURL prefix as an OAuth2 implementation +// which doesn't support the HTTP Basic authentication +// scheme to authenticate with the authorization server. +// Once a server is registered, credentials (client_id and client_secret) +// will be passed as query parameters rather than being present +// in the Authorization header. +// See https://code.google.com/p/goauth2/issues/detail?id=31 for background. +func RegisterBrokenAuthHeaderProvider(tokenURL string) { +	internal.RegisterBrokenAuthHeaderProvider(tokenURL) +} + +// Config describes a typical 3-legged OAuth2 flow, with both the +// client application information and the server's endpoint URLs. +type Config struct { +	// ClientID is the application's ID. +	ClientID string + +	// ClientSecret is the application's secret. +	ClientSecret string + +	// Endpoint contains the resource server's token endpoint +	// URLs. These are constants specific to each server and are +	// often available via site-specific packages, such as +	// google.Endpoint or github.Endpoint. +	Endpoint Endpoint + +	// RedirectURL is the URL to redirect users going through +	// the OAuth flow, after the resource owner's URLs. +	RedirectURL string + +	// Scope specifies optional requested permissions. +	Scopes []string +} + +// A TokenSource is anything that can return a token. +type TokenSource interface { +	// Token returns a token or an error. +	// Token must be safe for concurrent use by multiple goroutines. +	// The returned Token must not be modified. +	Token() (*Token, error) +} + +// Endpoint contains the OAuth 2.0 provider's authorization and token +// endpoint URLs. +type Endpoint struct { +	AuthURL  string +	TokenURL string +} + +var ( +	// AccessTypeOnline and AccessTypeOffline are options passed +	// to the Options.AuthCodeURL method. They modify the +	// "access_type" field that gets sent in the URL returned by +	// AuthCodeURL. +	// +	// Online is the default if neither is specified. If your +	// application needs to refresh access tokens when the user +	// is not present at the browser, then use offline. This will +	// result in your application obtaining a refresh token the +	// first time your application exchanges an authorization +	// code for a user. +	AccessTypeOnline  AuthCodeOption = SetAuthURLParam("access_type", "online") +	AccessTypeOffline AuthCodeOption = SetAuthURLParam("access_type", "offline") + +	// ApprovalForce forces the users to view the consent dialog +	// and confirm the permissions request at the URL returned +	// from AuthCodeURL, even if they've already done so. +	ApprovalForce AuthCodeOption = SetAuthURLParam("approval_prompt", "force") +) + +// An AuthCodeOption is passed to Config.AuthCodeURL. +type AuthCodeOption interface { +	setValue(url.Values) +} + +type setParam struct{ k, v string } + +func (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) } + +// SetAuthURLParam builds an AuthCodeOption which passes key/value parameters +// to a provider's authorization endpoint. +func SetAuthURLParam(key, value string) AuthCodeOption { +	return setParam{key, value} +} + +// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page +// that asks for permissions for the required scopes explicitly. +// +// State is a token to protect the user from CSRF attacks. You must +// always provide a non-zero string and validate that it matches the +// the state query parameter on your redirect callback. +// See http://tools.ietf.org/html/rfc6749#section-10.12 for more info. +// +// Opts may include AccessTypeOnline or AccessTypeOffline, as well +// as ApprovalForce. +func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string { +	var buf bytes.Buffer +	buf.WriteString(c.Endpoint.AuthURL) +	v := url.Values{ +		"response_type": {"code"}, +		"client_id":     {c.ClientID}, +		"redirect_uri":  internal.CondVal(c.RedirectURL), +		"scope":         internal.CondVal(strings.Join(c.Scopes, " ")), +		"state":         internal.CondVal(state), +	} +	for _, opt := range opts { +		opt.setValue(v) +	} +	if strings.Contains(c.Endpoint.AuthURL, "?") { +		buf.WriteByte('&') +	} else { +		buf.WriteByte('?') +	} +	buf.WriteString(v.Encode()) +	return buf.String() +} + +// PasswordCredentialsToken converts a resource owner username and password +// pair into a token. +// +// Per the RFC, this grant type should only be used "when there is a high +// degree of trust between the resource owner and the client (e.g., the client +// is part of the device operating system or a highly privileged application), +// 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. +func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) { +	return retrieveToken(ctx, c, url.Values{ +		"grant_type": {"password"}, +		"username":   {username}, +		"password":   {password}, +		"scope":      internal.CondVal(strings.Join(c.Scopes, " ")), +	}) +} + +// Exchange converts an authorization code into a token. +// +// 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 a client is not provided via the context, 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.Context, code string) (*Token, error) { +	return retrieveToken(ctx, c, url.Values{ +		"grant_type":   {"authorization_code"}, +		"code":         {code}, +		"redirect_uri": internal.CondVal(c.RedirectURL), +		"scope":        internal.CondVal(strings.Join(c.Scopes, " ")), +	}) +} + +// Client returns an HTTP client using the provided token. +// 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.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. +// +// Most users will use Config.Client instead. +func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource { +	tkr := &tokenRefresher{ +		ctx:  ctx, +		conf: c, +	} +	if t != nil { +		tkr.refreshToken = t.RefreshToken +	} +	return &reuseTokenSource{ +		t:   t, +		new: tkr, +	} +} + +// tokenRefresher is a TokenSource that makes "grant_type"=="refresh_token" +// HTTP requests to renew a token using a RefreshToken. +type tokenRefresher struct { +	ctx          context.Context // used to get HTTP requests +	conf         *Config +	refreshToken string +} + +// WARNING: Token is not safe for concurrent access, as it +// updates the tokenRefresher's refreshToken field. +// Within this package, it is used by reuseTokenSource which +// synchronizes calls to this method with its own mutex. +func (tf *tokenRefresher) Token() (*Token, error) { +	if tf.refreshToken == "" { +		return nil, errors.New("oauth2: token expired and refresh token is not set") +	} + +	tk, err := retrieveToken(tf.ctx, tf.conf, url.Values{ +		"grant_type":    {"refresh_token"}, +		"refresh_token": {tf.refreshToken}, +	}) + +	if err != nil { +		return nil, err +	} +	if tf.refreshToken != tk.RefreshToken { +		tf.refreshToken = tk.RefreshToken +	} +	return tk, err +} + +// reuseTokenSource is a TokenSource that holds a single token in memory +// and validates its expiry before each call to retrieve it with +// Token. If it's expired, it will be auto-refreshed using the +// new TokenSource. +type reuseTokenSource struct { +	new TokenSource // called when t is expired. + +	mu sync.Mutex // guards t +	t  *Token +} + +// Token returns the current token if it's still valid, else will +// refresh the current token (using r.Context for HTTP client +// information) and return the new one. +func (s *reuseTokenSource) Token() (*Token, error) { +	s.mu.Lock() +	defer s.mu.Unlock() +	if s.t.Valid() { +		return s.t, nil +	} +	t, err := s.new.Token() +	if err != nil { +		return nil, err +	} +	s.t = t +	return t, nil +} + +// StaticTokenSource returns a TokenSource that always returns the same token. +// Because the provided token t is never refreshed, StaticTokenSource is only +// useful for tokens that never expire. +func StaticTokenSource(t *Token) TokenSource { +	return staticTokenSource{t} +} + +// staticTokenSource is a TokenSource that always returns the same Token. +type staticTokenSource struct { +	t *Token +} + +func (s staticTokenSource) Token() (*Token, error) { +	return s.t, nil +} + +// HTTPClient is the context key to use with golang.org/x/net/context's +// WithValue function to associate an *http.Client value with a context. +var HTTPClient internal.ContextKey + +// NewClient creates an *http.Client from a Context and TokenSource. +// The returned client is not valid beyond the lifetime of the context. +// +// 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.Context, src TokenSource) *http.Client { +	if src == nil { +		c, err := internal.ContextClient(ctx) +		if err != nil { +			return &http.Client{Transport: internal.ErrorTransport{err}} +		} +		return c +	} +	return &http.Client{ +		Transport: &Transport{ +			Base:   internal.ContextTransport(ctx), +			Source: ReuseTokenSource(nil, src), +		}, +	} +} + +// ReuseTokenSource returns a TokenSource which repeatedly returns the +// same token as long as it's valid, starting with t. +// When its cached token is invalid, a new token is obtained from src. +// +// ReuseTokenSource is typically used to reuse tokens from a cache +// (such as a file on disk) between runs of a program, rather than +// obtaining new tokens unnecessarily. +// +// The initial token t may be nil, in which case the TokenSource is +// wrapped in a caching version if it isn't one already. This also +// means it's always safe to wrap ReuseTokenSource around any other +// TokenSource without adverse effects. +func ReuseTokenSource(t *Token, src TokenSource) TokenSource { +	// Don't wrap a reuseTokenSource in itself. That would work, +	// but cause an unnecessary number of mutex operations. +	// Just build the equivalent one. +	if rt, ok := src.(*reuseTokenSource); ok { +		if t == nil { +			// Just use it directly. +			return rt +		} +		src = rt.new +	} +	return &reuseTokenSource{ +		t:   t, +		new: src, +	} +} | 
