Update golang.org/x/golang.org/x/oauth2
The primary reason is to use JWTAccessTokenSourceFromJSON and
DefaultTokenSource.
Change-Id: I17d90715f3ca580c6dfd4bffd2c17eb9ae06923a
diff --git a/go/src/golang.org/x/oauth2/README.google b/go/src/golang.org/x/oauth2/README.google
index ff08bcf..2459346 100644
--- a/go/src/golang.org/x/oauth2/README.google
+++ b/go/src/golang.org/x/oauth2/README.google
@@ -1,5 +1,5 @@
-URL: https://github.com/golang/oauth2/archive/8914e5017ca260f2a3a1575b1e6868874050d95e.tar.gz
-Version: 8914e5017ca260f2a3a1575b1e6868874050d95e
+URL: https://github.com/golang/oauth2/archive/442624c9ec9243441e83b374a9e22ac549b5c51d.tar.gz
+Version: 442624c9ec9243441e83b374a9e22ac549b5c51d
License: New BSD
License File: LICENSE
diff --git a/go/src/golang.org/x/oauth2/bitbucket/bitbucket.go b/go/src/golang.org/x/oauth2/bitbucket/bitbucket.go
new file mode 100644
index 0000000..44af1f1
--- /dev/null
+++ b/go/src/golang.org/x/oauth2/bitbucket/bitbucket.go
@@ -0,0 +1,16 @@
+// Copyright 2015 The oauth2 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 bitbucket provides constants for using OAuth2 to access Bitbucket.
+package bitbucket
+
+import (
+ "golang.org/x/oauth2"
+)
+
+// Endpoint is Bitbucket's OAuth 2.0 endpoint.
+var Endpoint = oauth2.Endpoint{
+ AuthURL: "https://bitbucket.org/site/oauth2/authorize",
+ TokenURL: "https://bitbucket.org/site/oauth2/access_token",
+}
diff --git a/go/src/golang.org/x/oauth2/client_appengine.go b/go/src/golang.org/x/oauth2/client_appengine.go
index 4a554cb..8962c49 100644
--- a/go/src/golang.org/x/oauth2/client_appengine.go
+++ b/go/src/golang.org/x/oauth2/client_appengine.go
@@ -1,8 +1,8 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
-// +build appengine appenginevm
+// +build appengine
// App Engine hooks.
diff --git a/go/src/golang.org/x/oauth2/clientcredentials/clientcredentials.go b/go/src/golang.org/x/oauth2/clientcredentials/clientcredentials.go
index baebced..38be112 100644
--- a/go/src/golang.org/x/oauth2/clientcredentials/clientcredentials.go
+++ b/go/src/golang.org/x/oauth2/clientcredentials/clientcredentials.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
@@ -66,7 +66,7 @@
Scopes []string
}
-// Token uses client credentials to retreive a token.
+// Token uses client credentials to retrieve a token.
// The HTTP client to use is derived from the context.
// If nil, http.DefaultClient is used.
func (c *Config) Token(ctx context.Context) (*oauth2.Token, error) {
diff --git a/go/src/golang.org/x/oauth2/clientcredentials/clientcredentials_test.go b/go/src/golang.org/x/oauth2/clientcredentials/clientcredentials_test.go
index ab319e0..5a0170a 100644
--- a/go/src/golang.org/x/oauth2/clientcredentials/clientcredentials_test.go
+++ b/go/src/golang.org/x/oauth2/clientcredentials/clientcredentials_test.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
diff --git a/go/src/golang.org/x/oauth2/example_test.go b/go/src/golang.org/x/oauth2/example_test.go
index 8be2788..33b305c 100644
--- a/go/src/golang.org/x/oauth2/example_test.go
+++ b/go/src/golang.org/x/oauth2/example_test.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
diff --git a/go/src/golang.org/x/oauth2/facebook/facebook.go b/go/src/golang.org/x/oauth2/facebook/facebook.go
index 962e86b..14c801a 100644
--- a/go/src/golang.org/x/oauth2/facebook/facebook.go
+++ b/go/src/golang.org/x/oauth2/facebook/facebook.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
+// Copyright 2015 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.
diff --git a/go/src/golang.org/x/oauth2/github/github.go b/go/src/golang.org/x/oauth2/github/github.go
index 1648cb5..f297801 100644
--- a/go/src/golang.org/x/oauth2/github/github.go
+++ b/go/src/golang.org/x/oauth2/github/github.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
diff --git a/go/src/golang.org/x/oauth2/google/appengine.go b/go/src/golang.org/x/oauth2/google/appengine.go
index 65dc347..dc993ef 100644
--- a/go/src/golang.org/x/oauth2/google/appengine.go
+++ b/go/src/golang.org/x/oauth2/google/appengine.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
@@ -14,6 +14,9 @@
"golang.org/x/oauth2"
)
+// Set at init time by appenginevm_hook.go. If true, we are on App Engine Managed VMs.
+var appengineVM bool
+
// Set at init time by appengine_hook.go. If nil, we're not on App Engine.
var appengineTokenFunc func(c context.Context, scopes ...string) (token string, expiry time.Time, err error)
diff --git a/go/src/golang.org/x/oauth2/google/appengine_hook.go b/go/src/golang.org/x/oauth2/google/appengine_hook.go
index 2f9b154..4f42c8b 100644
--- a/go/src/golang.org/x/oauth2/google/appengine_hook.go
+++ b/go/src/golang.org/x/oauth2/google/appengine_hook.go
@@ -1,8 +1,8 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
+// Copyright 2015 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.
-// +build appengine appenginevm
+// +build appengine
package google
diff --git a/go/src/golang.org/x/oauth2/google/appenginevm_hook.go b/go/src/golang.org/x/oauth2/google/appenginevm_hook.go
new file mode 100644
index 0000000..633611c
--- /dev/null
+++ b/go/src/golang.org/x/oauth2/google/appenginevm_hook.go
@@ -0,0 +1,14 @@
+// Copyright 2015 The oauth2 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build appenginevm
+
+package google
+
+import "google.golang.org/appengine"
+
+func init() {
+ appengineVM = true
+ appengineTokenFunc = appengine.AccessToken
+}
diff --git a/go/src/golang.org/x/oauth2/google/default.go b/go/src/golang.org/x/oauth2/google/default.go
index 78f8089..b952362 100644
--- a/go/src/golang.org/x/oauth2/google/default.go
+++ b/go/src/golang.org/x/oauth2/google/default.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
+// Copyright 2015 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.
@@ -50,7 +50,8 @@
// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
// 3. On Google App Engine it uses the appengine.AccessToken function.
-// 4. On Google Compute Engine, it fetches credentials from the metadata server.
+// 4. On Google Compute Engine and Google App Engine Managed VMs, it fetches
+// credentials from the metadata server.
// (In this final case any provided scopes are ignored.)
//
// For more details, see:
@@ -84,7 +85,7 @@
}
// Third, if we're on Google App Engine use those credentials.
- if appengineTokenFunc != nil {
+ if appengineTokenFunc != nil && !appengineVM {
return AppEngineTokenSource(ctx, scope...), nil
}
diff --git a/go/src/golang.org/x/oauth2/google/example_test.go b/go/src/golang.org/x/oauth2/google/example_test.go
index 1726280..9745be1 100644
--- a/go/src/golang.org/x/oauth2/google/example_test.go
+++ b/go/src/golang.org/x/oauth2/google/example_test.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
diff --git a/go/src/golang.org/x/oauth2/google/google.go b/go/src/golang.org/x/oauth2/google/google.go
index 74aa7d9..9a3d5fe 100644
--- a/go/src/golang.org/x/oauth2/google/google.go
+++ b/go/src/golang.org/x/oauth2/google/google.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
diff --git a/go/src/golang.org/x/oauth2/google/google_test.go b/go/src/golang.org/x/oauth2/google/google_test.go
index 4cc0188..74080ed 100644
--- a/go/src/golang.org/x/oauth2/google/google_test.go
+++ b/go/src/golang.org/x/oauth2/google/google_test.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
+// Copyright 2015 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.
diff --git a/go/src/golang.org/x/oauth2/google/jwt.go b/go/src/golang.org/x/oauth2/google/jwt.go
new file mode 100644
index 0000000..b919917
--- /dev/null
+++ b/go/src/golang.org/x/oauth2/google/jwt.go
@@ -0,0 +1,71 @@
+// Copyright 2015 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 google
+
+import (
+ "crypto/rsa"
+ "fmt"
+ "time"
+
+ "golang.org/x/oauth2"
+ "golang.org/x/oauth2/internal"
+ "golang.org/x/oauth2/jws"
+)
+
+// JWTAccessTokenSourceFromJSON uses a Google Developers service account JSON
+// key file to read the credentials that authorize and authenticate the
+// requests, and returns a TokenSource that does not use any OAuth2 flow but
+// instead creates a JWT and sends that as the access token.
+// The audience is typically a URL that specifies the scope of the credentials.
+//
+// Note that this is not a standard OAuth flow, but rather an
+// optimization supported by a few Google services.
+// Unless you know otherwise, you should use JWTConfigFromJSON instead.
+func JWTAccessTokenSourceFromJSON(jsonKey []byte, audience string) (oauth2.TokenSource, error) {
+ cfg, err := JWTConfigFromJSON(jsonKey)
+ if err != nil {
+ return nil, fmt.Errorf("google: could not parse JSON key: %v", err)
+ }
+ pk, err := internal.ParseKey(cfg.PrivateKey)
+ if err != nil {
+ return nil, fmt.Errorf("google: could not parse key: %v", err)
+ }
+ ts := &jwtAccessTokenSource{
+ email: cfg.Email,
+ audience: audience,
+ pk: pk,
+ }
+ tok, err := ts.Token()
+ if err != nil {
+ return nil, err
+ }
+ return oauth2.ReuseTokenSource(tok, ts), nil
+}
+
+type jwtAccessTokenSource struct {
+ email, audience string
+ pk *rsa.PrivateKey
+}
+
+func (ts *jwtAccessTokenSource) Token() (*oauth2.Token, error) {
+ iat := time.Now()
+ exp := iat.Add(time.Hour)
+ cs := &jws.ClaimSet{
+ Iss: ts.email,
+ Sub: ts.email,
+ Aud: ts.audience,
+ Iat: iat.Unix(),
+ Exp: exp.Unix(),
+ }
+ hdr := &jws.Header{
+ Algorithm: "RS256",
+ Typ: "JWT",
+ }
+ msg, err := jws.Encode(hdr, cs, ts.pk)
+ if err != nil {
+ return nil, fmt.Errorf("google: could not encode JWT: %v", err)
+ }
+ return &oauth2.Token{AccessToken: msg, TokenType: "Bearer", Expiry: exp}, nil
+}
diff --git a/go/src/golang.org/x/oauth2/google/sdk.go b/go/src/golang.org/x/oauth2/google/sdk.go
index 01ba0ec..d29a3bb 100644
--- a/go/src/golang.org/x/oauth2/google/sdk.go
+++ b/go/src/golang.org/x/oauth2/google/sdk.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
+// Copyright 2015 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.
diff --git a/go/src/golang.org/x/oauth2/google/sdk_test.go b/go/src/golang.org/x/oauth2/google/sdk_test.go
index 79df889..a5aa2a6 100644
--- a/go/src/golang.org/x/oauth2/google/sdk_test.go
+++ b/go/src/golang.org/x/oauth2/google/sdk_test.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
+// Copyright 2015 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.
diff --git a/go/src/golang.org/x/oauth2/internal/oauth2.go b/go/src/golang.org/x/oauth2/internal/oauth2.go
index dc8ebfc..fbe1028 100644
--- a/go/src/golang.org/x/oauth2/internal/oauth2.go
+++ b/go/src/golang.org/x/oauth2/internal/oauth2.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
diff --git a/go/src/golang.org/x/oauth2/internal/oauth2_test.go b/go/src/golang.org/x/oauth2/internal/oauth2_test.go
index 014a351..c615855 100644
--- a/go/src/golang.org/x/oauth2/internal/oauth2_test.go
+++ b/go/src/golang.org/x/oauth2/internal/oauth2_test.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
diff --git a/go/src/golang.org/x/oauth2/internal/token.go b/go/src/golang.org/x/oauth2/internal/token.go
index a17d79d..39caf6c 100644
--- a/go/src/golang.org/x/oauth2/internal/token.go
+++ b/go/src/golang.org/x/oauth2/internal/token.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
@@ -91,25 +91,32 @@
var brokenAuthHeaderProviders = []string{
"https://accounts.google.com/",
- "https://www.googleapis.com/",
- "https://github.com/",
- "https://api.instagram.com/",
- "https://www.douban.com/",
"https://api.dropbox.com/",
- "https://api.soundcloud.com/",
- "https://www.linkedin.com/",
- "https://api.twitch.tv/",
- "https://oauth.vk.com/",
+ "https://api.instagram.com/",
+ "https://api.netatmo.net/",
"https://api.odnoklassniki.ru/",
- "https://connect.stripe.com/",
"https://api.pushbullet.com/",
+ "https://api.soundcloud.com/",
+ "https://api.twitch.tv/",
+ "https://app.box.com/",
+ "https://connect.stripe.com/",
+ "https://login.microsoftonline.com/",
+ "https://login.salesforce.com/",
"https://oauth.sandbox.trainingpeaks.com/",
"https://oauth.trainingpeaks.com/",
- "https://www.strava.com/oauth/",
- "https://app.box.com/",
+ "https://oauth.vk.com/",
+ "https://slack.com/",
"https://test-sandbox.auth.corp.google.com",
+ "https://test.salesforce.com/",
"https://user.gini.net/",
- "https://api.netatmo.net/",
+ "https://www.douban.com/",
+ "https://www.googleapis.com/",
+ "https://www.linkedin.com/",
+ "https://www.strava.com/oauth/",
+}
+
+func RegisterBrokenAuthHeaderProvider(tokenURL string) {
+ brokenAuthHeaderProviders = append(brokenAuthHeaderProviders, tokenURL)
}
// providerAuthHeaderWorks reports whether the OAuth2 server identified by the tokenURL
diff --git a/go/src/golang.org/x/oauth2/internal/token_test.go b/go/src/golang.org/x/oauth2/internal/token_test.go
index 864f6fa..d8d1e98 100644
--- a/go/src/golang.org/x/oauth2/internal/token_test.go
+++ b/go/src/golang.org/x/oauth2/internal/token_test.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
@@ -10,6 +10,14 @@
"testing"
)
+func TestRegisterBrokenAuthHeaderProvider(t *testing.T) {
+ RegisterBrokenAuthHeaderProvider("https://aaa.com/")
+ tokenURL := "https://aaa.com/token"
+ if providerAuthHeaderWorks(tokenURL) {
+ t.Errorf("URL: %s is a broken provider", tokenURL)
+ }
+}
+
func Test_providerAuthHeaderWorks(t *testing.T) {
for _, p := range brokenAuthHeaderProviders {
if providerAuthHeaderWorks(p) {
diff --git a/go/src/golang.org/x/oauth2/internal/transport.go b/go/src/golang.org/x/oauth2/internal/transport.go
index 521e7b4..33d3669 100644
--- a/go/src/golang.org/x/oauth2/internal/transport.go
+++ b/go/src/golang.org/x/oauth2/internal/transport.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
diff --git a/go/src/golang.org/x/oauth2/jws/jws.go b/go/src/golang.org/x/oauth2/jws/jws.go
index 362323c..8ca5978 100644
--- a/go/src/golang.org/x/oauth2/jws/jws.go
+++ b/go/src/golang.org/x/oauth2/jws/jws.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
@@ -27,8 +27,8 @@
Iss string `json:"iss"` // email address of the client_id of the application making the access token request
Scope string `json:"scope,omitempty"` // space-delimited list of the permissions the application requests
Aud string `json:"aud"` // descriptor of the intended target of the assertion (Optional).
- Exp int64 `json:"exp"` // the expiration time of the assertion
- Iat int64 `json:"iat"` // the time the assertion was issued.
+ Exp int64 `json:"exp"` // the expiration time of the assertion (seconds since Unix epoch)
+ Iat int64 `json:"iat"` // the time the assertion was issued (seconds since Unix epoch)
Typ string `json:"typ,omitempty"` // token type (Optional).
// Email for which the application is requesting delegated access (Optional).
@@ -41,23 +41,22 @@
// See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3
// This array is marshalled using custom code (see (c *ClaimSet) encode()).
PrivateClaims map[string]interface{} `json:"-"`
-
- exp time.Time
- iat time.Time
}
func (c *ClaimSet) encode() (string, error) {
- if c.exp.IsZero() || c.iat.IsZero() {
- // Reverting time back for machines whose time is not perfectly in sync.
- // If client machine's time is in the future according
- // to Google servers, an access token will not be issued.
- now := time.Now().Add(-10 * time.Second)
- c.iat = now
- c.exp = now.Add(time.Hour)
+ // Reverting time back for machines whose time is not perfectly in sync.
+ // If client machine's time is in the future according
+ // to Google servers, an access token will not be issued.
+ now := time.Now().Add(-10 * time.Second)
+ if c.Iat == 0 {
+ c.Iat = now.Unix()
}
-
- c.Exp = c.exp.Unix()
- c.Iat = c.iat.Unix()
+ if c.Exp == 0 {
+ c.Exp = now.Add(time.Hour).Unix()
+ }
+ if c.Exp < c.Iat {
+ return "", fmt.Errorf("jws: invalid Exp = %v; must be later than Iat = %v", c.Exp, c.Iat)
+ }
b, err := json.Marshal(c)
if err != nil {
@@ -120,8 +119,11 @@
return c, err
}
-// Encode encodes a signed JWS with provided header and claim set.
-func Encode(header *Header, c *ClaimSet, signature *rsa.PrivateKey) (string, error) {
+// Signer returns a signature for the given data.
+type Signer func(data []byte) (sig []byte, err error)
+
+// EncodeWithSigner encodes a header and claim set with the provided signer.
+func EncodeWithSigner(header *Header, c *ClaimSet, sg Signer) (string, error) {
head, err := header.encode()
if err != nil {
return "", err
@@ -131,14 +133,22 @@
return "", err
}
ss := fmt.Sprintf("%s.%s", head, cs)
- h := sha256.New()
- h.Write([]byte(ss))
- b, err := rsa.SignPKCS1v15(rand.Reader, signature, crypto.SHA256, h.Sum(nil))
+ sig, err := sg([]byte(ss))
if err != nil {
return "", err
}
- sig := base64Encode(b)
- return fmt.Sprintf("%s.%s", ss, sig), nil
+ return fmt.Sprintf("%s.%s", ss, base64Encode(sig)), nil
+}
+
+// Encode encodes a signed JWS with provided header and claim set.
+// This invokes EncodeWithSigner using crypto/rsa.SignPKCS1v15 with the given RSA private key.
+func Encode(header *Header, c *ClaimSet, key *rsa.PrivateKey) (string, error) {
+ sg := func(data []byte) (sig []byte, err error) {
+ h := sha256.New()
+ h.Write([]byte(data))
+ return rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, h.Sum(nil))
+ }
+ return EncodeWithSigner(header, c, sg)
}
// base64Encode returns and Base64url encoded version of the input string with any
@@ -151,6 +161,8 @@
func base64Decode(s string) ([]byte, error) {
// add back missing padding
switch len(s) % 4 {
+ case 1:
+ s += "==="
case 2:
s += "=="
case 3:
diff --git a/go/src/golang.org/x/oauth2/jwt/example_test.go b/go/src/golang.org/x/oauth2/jwt/example_test.go
index 6d61883..a9533e8 100644
--- a/go/src/golang.org/x/oauth2/jwt/example_test.go
+++ b/go/src/golang.org/x/oauth2/jwt/example_test.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
diff --git a/go/src/golang.org/x/oauth2/jwt/jwt.go b/go/src/golang.org/x/oauth2/jwt/jwt.go
index 205d23e..2ffad21 100644
--- a/go/src/golang.org/x/oauth2/jwt/jwt.go
+++ b/go/src/golang.org/x/oauth2/jwt/jwt.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
@@ -54,6 +54,9 @@
// TokenURL is the endpoint required to complete the 2-legged JWT flow.
TokenURL string
+
+ // Expires optionally specifies how long the token is valid for.
+ Expires time.Duration
}
// TokenSource returns a JWT TokenSource using the configuration
@@ -95,6 +98,9 @@
// to be compatible with legacy OAuth 2.0 providers.
claimSet.Prn = subject
}
+ if t := js.conf.Expires; t > 0 {
+ claimSet.Exp = time.Now().Add(t).Unix()
+ }
payload, err := jws.Encode(defaultHeader, claimSet, pk)
if err != nil {
return nil, err
diff --git a/go/src/golang.org/x/oauth2/jwt/jwt_test.go b/go/src/golang.org/x/oauth2/jwt/jwt_test.go
index da922c3..a9c126b 100644
--- a/go/src/golang.org/x/oauth2/jwt/jwt_test.go
+++ b/go/src/golang.org/x/oauth2/jwt/jwt_test.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
diff --git a/go/src/golang.org/x/oauth2/linkedin/linkedin.go b/go/src/golang.org/x/oauth2/linkedin/linkedin.go
index de91d5b..b619f93 100644
--- a/go/src/golang.org/x/oauth2/linkedin/linkedin.go
+++ b/go/src/golang.org/x/oauth2/linkedin/linkedin.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
+// Copyright 2015 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.
diff --git a/go/src/golang.org/x/oauth2/oauth2.go b/go/src/golang.org/x/oauth2/oauth2.go
index cca8b18..a682896 100644
--- a/go/src/golang.org/x/oauth2/oauth2.go
+++ b/go/src/golang.org/x/oauth2/oauth2.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
@@ -23,6 +23,18 @@
// 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 {
diff --git a/go/src/golang.org/x/oauth2/oauth2_test.go b/go/src/golang.org/x/oauth2/oauth2_test.go
index 2f7d731..448673b 100644
--- a/go/src/golang.org/x/oauth2/oauth2_test.go
+++ b/go/src/golang.org/x/oauth2/oauth2_test.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
@@ -11,6 +11,7 @@
"io/ioutil"
"net/http"
"net/http/httptest"
+ "net/url"
"reflect"
"strconv"
"testing"
@@ -170,6 +171,54 @@
if scope != "user" {
t.Errorf("Unexpected value for scope: %v", scope)
}
+ expiresIn := tok.Extra("expires_in")
+ if expiresIn != float64(86400) {
+ t.Errorf("Unexpected non-numeric value for expires_in: %v", expiresIn)
+ }
+}
+
+func TestExtraValueRetrieval(t *testing.T) {
+ values := url.Values{}
+
+ kvmap := map[string]string{
+ "scope": "user", "token_type": "bearer", "expires_in": "86400.92",
+ "server_time": "1443571905.5606415", "referer_ip": "10.0.0.1",
+ "etag": "\"afZYj912P4alikMz_P11982\"", "request_id": "86400",
+ "untrimmed": " untrimmed ",
+ }
+
+ for key, value := range kvmap {
+ values.Set(key, value)
+ }
+
+ tok := Token{
+ raw: values,
+ }
+
+ scope := tok.Extra("scope")
+ if scope != "user" {
+ t.Errorf("Unexpected scope %v wanted \"user\"", scope)
+ }
+ serverTime := tok.Extra("server_time")
+ if serverTime != 1443571905.5606415 {
+ t.Errorf("Unexpected non-float64 value for server_time: %v", serverTime)
+ }
+ refererIp := tok.Extra("referer_ip")
+ if refererIp != "10.0.0.1" {
+ t.Errorf("Unexpected non-string value for referer_ip: %v", refererIp)
+ }
+ expires_in := tok.Extra("expires_in")
+ if expires_in != 86400.92 {
+ t.Errorf("Unexpected value for expires_in, wanted 86400 got %v", expires_in)
+ }
+ requestId := tok.Extra("request_id")
+ if requestId != int64(86400) {
+ t.Errorf("Unexpected non-int64 value for request_id: %v", requestId)
+ }
+ untrimmed := tok.Extra("untrimmed")
+ if untrimmed != " untrimmed " {
+ t.Errorf("Unexpected value for untrimmed, got %q expected \" untrimmed \"", untrimmed)
+ }
}
const day = 24 * time.Hour
diff --git a/go/src/golang.org/x/oauth2/odnoklassniki/odnoklassniki.go b/go/src/golang.org/x/oauth2/odnoklassniki/odnoklassniki.go
index 2f7a962..c0d093c 100644
--- a/go/src/golang.org/x/oauth2/odnoklassniki/odnoklassniki.go
+++ b/go/src/golang.org/x/oauth2/odnoklassniki/odnoklassniki.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
+// Copyright 2015 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.
diff --git a/go/src/golang.org/x/oauth2/paypal/paypal.go b/go/src/golang.org/x/oauth2/paypal/paypal.go
index baeaa23..2e713c5 100644
--- a/go/src/golang.org/x/oauth2/paypal/paypal.go
+++ b/go/src/golang.org/x/oauth2/paypal/paypal.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
+// Copyright 2015 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.
diff --git a/go/src/golang.org/x/oauth2/token.go b/go/src/golang.org/x/oauth2/token.go
index ebbdddb..7a3167f 100644
--- a/go/src/golang.org/x/oauth2/token.go
+++ b/go/src/golang.org/x/oauth2/token.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
@@ -7,6 +7,7 @@
import (
"net/http"
"net/url"
+ "strconv"
"strings"
"time"
@@ -92,14 +93,28 @@
// Extra fields are key-value pairs returned by the server as a
// part of the token retrieval response.
func (t *Token) Extra(key string) interface{} {
- if vals, ok := t.raw.(url.Values); ok {
- // TODO(jbd): Cast numeric values to int64 or float64.
- return vals.Get(key)
- }
if raw, ok := t.raw.(map[string]interface{}); ok {
return raw[key]
}
- return nil
+
+ vals, ok := t.raw.(url.Values)
+ if !ok {
+ return nil
+ }
+
+ v := vals.Get(key)
+ switch s := strings.TrimSpace(v); strings.Count(s, ".") {
+ case 0: // Contains no "."; try to parse as int
+ if i, err := strconv.ParseInt(s, 10, 64); err == nil {
+ return i
+ }
+ case 1: // Contains a single "."; try to parse as float
+ if f, err := strconv.ParseFloat(s, 64); err == nil {
+ return f
+ }
+ }
+
+ return v
}
// expired reports whether the token is expired.
diff --git a/go/src/golang.org/x/oauth2/token_test.go b/go/src/golang.org/x/oauth2/token_test.go
index 739eeb2..80db83c 100644
--- a/go/src/golang.org/x/oauth2/token_test.go
+++ b/go/src/golang.org/x/oauth2/token_test.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
@@ -41,6 +41,7 @@
}{
{name: "12 seconds", tok: &Token{Expiry: now.Add(12 * time.Second)}, want: false},
{name: "10 seconds", tok: &Token{Expiry: now.Add(expiryDelta)}, want: true},
+ {name: "-1 hour", tok: &Token{Expiry: now.Add(-1 * time.Hour)}, want: true},
}
for _, tc := range cases {
if got, want := tc.tok.expired(), tc.want; got != want {
@@ -48,3 +49,24 @@
}
}
}
+
+func TestTokenTypeMethod(t *testing.T) {
+ cases := []struct {
+ name string
+ tok *Token
+ want string
+ }{
+ {name: "bearer-mixed_case", tok: &Token{TokenType: "beAREr"}, want: "Bearer"},
+ {name: "default-bearer", tok: &Token{}, want: "Bearer"},
+ {name: "basic", tok: &Token{TokenType: "basic"}, want: "Basic"},
+ {name: "basic-capitalized", tok: &Token{TokenType: "Basic"}, want: "Basic"},
+ {name: "mac", tok: &Token{TokenType: "mac"}, want: "MAC"},
+ {name: "mac-caps", tok: &Token{TokenType: "MAC"}, want: "MAC"},
+ {name: "mac-mixed_case", tok: &Token{TokenType: "mAc"}, want: "MAC"},
+ }
+ for _, tc := range cases {
+ if got, want := tc.tok.Type(), tc.want; got != want {
+ t.Errorf("TokenType(%q) = %v; want %v", tc.name, got, want)
+ }
+ }
+}
diff --git a/go/src/golang.org/x/oauth2/transport.go b/go/src/golang.org/x/oauth2/transport.go
index 90db088..92ac7e2 100644
--- a/go/src/golang.org/x/oauth2/transport.go
+++ b/go/src/golang.org/x/oauth2/transport.go
@@ -1,4 +1,4 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
+// 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.
diff --git a/go/src/golang.org/x/oauth2/vk/vk.go b/go/src/golang.org/x/oauth2/vk/vk.go
index 5acdeb1..bd8e159 100644
--- a/go/src/golang.org/x/oauth2/vk/vk.go
+++ b/go/src/golang.org/x/oauth2/vk/vk.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
+// Copyright 2015 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.