aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/golang.org/x/oauth2
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/oauth2')
-rw-r--r--vendor/golang.org/x/oauth2/.travis.yml13
-rw-r--r--vendor/golang.org/x/oauth2/AUTHORS3
-rw-r--r--vendor/golang.org/x/oauth2/CONTRIBUTING.md26
-rw-r--r--vendor/golang.org/x/oauth2/CONTRIBUTORS3
-rw-r--r--vendor/golang.org/x/oauth2/LICENSE27
-rw-r--r--vendor/golang.org/x/oauth2/README.md35
-rw-r--r--vendor/golang.org/x/oauth2/go.mod10
-rw-r--r--vendor/golang.org/x/oauth2/go.sum12
-rw-r--r--vendor/golang.org/x/oauth2/google/appengine.go38
-rw-r--r--vendor/golang.org/x/oauth2/google/appengine_gen1.go77
-rw-r--r--vendor/golang.org/x/oauth2/google/appengine_gen2_flex.go27
-rw-r--r--vendor/golang.org/x/oauth2/google/default.go155
-rw-r--r--vendor/golang.org/x/oauth2/google/doc.go40
-rw-r--r--vendor/golang.org/x/oauth2/google/google.go193
-rw-r--r--vendor/golang.org/x/oauth2/google/jwt.go74
-rw-r--r--vendor/golang.org/x/oauth2/google/sdk.go201
-rw-r--r--vendor/golang.org/x/oauth2/internal/client_appengine.go13
-rw-r--r--vendor/golang.org/x/oauth2/internal/doc.go6
-rw-r--r--vendor/golang.org/x/oauth2/internal/oauth2.go37
-rw-r--r--vendor/golang.org/x/oauth2/internal/token.go300
-rw-r--r--vendor/golang.org/x/oauth2/internal/transport.go33
-rw-r--r--vendor/golang.org/x/oauth2/jws/jws.go182
-rw-r--r--vendor/golang.org/x/oauth2/jwt/jwt.go170
-rw-r--r--vendor/golang.org/x/oauth2/oauth2.go381
-rw-r--r--vendor/golang.org/x/oauth2/token.go178
-rw-r--r--vendor/golang.org/x/oauth2/transport.go144
26 files changed, 2378 insertions, 0 deletions
diff --git a/vendor/golang.org/x/oauth2/.travis.yml b/vendor/golang.org/x/oauth2/.travis.yml
new file mode 100644
index 0000000..fa139db
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/.travis.yml
@@ -0,0 +1,13 @@
1language: go
2
3go:
4 - tip
5
6install:
7 - export GOPATH="$HOME/gopath"
8 - mkdir -p "$GOPATH/src/golang.org/x"
9 - mv "$TRAVIS_BUILD_DIR" "$GOPATH/src/golang.org/x/oauth2"
10 - go get -v -t -d golang.org/x/oauth2/...
11
12script:
13 - go test -v golang.org/x/oauth2/...
diff --git a/vendor/golang.org/x/oauth2/AUTHORS b/vendor/golang.org/x/oauth2/AUTHORS
new file mode 100644
index 0000000..15167cd
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/AUTHORS
@@ -0,0 +1,3 @@
1# This source code refers to The Go Authors for copyright purposes.
2# The master list of authors is in the main Go distribution,
3# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/oauth2/CONTRIBUTING.md b/vendor/golang.org/x/oauth2/CONTRIBUTING.md
new file mode 100644
index 0000000..dfbed62
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/CONTRIBUTING.md
@@ -0,0 +1,26 @@
1# Contributing to Go
2
3Go is an open source project.
4
5It is the work of hundreds of contributors. We appreciate your help!
6
7## Filing issues
8
9When [filing an issue](https://github.com/golang/oauth2/issues), make sure to answer these five questions:
10
111. What version of Go are you using (`go version`)?
122. What operating system and processor architecture are you using?
133. What did you do?
144. What did you expect to see?
155. What did you see instead?
16
17General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
18The gophers there will answer or ask you to file an issue if you've tripped over a bug.
19
20## Contributing code
21
22Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
23before sending patches.
24
25Unless otherwise noted, the Go source files are distributed under
26the BSD-style license found in the LICENSE file.
diff --git a/vendor/golang.org/x/oauth2/CONTRIBUTORS b/vendor/golang.org/x/oauth2/CONTRIBUTORS
new file mode 100644
index 0000000..1c4577e
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/CONTRIBUTORS
@@ -0,0 +1,3 @@
1# This source code was written by the Go contributors.
2# The master list of contributors is in the main Go distribution,
3# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/oauth2/LICENSE b/vendor/golang.org/x/oauth2/LICENSE
new file mode 100644
index 0000000..6a66aea
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/LICENSE
@@ -0,0 +1,27 @@
1Copyright (c) 2009 The Go Authors. All rights reserved.
2
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are
5met:
6
7 * Redistributions of source code must retain the above copyright
8notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10copyright notice, this list of conditions and the following disclaimer
11in the documentation and/or other materials provided with the
12distribution.
13 * Neither the name of Google Inc. nor the names of its
14contributors may be used to endorse or promote products derived from
15this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/oauth2/README.md b/vendor/golang.org/x/oauth2/README.md
new file mode 100644
index 0000000..0f443e6
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/README.md
@@ -0,0 +1,35 @@
1# OAuth2 for Go
2
3[![Build Status](https://travis-ci.org/golang/oauth2.svg?branch=master)](https://travis-ci.org/golang/oauth2)
4[![GoDoc](https://godoc.org/golang.org/x/oauth2?status.svg)](https://godoc.org/golang.org/x/oauth2)
5
6oauth2 package contains a client implementation for OAuth 2.0 spec.
7
8## Installation
9
10~~~~
11go get golang.org/x/oauth2
12~~~~
13
14Or you can manually git clone the repository to
15`$(go env GOPATH)/src/golang.org/x/oauth2`.
16
17See godoc for further documentation and examples.
18
19* [godoc.org/golang.org/x/oauth2](http://godoc.org/golang.org/x/oauth2)
20* [godoc.org/golang.org/x/oauth2/google](http://godoc.org/golang.org/x/oauth2/google)
21
22## Policy for new packages
23
24We no longer accept new provider-specific packages in this repo. For
25defining provider endpoints and provider-specific OAuth2 behavior, we
26encourage you to create packages elsewhere. We'll keep the existing
27packages for compatibility.
28
29## Report Issues / Send Patches
30
31This repository uses Gerrit for code changes. To learn how to submit changes to
32this repository, see https://golang.org/doc/contribute.html.
33
34The main issue tracker for the oauth2 repository is located at
35https://github.com/golang/oauth2/issues.
diff --git a/vendor/golang.org/x/oauth2/go.mod b/vendor/golang.org/x/oauth2/go.mod
new file mode 100644
index 0000000..b345781
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/go.mod
@@ -0,0 +1,10 @@
1module golang.org/x/oauth2
2
3go 1.11
4
5require (
6 cloud.google.com/go v0.34.0
7 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e
8 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
9 google.golang.org/appengine v1.4.0
10)
diff --git a/vendor/golang.org/x/oauth2/go.sum b/vendor/golang.org/x/oauth2/go.sum
new file mode 100644
index 0000000..6f0079b
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/go.sum
@@ -0,0 +1,12 @@
1cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
2cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
3github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
4github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
5golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
6golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
7golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
8golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
9golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
10golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
11google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
12google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
diff --git a/vendor/golang.org/x/oauth2/google/appengine.go b/vendor/golang.org/x/oauth2/google/appengine.go
new file mode 100644
index 0000000..feb1157
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/google/appengine.go
@@ -0,0 +1,38 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package google
6
7import (
8 "context"
9 "time"
10
11 "golang.org/x/oauth2"
12)
13
14// Set at init time by appengine_gen1.go. If nil, we're not on App Engine standard first generation (<= Go 1.9) or App Engine flexible.
15var appengineTokenFunc func(c context.Context, scopes ...string) (token string, expiry time.Time, err error)
16
17// Set at init time by appengine_gen1.go. If nil, we're not on App Engine standard first generation (<= Go 1.9) or App Engine flexible.
18var appengineAppIDFunc func(c context.Context) string
19
20// AppEngineTokenSource returns a token source that fetches tokens from either
21// the current application's service account or from the metadata server,
22// depending on the App Engine environment. See below for environment-specific
23// details. If you are implementing a 3-legged OAuth 2.0 flow on App Engine that
24// involves user accounts, see oauth2.Config instead.
25//
26// First generation App Engine runtimes (<= Go 1.9):
27// AppEngineTokenSource returns a token source that fetches tokens issued to the
28// current App Engine application's service account. The provided context must have
29// come from appengine.NewContext.
30//
31// Second generation App Engine runtimes (>= Go 1.11) and App Engine flexible:
32// AppEngineTokenSource is DEPRECATED on second generation runtimes and on the
33// flexible environment. It delegates to ComputeTokenSource, and the provided
34// context and scopes are not used. Please use DefaultTokenSource (or ComputeTokenSource,
35// which DefaultTokenSource will use in this case) instead.
36func AppEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource {
37 return appEngineTokenSource(ctx, scope...)
38}
diff --git a/vendor/golang.org/x/oauth2/google/appengine_gen1.go b/vendor/golang.org/x/oauth2/google/appengine_gen1.go
new file mode 100644
index 0000000..83dacac
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/google/appengine_gen1.go
@@ -0,0 +1,77 @@
1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build appengine
6
7// This file applies to App Engine first generation runtimes (<= Go 1.9).
8
9package google
10
11import (
12 "context"
13 "sort"
14 "strings"
15 "sync"
16
17 "golang.org/x/oauth2"
18 "google.golang.org/appengine"
19)
20
21func init() {
22 appengineTokenFunc = appengine.AccessToken
23 appengineAppIDFunc = appengine.AppID
24}
25
26// See comment on AppEngineTokenSource in appengine.go.
27func appEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource {
28 scopes := append([]string{}, scope...)
29 sort.Strings(scopes)
30 return &gaeTokenSource{
31 ctx: ctx,
32 scopes: scopes,
33 key: strings.Join(scopes, " "),
34 }
35}
36
37// aeTokens helps the fetched tokens to be reused until their expiration.
38var (
39 aeTokensMu sync.Mutex
40 aeTokens = make(map[string]*tokenLock) // key is space-separated scopes
41)
42
43type tokenLock struct {
44 mu sync.Mutex // guards t; held while fetching or updating t
45 t *oauth2.Token
46}
47
48type gaeTokenSource struct {
49 ctx context.Context
50 scopes []string
51 key string // to aeTokens map; space-separated scopes
52}
53
54func (ts *gaeTokenSource) Token() (*oauth2.Token, error) {
55 aeTokensMu.Lock()
56 tok, ok := aeTokens[ts.key]
57 if !ok {
58 tok = &tokenLock{}
59 aeTokens[ts.key] = tok
60 }
61 aeTokensMu.Unlock()
62
63 tok.mu.Lock()
64 defer tok.mu.Unlock()
65 if tok.t.Valid() {
66 return tok.t, nil
67 }
68 access, exp, err := appengineTokenFunc(ts.ctx, ts.scopes...)
69 if err != nil {
70 return nil, err
71 }
72 tok.t = &oauth2.Token{
73 AccessToken: access,
74 Expiry: exp,
75 }
76 return tok.t, nil
77}
diff --git a/vendor/golang.org/x/oauth2/google/appengine_gen2_flex.go b/vendor/golang.org/x/oauth2/google/appengine_gen2_flex.go
new file mode 100644
index 0000000..04c2c22
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/google/appengine_gen2_flex.go
@@ -0,0 +1,27 @@
1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build !appengine
6
7// This file applies to App Engine second generation runtimes (>= Go 1.11) and App Engine flexible.
8
9package google
10
11import (
12 "context"
13 "log"
14 "sync"
15
16 "golang.org/x/oauth2"
17)
18
19var logOnce sync.Once // only spam about deprecation once
20
21// See comment on AppEngineTokenSource in appengine.go.
22func appEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource {
23 logOnce.Do(func() {
24 log.Print("google: AppEngineTokenSource is deprecated on App Engine standard second generation runtimes (>= Go 1.11) and App Engine flexible. Please use DefaultTokenSource or ComputeTokenSource.")
25 })
26 return ComputeTokenSource("")
27}
diff --git a/vendor/golang.org/x/oauth2/google/default.go b/vendor/golang.org/x/oauth2/google/default.go
new file mode 100644
index 0000000..5087d84
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/google/default.go
@@ -0,0 +1,155 @@
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package google
6
7import (
8 "context"
9 "encoding/json"
10 "fmt"
11 "io/ioutil"
12 "net/http"
13 "os"
14 "path/filepath"
15 "runtime"
16
17 "cloud.google.com/go/compute/metadata"
18 "golang.org/x/oauth2"
19)
20
21// Credentials holds Google credentials, including "Application Default Credentials".
22// For more details, see:
23// https://developers.google.com/accounts/docs/application-default-credentials
24type Credentials struct {
25 ProjectID string // may be empty
26 TokenSource oauth2.TokenSource
27
28 // JSON contains the raw bytes from a JSON credentials file.
29 // This field may be nil if authentication is provided by the
30 // environment and not with a credentials file, e.g. when code is
31 // running on Google Cloud Platform.
32 JSON []byte
33}
34
35// DefaultCredentials is the old name of Credentials.
36//
37// Deprecated: use Credentials instead.
38type DefaultCredentials = Credentials
39
40// DefaultClient returns an HTTP Client that uses the
41// DefaultTokenSource to obtain authentication credentials.
42func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
43 ts, err := DefaultTokenSource(ctx, scope...)
44 if err != nil {
45 return nil, err
46 }
47 return oauth2.NewClient(ctx, ts), nil
48}
49
50// DefaultTokenSource returns the token source for
51// "Application Default Credentials".
52// It is a shortcut for FindDefaultCredentials(ctx, scope).TokenSource.
53func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSource, error) {
54 creds, err := FindDefaultCredentials(ctx, scope...)
55 if err != nil {
56 return nil, err
57 }
58 return creds.TokenSource, nil
59}
60
61// FindDefaultCredentials searches for "Application Default Credentials".
62//
63// It looks for credentials in the following places,
64// preferring the first location found:
65//
66// 1. A JSON file whose path is specified by the
67// GOOGLE_APPLICATION_CREDENTIALS environment variable.
68// 2. A JSON file in a location known to the gcloud command-line tool.
69// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
70// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
71// 3. On Google App Engine standard first generation runtimes (<= Go 1.9) it uses
72// the appengine.AccessToken function.
73// 4. On Google Compute Engine, Google App Engine standard second generation runtimes
74// (>= Go 1.11), and Google App Engine flexible environment, it fetches
75// credentials from the metadata server.
76// (In this final case any provided scopes are ignored.)
77func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials, error) {
78 // First, try the environment variable.
79 const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
80 if filename := os.Getenv(envVar); filename != "" {
81 creds, err := readCredentialsFile(ctx, filename, scopes)
82 if err != nil {
83 return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err)
84 }
85 return creds, nil
86 }
87
88 // Second, try a well-known file.
89 filename := wellKnownFile()
90 if creds, err := readCredentialsFile(ctx, filename, scopes); err == nil {
91 return creds, nil
92 } else if !os.IsNotExist(err) {
93 return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err)
94 }
95
96 // Third, if we're on a Google App Engine standard first generation runtime (<= Go 1.9)
97 // use those credentials. App Engine standard second generation runtimes (>= Go 1.11)
98 // and App Engine flexible use ComputeTokenSource and the metadata server.
99 if appengineTokenFunc != nil {
100 return &DefaultCredentials{
101 ProjectID: appengineAppIDFunc(ctx),
102 TokenSource: AppEngineTokenSource(ctx, scopes...),
103 }, nil
104 }
105
106 // Fourth, if we're on Google Compute Engine, an App Engine standard second generation runtime,
107 // or App Engine flexible, use the metadata server.
108 if metadata.OnGCE() {
109 id, _ := metadata.ProjectID()
110 return &DefaultCredentials{
111 ProjectID: id,
112 TokenSource: ComputeTokenSource(""),
113 }, nil
114 }
115
116 // None are found; return helpful error.
117 const url = "https://developers.google.com/accounts/docs/application-default-credentials"
118 return nil, fmt.Errorf("google: could not find default credentials. See %v for more information.", url)
119}
120
121// CredentialsFromJSON obtains Google credentials from a JSON value. The JSON can
122// represent either a Google Developers Console client_credentials.json file (as in
123// ConfigFromJSON) or a Google Developers service account key file (as in
124// JWTConfigFromJSON).
125func CredentialsFromJSON(ctx context.Context, jsonData []byte, scopes ...string) (*Credentials, error) {
126 var f credentialsFile
127 if err := json.Unmarshal(jsonData, &f); err != nil {
128 return nil, err
129 }
130 ts, err := f.tokenSource(ctx, append([]string(nil), scopes...))
131 if err != nil {
132 return nil, err
133 }
134 return &DefaultCredentials{
135 ProjectID: f.ProjectID,
136 TokenSource: ts,
137 JSON: jsonData,
138 }, nil
139}
140
141func wellKnownFile() string {
142 const f = "application_default_credentials.json"
143 if runtime.GOOS == "windows" {
144 return filepath.Join(os.Getenv("APPDATA"), "gcloud", f)
145 }
146 return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", f)
147}
148
149func readCredentialsFile(ctx context.Context, filename string, scopes []string) (*DefaultCredentials, error) {
150 b, err := ioutil.ReadFile(filename)
151 if err != nil {
152 return nil, err
153 }
154 return CredentialsFromJSON(ctx, b, scopes...)
155}
diff --git a/vendor/golang.org/x/oauth2/google/doc.go b/vendor/golang.org/x/oauth2/google/doc.go
new file mode 100644
index 0000000..73be629
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/google/doc.go
@@ -0,0 +1,40 @@
1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package google provides support for making OAuth2 authorized and authenticated
6// HTTP requests to Google APIs. It supports the Web server flow, client-side
7// credentials, service accounts, Google Compute Engine service accounts, and Google
8// App Engine service accounts.
9//
10// A brief overview of the package follows. For more information, please read
11// https://developers.google.com/accounts/docs/OAuth2
12// and
13// https://developers.google.com/accounts/docs/application-default-credentials.
14//
15// OAuth2 Configs
16//
17// Two functions in this package return golang.org/x/oauth2.Config values from Google credential
18// data. Google supports two JSON formats for OAuth2 credentials: one is handled by ConfigFromJSON,
19// the other by JWTConfigFromJSON. The returned Config can be used to obtain a TokenSource or
20// create an http.Client.
21//
22//
23// Credentials
24//
25// The Credentials type represents Google credentials, including Application Default
26// Credentials.
27//
28// Use FindDefaultCredentials to obtain Application Default Credentials.
29// FindDefaultCredentials looks in some well-known places for a credentials file, and
30// will call AppEngineTokenSource or ComputeTokenSource as needed.
31//
32// DefaultClient and DefaultTokenSource are convenience methods. They first call FindDefaultCredentials,
33// then use the credentials to construct an http.Client or an oauth2.TokenSource.
34//
35// Use CredentialsFromJSON to obtain credentials from either of the two JSON formats
36// described in OAuth2 Configs, above. The TokenSource in the returned value is the
37// same as the one obtained from the oauth2.Config returned from ConfigFromJSON or
38// JWTConfigFromJSON, but the Credentials may contain additional information
39// that is useful is some circumstances.
40package google // import "golang.org/x/oauth2/google"
diff --git a/vendor/golang.org/x/oauth2/google/google.go b/vendor/golang.org/x/oauth2/google/google.go
new file mode 100644
index 0000000..4b0b547
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/google/google.go
@@ -0,0 +1,193 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package google
6
7import (
8 "context"
9 "encoding/json"
10 "errors"
11 "fmt"
12 "strings"
13 "time"
14
15 "cloud.google.com/go/compute/metadata"
16 "golang.org/x/oauth2"
17 "golang.org/x/oauth2/jwt"
18)
19
20// Endpoint is Google's OAuth 2.0 endpoint.
21var Endpoint = oauth2.Endpoint{
22 AuthURL: "https://accounts.google.com/o/oauth2/auth",
23 TokenURL: "https://accounts.google.com/o/oauth2/token",
24 AuthStyle: oauth2.AuthStyleInParams,
25}
26
27// JWTTokenURL is Google's OAuth 2.0 token URL to use with the JWT flow.
28const JWTTokenURL = "https://accounts.google.com/o/oauth2/token"
29
30// ConfigFromJSON uses a Google Developers Console client_credentials.json
31// file to construct a config.
32// client_credentials.json can be downloaded from
33// https://console.developers.google.com, under "Credentials". Download the Web
34// application credentials in the JSON format and provide the contents of the
35// file as jsonKey.
36func ConfigFromJSON(jsonKey []byte, scope ...string) (*oauth2.Config, error) {
37 type cred struct {
38 ClientID string `json:"client_id"`
39 ClientSecret string `json:"client_secret"`
40 RedirectURIs []string `json:"redirect_uris"`
41 AuthURI string `json:"auth_uri"`
42 TokenURI string `json:"token_uri"`
43 }
44 var j struct {
45 Web *cred `json:"web"`
46 Installed *cred `json:"installed"`
47 }
48 if err := json.Unmarshal(jsonKey, &j); err != nil {
49 return nil, err
50 }
51 var c *cred
52 switch {
53 case j.Web != nil:
54 c = j.Web
55 case j.Installed != nil:
56 c = j.Installed
57 default:
58 return nil, fmt.Errorf("oauth2/google: no credentials found")
59 }
60 if len(c.RedirectURIs) < 1 {
61 return nil, errors.New("oauth2/google: missing redirect URL in the client_credentials.json")
62 }
63 return &oauth2.Config{
64 ClientID: c.ClientID,
65 ClientSecret: c.ClientSecret,
66 RedirectURL: c.RedirectURIs[0],
67 Scopes: scope,
68 Endpoint: oauth2.Endpoint{
69 AuthURL: c.AuthURI,
70 TokenURL: c.TokenURI,
71 },
72 }, nil
73}
74
75// JWTConfigFromJSON uses a Google Developers service account JSON key file to read
76// the credentials that authorize and authenticate the requests.
77// Create a service account on "Credentials" for your project at
78// https://console.developers.google.com to download a JSON key file.
79func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) {
80 var f credentialsFile
81 if err := json.Unmarshal(jsonKey, &f); err != nil {
82 return nil, err
83 }
84 if f.Type != serviceAccountKey {
85 return nil, fmt.Errorf("google: read JWT from JSON credentials: 'type' field is %q (expected %q)", f.Type, serviceAccountKey)
86 }
87 scope = append([]string(nil), scope...) // copy
88 return f.jwtConfig(scope), nil
89}
90
91// JSON key file types.
92const (
93 serviceAccountKey = "service_account"
94 userCredentialsKey = "authorized_user"
95)
96
97// credentialsFile is the unmarshalled representation of a credentials file.
98type credentialsFile struct {
99 Type string `json:"type"` // serviceAccountKey or userCredentialsKey
100
101 // Service Account fields
102 ClientEmail string `json:"client_email"`
103 PrivateKeyID string `json:"private_key_id"`
104 PrivateKey string `json:"private_key"`
105 TokenURL string `json:"token_uri"`
106 ProjectID string `json:"project_id"`
107
108 // User Credential fields
109 // (These typically come from gcloud auth.)
110 ClientSecret string `json:"client_secret"`
111 ClientID string `json:"client_id"`
112 RefreshToken string `json:"refresh_token"`
113}
114
115func (f *credentialsFile) jwtConfig(scopes []string) *jwt.Config {
116 cfg := &jwt.Config{
117 Email: f.ClientEmail,
118 PrivateKey: []byte(f.PrivateKey),
119 PrivateKeyID: f.PrivateKeyID,
120 Scopes: scopes,
121 TokenURL: f.TokenURL,
122 }
123 if cfg.TokenURL == "" {
124 cfg.TokenURL = JWTTokenURL
125 }
126 return cfg
127}
128
129func (f *credentialsFile) tokenSource(ctx context.Context, scopes []string) (oauth2.TokenSource, error) {
130 switch f.Type {
131 case serviceAccountKey:
132 cfg := f.jwtConfig(scopes)
133 return cfg.TokenSource(ctx), nil
134 case userCredentialsKey:
135 cfg := &oauth2.Config{
136 ClientID: f.ClientID,
137 ClientSecret: f.ClientSecret,
138 Scopes: scopes,
139 Endpoint: Endpoint,
140 }
141 tok := &oauth2.Token{RefreshToken: f.RefreshToken}
142 return cfg.TokenSource(ctx, tok), nil
143 case "":
144 return nil, errors.New("missing 'type' field in credentials")
145 default:
146 return nil, fmt.Errorf("unknown credential type: %q", f.Type)
147 }
148}
149
150// ComputeTokenSource returns a token source that fetches access tokens
151// from Google Compute Engine (GCE)'s metadata server. It's only valid to use
152// this token source if your program is running on a GCE instance.
153// If no account is specified, "default" is used.
154// Further information about retrieving access tokens from the GCE metadata
155// server can be found at https://cloud.google.com/compute/docs/authentication.
156func ComputeTokenSource(account string) oauth2.TokenSource {
157 return oauth2.ReuseTokenSource(nil, computeSource{account: account})
158}
159
160type computeSource struct {
161 account string
162}
163
164func (cs computeSource) Token() (*oauth2.Token, error) {
165 if !metadata.OnGCE() {
166 return nil, errors.New("oauth2/google: can't get a token from the metadata service; not running on GCE")
167 }
168 acct := cs.account
169 if acct == "" {
170 acct = "default"
171 }
172 tokenJSON, err := metadata.Get("instance/service-accounts/" + acct + "/token")
173 if err != nil {
174 return nil, err
175 }
176 var res struct {
177 AccessToken string `json:"access_token"`
178 ExpiresInSec int `json:"expires_in"`
179 TokenType string `json:"token_type"`
180 }
181 err = json.NewDecoder(strings.NewReader(tokenJSON)).Decode(&res)
182 if err != nil {
183 return nil, fmt.Errorf("oauth2/google: invalid token JSON from metadata: %v", err)
184 }
185 if res.ExpiresInSec == 0 || res.AccessToken == "" {
186 return nil, fmt.Errorf("oauth2/google: incomplete token received from metadata")
187 }
188 return &oauth2.Token{
189 AccessToken: res.AccessToken,
190 TokenType: res.TokenType,
191 Expiry: time.Now().Add(time.Duration(res.ExpiresInSec) * time.Second),
192 }, nil
193}
diff --git a/vendor/golang.org/x/oauth2/google/jwt.go b/vendor/golang.org/x/oauth2/google/jwt.go
new file mode 100644
index 0000000..b0fdb3a
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/google/jwt.go
@@ -0,0 +1,74 @@
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package google
6
7import (
8 "crypto/rsa"
9 "fmt"
10 "time"
11
12 "golang.org/x/oauth2"
13 "golang.org/x/oauth2/internal"
14 "golang.org/x/oauth2/jws"
15)
16
17// JWTAccessTokenSourceFromJSON uses a Google Developers service account JSON
18// key file to read the credentials that authorize and authenticate the
19// requests, and returns a TokenSource that does not use any OAuth2 flow but
20// instead creates a JWT and sends that as the access token.
21// The audience is typically a URL that specifies the scope of the credentials.
22//
23// Note that this is not a standard OAuth flow, but rather an
24// optimization supported by a few Google services.
25// Unless you know otherwise, you should use JWTConfigFromJSON instead.
26func JWTAccessTokenSourceFromJSON(jsonKey []byte, audience string) (oauth2.TokenSource, error) {
27 cfg, err := JWTConfigFromJSON(jsonKey)
28 if err != nil {
29 return nil, fmt.Errorf("google: could not parse JSON key: %v", err)
30 }
31 pk, err := internal.ParseKey(cfg.PrivateKey)
32 if err != nil {
33 return nil, fmt.Errorf("google: could not parse key: %v", err)
34 }
35 ts := &jwtAccessTokenSource{
36 email: cfg.Email,
37 audience: audience,
38 pk: pk,
39 pkID: cfg.PrivateKeyID,
40 }
41 tok, err := ts.Token()
42 if err != nil {
43 return nil, err
44 }
45 return oauth2.ReuseTokenSource(tok, ts), nil
46}
47
48type jwtAccessTokenSource struct {
49 email, audience string
50 pk *rsa.PrivateKey
51 pkID string
52}
53
54func (ts *jwtAccessTokenSource) Token() (*oauth2.Token, error) {
55 iat := time.Now()
56 exp := iat.Add(time.Hour)
57 cs := &jws.ClaimSet{
58 Iss: ts.email,
59 Sub: ts.email,
60 Aud: ts.audience,
61 Iat: iat.Unix(),
62 Exp: exp.Unix(),
63 }
64 hdr := &jws.Header{
65 Algorithm: "RS256",
66 Typ: "JWT",
67 KeyID: string(ts.pkID),
68 }
69 msg, err := jws.Encode(hdr, cs, ts.pk)
70 if err != nil {
71 return nil, fmt.Errorf("google: could not encode JWT: %v", err)
72 }
73 return &oauth2.Token{AccessToken: msg, TokenType: "Bearer", Expiry: exp}, nil
74}
diff --git a/vendor/golang.org/x/oauth2/google/sdk.go b/vendor/golang.org/x/oauth2/google/sdk.go
new file mode 100644
index 0000000..456224b
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/google/sdk.go
@@ -0,0 +1,201 @@
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package google
6
7import (
8 "bufio"
9 "context"
10 "encoding/json"
11 "errors"
12 "fmt"
13 "io"
14 "net/http"
15 "os"
16 "os/user"
17 "path/filepath"
18 "runtime"
19 "strings"
20 "time"
21
22 "golang.org/x/oauth2"
23)
24
25type sdkCredentials struct {
26 Data []struct {
27 Credential struct {
28 ClientID string `json:"client_id"`
29 ClientSecret string `json:"client_secret"`
30 AccessToken string `json:"access_token"`
31 RefreshToken string `json:"refresh_token"`
32 TokenExpiry *time.Time `json:"token_expiry"`
33 } `json:"credential"`
34 Key struct {
35 Account string `json:"account"`
36 Scope string `json:"scope"`
37 } `json:"key"`
38 }
39}
40
41// An SDKConfig provides access to tokens from an account already
42// authorized via the Google Cloud SDK.
43type SDKConfig struct {
44 conf oauth2.Config
45 initialToken *oauth2.Token
46}
47
48// NewSDKConfig creates an SDKConfig for the given Google Cloud SDK
49// account. If account is empty, the account currently active in
50// Google Cloud SDK properties is used.
51// Google Cloud SDK credentials must be created by running `gcloud auth`
52// before using this function.
53// The Google Cloud SDK is available at https://cloud.google.com/sdk/.
54func NewSDKConfig(account string) (*SDKConfig, error) {
55 configPath, err := sdkConfigPath()
56 if err != nil {
57 return nil, fmt.Errorf("oauth2/google: error getting SDK config path: %v", err)
58 }
59 credentialsPath := filepath.Join(configPath, "credentials")
60 f, err := os.Open(credentialsPath)
61 if err != nil {
62 return nil, fmt.Errorf("oauth2/google: failed to load SDK credentials: %v", err)
63 }
64 defer f.Close()
65
66 var c sdkCredentials
67 if err := json.NewDecoder(f).Decode(&c); err != nil {
68 return nil, fmt.Errorf("oauth2/google: failed to decode SDK credentials from %q: %v", credentialsPath, err)
69 }
70 if len(c.Data) == 0 {
71 return nil, fmt.Errorf("oauth2/google: no credentials found in %q, run `gcloud auth login` to create one", credentialsPath)
72 }
73 if account == "" {
74 propertiesPath := filepath.Join(configPath, "properties")
75 f, err := os.Open(propertiesPath)
76 if err != nil {
77 return nil, fmt.Errorf("oauth2/google: failed to load SDK properties: %v", err)
78 }
79 defer f.Close()
80 ini, err := parseINI(f)
81 if err != nil {
82 return nil, fmt.Errorf("oauth2/google: failed to parse SDK properties %q: %v", propertiesPath, err)
83 }
84 core, ok := ini["core"]
85 if !ok {
86 return nil, fmt.Errorf("oauth2/google: failed to find [core] section in %v", ini)
87 }
88 active, ok := core["account"]
89 if !ok {
90 return nil, fmt.Errorf("oauth2/google: failed to find %q attribute in %v", "account", core)
91 }
92 account = active
93 }
94
95 for _, d := range c.Data {
96 if account == "" || d.Key.Account == account {
97 if d.Credential.AccessToken == "" && d.Credential.RefreshToken == "" {
98 return nil, fmt.Errorf("oauth2/google: no token available for account %q", account)
99 }
100 var expiry time.Time
101 if d.Credential.TokenExpiry != nil {
102 expiry = *d.Credential.TokenExpiry
103 }
104 return &SDKConfig{
105 conf: oauth2.Config{
106 ClientID: d.Credential.ClientID,
107 ClientSecret: d.Credential.ClientSecret,
108 Scopes: strings.Split(d.Key.Scope, " "),
109 Endpoint: Endpoint,
110 RedirectURL: "oob",
111 },
112 initialToken: &oauth2.Token{
113 AccessToken: d.Credential.AccessToken,
114 RefreshToken: d.Credential.RefreshToken,
115 Expiry: expiry,
116 },
117 }, nil
118 }
119 }
120 return nil, fmt.Errorf("oauth2/google: no such credentials for account %q", account)
121}
122
123// Client returns an HTTP client using Google Cloud SDK credentials to
124// authorize requests. The token will auto-refresh as necessary. The
125// underlying http.RoundTripper will be obtained using the provided
126// context. The returned client and its Transport should not be
127// modified.
128func (c *SDKConfig) Client(ctx context.Context) *http.Client {
129 return &http.Client{
130 Transport: &oauth2.Transport{
131 Source: c.TokenSource(ctx),
132 },
133 }
134}
135
136// TokenSource returns an oauth2.TokenSource that retrieve tokens from
137// Google Cloud SDK credentials using the provided context.
138// It will returns the current access token stored in the credentials,
139// and refresh it when it expires, but it won't update the credentials
140// with the new access token.
141func (c *SDKConfig) TokenSource(ctx context.Context) oauth2.TokenSource {
142 return c.conf.TokenSource(ctx, c.initialToken)
143}
144
145// Scopes are the OAuth 2.0 scopes the current account is authorized for.
146func (c *SDKConfig) Scopes() []string {
147 return c.conf.Scopes
148}
149
150func parseINI(ini io.Reader) (map[string]map[string]string, error) {
151 result := map[string]map[string]string{
152 "": {}, // root section
153 }
154 scanner := bufio.NewScanner(ini)
155 currentSection := ""
156 for scanner.Scan() {
157 line := strings.TrimSpace(scanner.Text())
158 if strings.HasPrefix(line, ";") {
159 // comment.
160 continue
161 }
162 if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
163 currentSection = strings.TrimSpace(line[1 : len(line)-1])
164 result[currentSection] = map[string]string{}
165 continue
166 }
167 parts := strings.SplitN(line, "=", 2)
168 if len(parts) == 2 && parts[0] != "" {
169 result[currentSection][strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
170 }
171 }
172 if err := scanner.Err(); err != nil {
173 return nil, fmt.Errorf("error scanning ini: %v", err)
174 }
175 return result, nil
176}
177
178// sdkConfigPath tries to guess where the gcloud config is located.
179// It can be overridden during tests.
180var sdkConfigPath = func() (string, error) {
181 if runtime.GOOS == "windows" {
182 return filepath.Join(os.Getenv("APPDATA"), "gcloud"), nil
183 }
184 homeDir := guessUnixHomeDir()
185 if homeDir == "" {
186 return "", errors.New("unable to get current user home directory: os/user lookup failed; $HOME is empty")
187 }
188 return filepath.Join(homeDir, ".config", "gcloud"), nil
189}
190
191func guessUnixHomeDir() string {
192 // Prefer $HOME over user.Current due to glibc bug: golang.org/issue/13470
193 if v := os.Getenv("HOME"); v != "" {
194 return v
195 }
196 // Else, fall back to user.Current:
197 if u, err := user.Current(); err == nil {
198 return u.HomeDir
199 }
200 return ""
201}
diff --git a/vendor/golang.org/x/oauth2/internal/client_appengine.go b/vendor/golang.org/x/oauth2/internal/client_appengine.go
new file mode 100644
index 0000000..7434871
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/internal/client_appengine.go
@@ -0,0 +1,13 @@
1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build appengine
6
7package internal
8
9import "google.golang.org/appengine/urlfetch"
10
11func init() {
12 appengineClientHook = urlfetch.Client
13}
diff --git a/vendor/golang.org/x/oauth2/internal/doc.go b/vendor/golang.org/x/oauth2/internal/doc.go
new file mode 100644
index 0000000..03265e8
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/internal/doc.go
@@ -0,0 +1,6 @@
1// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package internal contains support packages for oauth2 package.
6package internal
diff --git a/vendor/golang.org/x/oauth2/internal/oauth2.go b/vendor/golang.org/x/oauth2/internal/oauth2.go
new file mode 100644
index 0000000..c0ab196
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/internal/oauth2.go
@@ -0,0 +1,37 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package internal
6
7import (
8 "crypto/rsa"
9 "crypto/x509"
10 "encoding/pem"
11 "errors"
12 "fmt"
13)
14
15// ParseKey converts the binary contents of a private key file
16// to an *rsa.PrivateKey. It detects whether the private key is in a
17// PEM container or not. If so, it extracts the the private key
18// from PEM container before conversion. It only supports PEM
19// containers with no passphrase.
20func ParseKey(key []byte) (*rsa.PrivateKey, error) {
21 block, _ := pem.Decode(key)
22 if block != nil {
23 key = block.Bytes
24 }
25 parsedKey, err := x509.ParsePKCS8PrivateKey(key)
26 if err != nil {
27 parsedKey, err = x509.ParsePKCS1PrivateKey(key)
28 if err != nil {
29 return nil, fmt.Errorf("private key should be a PEM or plain PKCS1 or PKCS8; parse error: %v", err)
30 }
31 }
32 parsed, ok := parsedKey.(*rsa.PrivateKey)
33 if !ok {
34 return nil, errors.New("private key is invalid")
35 }
36 return parsed, nil
37}
diff --git a/vendor/golang.org/x/oauth2/internal/token.go b/vendor/golang.org/x/oauth2/internal/token.go
new file mode 100644
index 0000000..955d5a0
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/internal/token.go
@@ -0,0 +1,300 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package internal
6
7import (
8 "context"
9 "encoding/json"
10 "errors"
11 "fmt"
12 "io"
13 "io/ioutil"
14 "mime"
15 "net/http"
16 "net/url"
17 "strconv"
18 "strings"
19 "sync"
20 "time"
21
22 "golang.org/x/net/context/ctxhttp"
23)
24
25// Token represents the credentials used to authorize
26// the requests to access protected resources on the OAuth 2.0
27// provider's backend.
28//
29// This type is a mirror of oauth2.Token and exists to break
30// an otherwise-circular dependency. Other internal packages
31// should convert this Token into an oauth2.Token before use.
32type Token struct {
33 // AccessToken is the token that authorizes and authenticates
34 // the requests.
35 AccessToken string
36
37 // TokenType is the type of token.
38 // The Type method returns either this or "Bearer", the default.
39 TokenType string
40
41 // RefreshToken is a token that's used by the application
42 // (as opposed to the user) to refresh the access token
43 // if it expires.
44 RefreshToken string
45
46 // Expiry is the optional expiration time of the access token.
47 //
48 // If zero, TokenSource implementations will reuse the same
49 // token forever and RefreshToken or equivalent
50 // mechanisms for that TokenSource will not be used.
51 Expiry time.Time
52
53 // Raw optionally contains extra metadata from the server
54 // when updating a token.
55 Raw interface{}
56}
57
58// tokenJSON is the struct representing the HTTP response from OAuth2
59// providers returning a token in JSON form.
60type tokenJSON struct {
61 AccessToken string `json:"access_token"`
62 TokenType string `json:"token_type"`
63 RefreshToken string `json:"refresh_token"`
64 ExpiresIn expirationTime `json:"expires_in"` // at least PayPal returns string, while most return number
65 Expires expirationTime `json:"expires"` // broken Facebook spelling of expires_in
66}
67
68func (e *tokenJSON) expiry() (t time.Time) {
69 if v := e.ExpiresIn; v != 0 {
70 return time.Now().Add(time.Duration(v) * time.Second)
71 }
72 if v := e.Expires; v != 0 {
73 return time.Now().Add(time.Duration(v) * time.Second)
74 }
75 return
76}
77
78type expirationTime int32
79
80func (e *expirationTime) UnmarshalJSON(b []byte) error {
81 if len(b) == 0 || string(b) == "null" {
82 return nil
83 }
84 var n json.Number
85 err := json.Unmarshal(b, &n)
86 if err != nil {
87 return err
88 }
89 i, err := n.Int64()
90 if err != nil {
91 return err
92 }
93 *e = expirationTime(i)
94 return nil
95}
96
97// RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op.
98//
99// Deprecated: this function no longer does anything. Caller code that
100// wants to avoid potential extra HTTP requests made during
101// auto-probing of the provider's auth style should set
102// Endpoint.AuthStyle.
103func RegisterBrokenAuthHeaderProvider(tokenURL string) {}
104
105// AuthStyle is a copy of the golang.org/x/oauth2 package's AuthStyle type.
106type AuthStyle int
107
108const (
109 AuthStyleUnknown AuthStyle = 0
110 AuthStyleInParams AuthStyle = 1
111 AuthStyleInHeader AuthStyle = 2
112)
113
114// authStyleCache is the set of tokenURLs we've successfully used via
115// RetrieveToken and which style auth we ended up using.
116// It's called a cache, but it doesn't (yet?) shrink. It's expected that
117// the set of OAuth2 servers a program contacts over time is fixed and
118// small.
119var authStyleCache struct {
120 sync.Mutex
121 m map[string]AuthStyle // keyed by tokenURL
122}
123
124// ResetAuthCache resets the global authentication style cache used
125// for AuthStyleUnknown token requests.
126func ResetAuthCache() {
127 authStyleCache.Lock()
128 defer authStyleCache.Unlock()
129 authStyleCache.m = nil
130}
131
132// lookupAuthStyle reports which auth style we last used with tokenURL
133// when calling RetrieveToken and whether we have ever done so.
134func lookupAuthStyle(tokenURL string) (style AuthStyle, ok bool) {
135 authStyleCache.Lock()
136 defer authStyleCache.Unlock()
137 style, ok = authStyleCache.m[tokenURL]
138 return
139}
140
141// setAuthStyle adds an entry to authStyleCache, documented above.
142func setAuthStyle(tokenURL string, v AuthStyle) {
143 authStyleCache.Lock()
144 defer authStyleCache.Unlock()
145 if authStyleCache.m == nil {
146 authStyleCache.m = make(map[string]AuthStyle)
147 }
148 authStyleCache.m[tokenURL] = v
149}
150
151// newTokenRequest returns a new *http.Request to retrieve a new token
152// from tokenURL using the provided clientID, clientSecret, and POST
153// body parameters.
154//
155// inParams is whether the clientID & clientSecret should be encoded
156// as the POST body. An 'inParams' value of true means to send it in
157// the POST body (along with any values in v); false means to send it
158// in the Authorization header.
159func newTokenRequest(tokenURL, clientID, clientSecret string, v url.Values, authStyle AuthStyle) (*http.Request, error) {
160 if authStyle == AuthStyleInParams {
161 v = cloneURLValues(v)
162 if clientID != "" {
163 v.Set("client_id", clientID)
164 }
165 if clientSecret != "" {
166 v.Set("client_secret", clientSecret)
167 }
168 }
169 req, err := http.NewRequest("POST", tokenURL, strings.NewReader(v.Encode()))
170 if err != nil {
171 return nil, err
172 }
173 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
174 if authStyle == AuthStyleInHeader {
175 req.SetBasicAuth(url.QueryEscape(clientID), url.QueryEscape(clientSecret))
176 }
177 return req, nil
178}
179
180func cloneURLValues(v url.Values) url.Values {
181 v2 := make(url.Values, len(v))
182 for k, vv := range v {
183 v2[k] = append([]string(nil), vv...)
184 }
185 return v2
186}
187
188func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values, authStyle AuthStyle) (*Token, error) {
189 needsAuthStyleProbe := authStyle == 0
190 if needsAuthStyleProbe {
191 if style, ok := lookupAuthStyle(tokenURL); ok {
192 authStyle = style
193 needsAuthStyleProbe = false
194 } else {
195 authStyle = AuthStyleInHeader // the first way we'll try
196 }
197 }
198 req, err := newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle)
199 if err != nil {
200 return nil, err
201 }
202 token, err := doTokenRoundTrip(ctx, req)
203 if err != nil && needsAuthStyleProbe {
204 // If we get an error, assume the server wants the
205 // clientID & clientSecret in a different form.
206 // See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
207 // In summary:
208 // - Reddit only accepts client secret in the Authorization header
209 // - Dropbox accepts either it in URL param or Auth header, but not both.
210 // - Google only accepts URL param (not spec compliant?), not Auth header
211 // - Stripe only accepts client secret in Auth header with Bearer method, not Basic
212 //
213 // We used to maintain a big table in this code of all the sites and which way
214 // they went, but maintaining it didn't scale & got annoying.
215 // So just try both ways.
216 authStyle = AuthStyleInParams // the second way we'll try
217 req, _ = newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle)
218 token, err = doTokenRoundTrip(ctx, req)
219 }
220 if needsAuthStyleProbe && err == nil {
221 setAuthStyle(tokenURL, authStyle)
222 }
223 // Don't overwrite `RefreshToken` with an empty value
224 // if this was a token refreshing request.
225 if token != nil && token.RefreshToken == "" {
226 token.RefreshToken = v.Get("refresh_token")
227 }
228 return token, err
229}
230
231func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) {
232 r, err := ctxhttp.Do(ctx, ContextClient(ctx), req)
233 if err != nil {
234 return nil, err
235 }
236 body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20))
237 r.Body.Close()
238 if err != nil {
239 return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
240 }
241 if code := r.StatusCode; code < 200 || code > 299 {
242 return nil, &RetrieveError{
243 Response: r,
244 Body: body,
245 }
246 }
247
248 var token *Token
249 content, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
250 switch content {
251 case "application/x-www-form-urlencoded", "text/plain":
252 vals, err := url.ParseQuery(string(body))
253 if err != nil {
254 return nil, err
255 }
256 token = &Token{
257 AccessToken: vals.Get("access_token"),
258 TokenType: vals.Get("token_type"),
259 RefreshToken: vals.Get("refresh_token"),
260 Raw: vals,
261 }
262 e := vals.Get("expires_in")
263 if e == "" || e == "null" {
264 // TODO(jbd): Facebook's OAuth2 implementation is broken and
265 // returns expires_in field in expires. Remove the fallback to expires,
266 // when Facebook fixes their implementation.
267 e = vals.Get("expires")
268 }
269 expires, _ := strconv.Atoi(e)
270 if expires != 0 {
271 token.Expiry = time.Now().Add(time.Duration(expires) * time.Second)
272 }
273 default:
274 var tj tokenJSON
275 if err = json.Unmarshal(body, &tj); err != nil {
276 return nil, err
277 }
278 token = &Token{
279 AccessToken: tj.AccessToken,
280 TokenType: tj.TokenType,
281 RefreshToken: tj.RefreshToken,
282 Expiry: tj.expiry(),
283 Raw: make(map[string]interface{}),
284 }
285 json.Unmarshal(body, &token.Raw) // no error checks for optional fields
286 }
287 if token.AccessToken == "" {
288 return nil, errors.New("oauth2: server response missing access_token")
289 }
290 return token, nil
291}
292
293type RetrieveError struct {
294 Response *http.Response
295 Body []byte
296}
297
298func (r *RetrieveError) Error() string {
299 return fmt.Sprintf("oauth2: cannot fetch token: %v\nResponse: %s", r.Response.Status, r.Body)
300}
diff --git a/vendor/golang.org/x/oauth2/internal/transport.go b/vendor/golang.org/x/oauth2/internal/transport.go
new file mode 100644
index 0000000..572074a
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/internal/transport.go
@@ -0,0 +1,33 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package internal
6
7import (
8 "context"
9 "net/http"
10)
11
12// HTTPClient is the context key to use with golang.org/x/net/context's
13// WithValue function to associate an *http.Client value with a context.
14var HTTPClient ContextKey
15
16// ContextKey is just an empty struct. It exists so HTTPClient can be
17// an immutable public variable with a unique type. It's immutable
18// because nobody else can create a ContextKey, being unexported.
19type ContextKey struct{}
20
21var appengineClientHook func(context.Context) *http.Client
22
23func ContextClient(ctx context.Context) *http.Client {
24 if ctx != nil {
25 if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok {
26 return hc
27 }
28 }
29 if appengineClientHook != nil {
30 return appengineClientHook(ctx)
31 }
32 return http.DefaultClient
33}
diff --git a/vendor/golang.org/x/oauth2/jws/jws.go b/vendor/golang.org/x/oauth2/jws/jws.go
new file mode 100644
index 0000000..683d2d2
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/jws/jws.go
@@ -0,0 +1,182 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package jws provides a partial implementation
6// of JSON Web Signature encoding and decoding.
7// It exists to support the golang.org/x/oauth2 package.
8//
9// See RFC 7515.
10//
11// Deprecated: this package is not intended for public use and might be
12// removed in the future. It exists for internal use only.
13// Please switch to another JWS package or copy this package into your own
14// source tree.
15package jws // import "golang.org/x/oauth2/jws"
16
17import (
18 "bytes"
19 "crypto"
20 "crypto/rand"
21 "crypto/rsa"
22 "crypto/sha256"
23 "encoding/base64"
24 "encoding/json"
25 "errors"
26 "fmt"
27 "strings"
28 "time"
29)
30
31// ClaimSet contains information about the JWT signature including the
32// permissions being requested (scopes), the target of the token, the issuer,
33// the time the token was issued, and the lifetime of the token.
34type ClaimSet struct {
35 Iss string `json:"iss"` // email address of the client_id of the application making the access token request
36 Scope string `json:"scope,omitempty"` // space-delimited list of the permissions the application requests
37 Aud string `json:"aud"` // descriptor of the intended target of the assertion (Optional).
38 Exp int64 `json:"exp"` // the expiration time of the assertion (seconds since Unix epoch)
39 Iat int64 `json:"iat"` // the time the assertion was issued (seconds since Unix epoch)
40 Typ string `json:"typ,omitempty"` // token type (Optional).
41
42 // Email for which the application is requesting delegated access (Optional).
43 Sub string `json:"sub,omitempty"`
44
45 // The old name of Sub. Client keeps setting Prn to be
46 // complaint with legacy OAuth 2.0 providers. (Optional)
47 Prn string `json:"prn,omitempty"`
48
49 // See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3
50 // This array is marshalled using custom code (see (c *ClaimSet) encode()).
51 PrivateClaims map[string]interface{} `json:"-"`
52}
53
54func (c *ClaimSet) encode() (string, error) {
55 // Reverting time back for machines whose time is not perfectly in sync.
56 // If client machine's time is in the future according
57 // to Google servers, an access token will not be issued.
58 now := time.Now().Add(-10 * time.Second)
59 if c.Iat == 0 {
60 c.Iat = now.Unix()
61 }
62 if c.Exp == 0 {
63 c.Exp = now.Add(time.Hour).Unix()
64 }
65 if c.Exp < c.Iat {
66 return "", fmt.Errorf("jws: invalid Exp = %v; must be later than Iat = %v", c.Exp, c.Iat)
67 }
68
69 b, err := json.Marshal(c)
70 if err != nil {
71 return "", err
72 }
73
74 if len(c.PrivateClaims) == 0 {
75 return base64.RawURLEncoding.EncodeToString(b), nil
76 }
77
78 // Marshal private claim set and then append it to b.
79 prv, err := json.Marshal(c.PrivateClaims)
80 if err != nil {
81 return "", fmt.Errorf("jws: invalid map of private claims %v", c.PrivateClaims)
82 }
83
84 // Concatenate public and private claim JSON objects.
85 if !bytes.HasSuffix(b, []byte{'}'}) {
86 return "", fmt.Errorf("jws: invalid JSON %s", b)
87 }
88 if !bytes.HasPrefix(prv, []byte{'{'}) {
89 return "", fmt.Errorf("jws: invalid JSON %s", prv)
90 }
91 b[len(b)-1] = ',' // Replace closing curly brace with a comma.
92 b = append(b, prv[1:]...) // Append private claims.
93 return base64.RawURLEncoding.EncodeToString(b), nil
94}
95
96// Header represents the header for the signed JWS payloads.
97type Header struct {
98 // The algorithm used for signature.
99 Algorithm string `json:"alg"`
100
101 // Represents the token type.
102 Typ string `json:"typ"`
103
104 // The optional hint of which key is being used.
105 KeyID string `json:"kid,omitempty"`
106}
107
108func (h *Header) encode() (string, error) {
109 b, err := json.Marshal(h)
110 if err != nil {
111 return "", err
112 }
113 return base64.RawURLEncoding.EncodeToString(b), nil
114}
115
116// Decode decodes a claim set from a JWS payload.
117func Decode(payload string) (*ClaimSet, error) {
118 // decode returned id token to get expiry
119 s := strings.Split(payload, ".")
120 if len(s) < 2 {
121 // TODO(jbd): Provide more context about the error.
122 return nil, errors.New("jws: invalid token received")
123 }
124 decoded, err := base64.RawURLEncoding.DecodeString(s[1])
125 if err != nil {
126 return nil, err
127 }
128 c := &ClaimSet{}
129 err = json.NewDecoder(bytes.NewBuffer(decoded)).Decode(c)
130 return c, err
131}
132
133// Signer returns a signature for the given data.
134type Signer func(data []byte) (sig []byte, err error)
135
136// EncodeWithSigner encodes a header and claim set with the provided signer.
137func EncodeWithSigner(header *Header, c *ClaimSet, sg Signer) (string, error) {
138 head, err := header.encode()
139 if err != nil {
140 return "", err
141 }
142 cs, err := c.encode()
143 if err != nil {
144 return "", err
145 }
146 ss := fmt.Sprintf("%s.%s", head, cs)
147 sig, err := sg([]byte(ss))
148 if err != nil {
149 return "", err
150 }
151 return fmt.Sprintf("%s.%s", ss, base64.RawURLEncoding.EncodeToString(sig)), nil
152}
153
154// Encode encodes a signed JWS with provided header and claim set.
155// This invokes EncodeWithSigner using crypto/rsa.SignPKCS1v15 with the given RSA private key.
156func Encode(header *Header, c *ClaimSet, key *rsa.PrivateKey) (string, error) {
157 sg := func(data []byte) (sig []byte, err error) {
158 h := sha256.New()
159 h.Write(data)
160 return rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, h.Sum(nil))
161 }
162 return EncodeWithSigner(header, c, sg)
163}
164
165// Verify tests whether the provided JWT token's signature was produced by the private key
166// associated with the supplied public key.
167func Verify(token string, key *rsa.PublicKey) error {
168 parts := strings.Split(token, ".")
169 if len(parts) != 3 {
170 return errors.New("jws: invalid token received, token must have 3 parts")
171 }
172
173 signedContent := parts[0] + "." + parts[1]
174 signatureString, err := base64.RawURLEncoding.DecodeString(parts[2])
175 if err != nil {
176 return err
177 }
178
179 h := sha256.New()
180 h.Write([]byte(signedContent))
181 return rsa.VerifyPKCS1v15(key, crypto.SHA256, h.Sum(nil), []byte(signatureString))
182}
diff --git a/vendor/golang.org/x/oauth2/jwt/jwt.go b/vendor/golang.org/x/oauth2/jwt/jwt.go
new file mode 100644
index 0000000..99f3e0a
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/jwt/jwt.go
@@ -0,0 +1,170 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package jwt implements the OAuth 2.0 JSON Web Token flow, commonly
6// known as "two-legged OAuth 2.0".
7//
8// See: https://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-12
9package jwt
10
11import (
12 "context"
13 "encoding/json"
14 "fmt"
15 "io"
16 "io/ioutil"
17 "net/http"
18 "net/url"
19 "strings"
20 "time"
21
22 "golang.org/x/oauth2"
23 "golang.org/x/oauth2/internal"
24 "golang.org/x/oauth2/jws"
25)
26
27var (
28 defaultGrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer"
29 defaultHeader = &jws.Header{Algorithm: "RS256", Typ: "JWT"}
30)
31
32// Config is the configuration for using JWT to fetch tokens,
33// commonly known as "two-legged OAuth 2.0".
34type Config struct {
35 // Email is the OAuth client identifier used when communicating with
36 // the configured OAuth provider.
37 Email string
38
39 // PrivateKey contains the contents of an RSA private key or the
40 // contents of a PEM file that contains a private key. The provided
41 // private key is used to sign JWT payloads.
42 // PEM containers with a passphrase are not supported.
43 // Use the following command to convert a PKCS 12 file into a PEM.
44 //
45 // $ openssl pkcs12 -in key.p12 -out key.pem -nodes
46 //
47 PrivateKey []byte
48
49 // PrivateKeyID contains an optional hint indicating which key is being
50 // used.
51 PrivateKeyID string
52
53 // Subject is the optional user to impersonate.
54 Subject string
55
56 // Scopes optionally specifies a list of requested permission scopes.
57 Scopes []string
58
59 // TokenURL is the endpoint required to complete the 2-legged JWT flow.
60 TokenURL string
61
62 // Expires optionally specifies how long the token is valid for.
63 Expires time.Duration
64
65 // Audience optionally specifies the intended audience of the
66 // request. If empty, the value of TokenURL is used as the
67 // intended audience.
68 Audience string
69}
70
71// TokenSource returns a JWT TokenSource using the configuration
72// in c and the HTTP client from the provided context.
73func (c *Config) TokenSource(ctx context.Context) oauth2.TokenSource {
74 return oauth2.ReuseTokenSource(nil, jwtSource{ctx, c})
75}
76
77// Client returns an HTTP client wrapping the context's
78// HTTP transport and adding Authorization headers with tokens
79// obtained from c.
80//
81// The returned client and its Transport should not be modified.
82func (c *Config) Client(ctx context.Context) *http.Client {
83 return oauth2.NewClient(ctx, c.TokenSource(ctx))
84}
85
86// jwtSource is a source that always does a signed JWT request for a token.
87// It should typically be wrapped with a reuseTokenSource.
88type jwtSource struct {
89 ctx context.Context
90 conf *Config
91}
92
93func (js jwtSource) Token() (*oauth2.Token, error) {
94 pk, err := internal.ParseKey(js.conf.PrivateKey)
95 if err != nil {
96 return nil, err
97 }
98 hc := oauth2.NewClient(js.ctx, nil)
99 claimSet := &jws.ClaimSet{
100 Iss: js.conf.Email,
101 Scope: strings.Join(js.conf.Scopes, " "),
102 Aud: js.conf.TokenURL,
103 }
104 if subject := js.conf.Subject; subject != "" {
105 claimSet.Sub = subject
106 // prn is the old name of sub. Keep setting it
107 // to be compatible with legacy OAuth 2.0 providers.
108 claimSet.Prn = subject
109 }
110 if t := js.conf.Expires; t > 0 {
111 claimSet.Exp = time.Now().Add(t).Unix()
112 }
113 if aud := js.conf.Audience; aud != "" {
114 claimSet.Aud = aud
115 }
116 h := *defaultHeader
117 h.KeyID = js.conf.PrivateKeyID
118 payload, err := jws.Encode(&h, claimSet, pk)
119 if err != nil {
120 return nil, err
121 }
122 v := url.Values{}
123 v.Set("grant_type", defaultGrantType)
124 v.Set("assertion", payload)
125 resp, err := hc.PostForm(js.conf.TokenURL, v)
126 if err != nil {
127 return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
128 }
129 defer resp.Body.Close()
130 body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
131 if err != nil {
132 return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
133 }
134 if c := resp.StatusCode; c < 200 || c > 299 {
135 return nil, &oauth2.RetrieveError{
136 Response: resp,
137 Body: body,
138 }
139 }
140 // tokenRes is the JSON response body.
141 var tokenRes struct {
142 AccessToken string `json:"access_token"`
143 TokenType string `json:"token_type"`
144 IDToken string `json:"id_token"`
145 ExpiresIn int64 `json:"expires_in"` // relative seconds from now
146 }
147 if err := json.Unmarshal(body, &tokenRes); err != nil {
148 return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
149 }
150 token := &oauth2.Token{
151 AccessToken: tokenRes.AccessToken,
152 TokenType: tokenRes.TokenType,
153 }
154 raw := make(map[string]interface{})
155 json.Unmarshal(body, &raw) // no error checks for optional fields
156 token = token.WithExtra(raw)
157
158 if secs := tokenRes.ExpiresIn; secs > 0 {
159 token.Expiry = time.Now().Add(time.Duration(secs) * time.Second)
160 }
161 if v := tokenRes.IDToken; v != "" {
162 // decode returned id token to get expiry
163 claimSet, err := jws.Decode(v)
164 if err != nil {
165 return nil, fmt.Errorf("oauth2: error decoding JWT token: %v", err)
166 }
167 token.Expiry = time.Unix(claimSet.Exp, 0)
168 }
169 return token, nil
170}
diff --git a/vendor/golang.org/x/oauth2/oauth2.go b/vendor/golang.org/x/oauth2/oauth2.go
new file mode 100644
index 0000000..428283f
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/oauth2.go
@@ -0,0 +1,381 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package oauth2 provides support for making
6// OAuth2 authorized and authenticated HTTP requests,
7// as specified in RFC 6749.
8// It can additionally grant authorization with Bearer JWT.
9package oauth2 // import "golang.org/x/oauth2"
10
11import (
12 "bytes"
13 "context"
14 "errors"
15 "net/http"
16 "net/url"
17 "strings"
18 "sync"
19
20 "golang.org/x/oauth2/internal"
21)
22
23// NoContext is the default context you should supply if not using
24// your own context.Context (see https://golang.org/x/net/context).
25//
26// Deprecated: Use context.Background() or context.TODO() instead.
27var NoContext = context.TODO()
28
29// RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op.
30//
31// Deprecated: this function no longer does anything. Caller code that
32// wants to avoid potential extra HTTP requests made during
33// auto-probing of the provider's auth style should set
34// Endpoint.AuthStyle.
35func RegisterBrokenAuthHeaderProvider(tokenURL string) {}
36
37// Config describes a typical 3-legged OAuth2 flow, with both the
38// client application information and the server's endpoint URLs.
39// For the client credentials 2-legged OAuth2 flow, see the clientcredentials
40// package (https://golang.org/x/oauth2/clientcredentials).
41type Config struct {
42 // ClientID is the application's ID.
43 ClientID string
44
45 // ClientSecret is the application's secret.
46 ClientSecret string
47
48 // Endpoint contains the resource server's token endpoint
49 // URLs. These are constants specific to each server and are
50 // often available via site-specific packages, such as
51 // google.Endpoint or github.Endpoint.
52 Endpoint Endpoint
53
54 // RedirectURL is the URL to redirect users going through
55 // the OAuth flow, after the resource owner's URLs.
56 RedirectURL string
57
58 // Scope specifies optional requested permissions.
59 Scopes []string
60}
61
62// A TokenSource is anything that can return a token.
63type TokenSource interface {
64 // Token returns a token or an error.
65 // Token must be safe for concurrent use by multiple goroutines.
66 // The returned Token must not be modified.
67 Token() (*Token, error)
68}
69
70// Endpoint represents an OAuth 2.0 provider's authorization and token
71// endpoint URLs.
72type Endpoint struct {
73 AuthURL string
74 TokenURL string
75
76 // AuthStyle optionally specifies how the endpoint wants the
77 // client ID & client secret sent. The zero value means to
78 // auto-detect.
79 AuthStyle AuthStyle
80}
81
82// AuthStyle represents how requests for tokens are authenticated
83// to the server.
84type AuthStyle int
85
86const (
87 // AuthStyleAutoDetect means to auto-detect which authentication
88 // style the provider wants by trying both ways and caching
89 // the successful way for the future.
90 AuthStyleAutoDetect AuthStyle = 0
91
92 // AuthStyleInParams sends the "client_id" and "client_secret"
93 // in the POST body as application/x-www-form-urlencoded parameters.
94 AuthStyleInParams AuthStyle = 1
95
96 // AuthStyleInHeader sends the client_id and client_password
97 // using HTTP Basic Authorization. This is an optional style
98 // described in the OAuth2 RFC 6749 section 2.3.1.
99 AuthStyleInHeader AuthStyle = 2
100)
101
102var (
103 // AccessTypeOnline and AccessTypeOffline are options passed
104 // to the Options.AuthCodeURL method. They modify the
105 // "access_type" field that gets sent in the URL returned by
106 // AuthCodeURL.
107 //
108 // Online is the default if neither is specified. If your
109 // application needs to refresh access tokens when the user
110 // is not present at the browser, then use offline. This will
111 // result in your application obtaining a refresh token the
112 // first time your application exchanges an authorization
113 // code for a user.
114 AccessTypeOnline AuthCodeOption = SetAuthURLParam("access_type", "online")
115 AccessTypeOffline AuthCodeOption = SetAuthURLParam("access_type", "offline")
116
117 // ApprovalForce forces the users to view the consent dialog
118 // and confirm the permissions request at the URL returned
119 // from AuthCodeURL, even if they've already done so.
120 ApprovalForce AuthCodeOption = SetAuthURLParam("approval_prompt", "force")
121)
122
123// An AuthCodeOption is passed to Config.AuthCodeURL.
124type AuthCodeOption interface {
125 setValue(url.Values)
126}
127
128type setParam struct{ k, v string }
129
130func (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) }
131
132// SetAuthURLParam builds an AuthCodeOption which passes key/value parameters
133// to a provider's authorization endpoint.
134func SetAuthURLParam(key, value string) AuthCodeOption {
135 return setParam{key, value}
136}
137
138// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page
139// that asks for permissions for the required scopes explicitly.
140//
141// State is a token to protect the user from CSRF attacks. You must
142// always provide a non-empty string and validate that it matches the
143// the state query parameter on your redirect callback.
144// See http://tools.ietf.org/html/rfc6749#section-10.12 for more info.
145//
146// Opts may include AccessTypeOnline or AccessTypeOffline, as well
147// as ApprovalForce.
148// It can also be used to pass the PKCE challenge.
149// See https://www.oauth.com/oauth2-servers/pkce/ for more info.
150func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
151 var buf bytes.Buffer
152 buf.WriteString(c.Endpoint.AuthURL)
153 v := url.Values{
154 "response_type": {"code"},
155 "client_id": {c.ClientID},
156 }
157 if c.RedirectURL != "" {
158 v.Set("redirect_uri", c.RedirectURL)
159 }
160 if len(c.Scopes) > 0 {
161 v.Set("scope", strings.Join(c.Scopes, " "))
162 }
163 if state != "" {
164 // TODO(light): Docs say never to omit state; don't allow empty.
165 v.Set("state", state)
166 }
167 for _, opt := range opts {
168 opt.setValue(v)
169 }
170 if strings.Contains(c.Endpoint.AuthURL, "?") {
171 buf.WriteByte('&')
172 } else {
173 buf.WriteByte('?')
174 }
175 buf.WriteString(v.Encode())
176 return buf.String()
177}
178
179// PasswordCredentialsToken converts a resource owner username and password
180// pair into a token.
181//
182// Per the RFC, this grant type should only be used "when there is a high
183// degree of trust between the resource owner and the client (e.g., the client
184// is part of the device operating system or a highly privileged application),
185// and when other authorization grant types are not available."
186// See https://tools.ietf.org/html/rfc6749#section-4.3 for more info.
187//
188// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
189func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) {
190 v := url.Values{
191 "grant_type": {"password"},
192 "username": {username},
193 "password": {password},
194 }
195 if len(c.Scopes) > 0 {
196 v.Set("scope", strings.Join(c.Scopes, " "))
197 }
198 return retrieveToken(ctx, c, v)
199}
200
201// Exchange converts an authorization code into a token.
202//
203// It is used after a resource provider redirects the user back
204// to the Redirect URI (the URL obtained from AuthCodeURL).
205//
206// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
207//
208// The code will be in the *http.Request.FormValue("code"). Before
209// calling Exchange, be sure to validate FormValue("state").
210//
211// Opts may include the PKCE verifier code if previously used in AuthCodeURL.
212// See https://www.oauth.com/oauth2-servers/pkce/ for more info.
213func (c *Config) Exchange(ctx context.Context, code string, opts ...AuthCodeOption) (*Token, error) {
214 v := url.Values{
215 "grant_type": {"authorization_code"},
216 "code": {code},
217 }
218 if c.RedirectURL != "" {
219 v.Set("redirect_uri", c.RedirectURL)
220 }
221 for _, opt := range opts {
222 opt.setValue(v)
223 }
224 return retrieveToken(ctx, c, v)
225}
226
227// Client returns an HTTP client using the provided token.
228// The token will auto-refresh as necessary. The underlying
229// HTTP transport will be obtained using the provided context.
230// The returned client and its Transport should not be modified.
231func (c *Config) Client(ctx context.Context, t *Token) *http.Client {
232 return NewClient(ctx, c.TokenSource(ctx, t))
233}
234
235// TokenSource returns a TokenSource that returns t until t expires,
236// automatically refreshing it as necessary using the provided context.
237//
238// Most users will use Config.Client instead.
239func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource {
240 tkr := &tokenRefresher{
241 ctx: ctx,
242 conf: c,
243 }
244 if t != nil {
245 tkr.refreshToken = t.RefreshToken
246 }
247 return &reuseTokenSource{
248 t: t,
249 new: tkr,
250 }
251}
252
253// tokenRefresher is a TokenSource that makes "grant_type"=="refresh_token"
254// HTTP requests to renew a token using a RefreshToken.
255type tokenRefresher struct {
256 ctx context.Context // used to get HTTP requests
257 conf *Config
258 refreshToken string
259}
260
261// WARNING: Token is not safe for concurrent access, as it
262// updates the tokenRefresher's refreshToken field.
263// Within this package, it is used by reuseTokenSource which
264// synchronizes calls to this method with its own mutex.
265func (tf *tokenRefresher) Token() (*Token, error) {
266 if tf.refreshToken == "" {
267 return nil, errors.New("oauth2: token expired and refresh token is not set")
268 }
269
270 tk, err := retrieveToken(tf.ctx, tf.conf, url.Values{
271 "grant_type": {"refresh_token"},
272 "refresh_token": {tf.refreshToken},
273 })
274
275 if err != nil {
276 return nil, err
277 }
278 if tf.refreshToken != tk.RefreshToken {
279 tf.refreshToken = tk.RefreshToken
280 }
281 return tk, err
282}
283
284// reuseTokenSource is a TokenSource that holds a single token in memory
285// and validates its expiry before each call to retrieve it with
286// Token. If it's expired, it will be auto-refreshed using the
287// new TokenSource.
288type reuseTokenSource struct {
289 new TokenSource // called when t is expired.
290
291 mu sync.Mutex // guards t
292 t *Token
293}
294
295// Token returns the current token if it's still valid, else will
296// refresh the current token (using r.Context for HTTP client
297// information) and return the new one.
298func (s *reuseTokenSource) Token() (*Token, error) {
299 s.mu.Lock()
300 defer s.mu.Unlock()
301 if s.t.Valid() {
302 return s.t, nil
303 }
304 t, err := s.new.Token()
305 if err != nil {
306 return nil, err
307 }
308 s.t = t
309 return t, nil
310}
311
312// StaticTokenSource returns a TokenSource that always returns the same token.
313// Because the provided token t is never refreshed, StaticTokenSource is only
314// useful for tokens that never expire.
315func StaticTokenSource(t *Token) TokenSource {
316 return staticTokenSource{t}
317}
318
319// staticTokenSource is a TokenSource that always returns the same Token.
320type staticTokenSource struct {
321 t *Token
322}
323
324func (s staticTokenSource) Token() (*Token, error) {
325 return s.t, nil
326}
327
328// HTTPClient is the context key to use with golang.org/x/net/context's
329// WithValue function to associate an *http.Client value with a context.
330var HTTPClient internal.ContextKey
331
332// NewClient creates an *http.Client from a Context and TokenSource.
333// The returned client is not valid beyond the lifetime of the context.
334//
335// Note that if a custom *http.Client is provided via the Context it
336// is used only for token acquisition and is not used to configure the
337// *http.Client returned from NewClient.
338//
339// As a special case, if src is nil, a non-OAuth2 client is returned
340// using the provided context. This exists to support related OAuth2
341// packages.
342func NewClient(ctx context.Context, src TokenSource) *http.Client {
343 if src == nil {
344 return internal.ContextClient(ctx)
345 }
346 return &http.Client{
347 Transport: &Transport{
348 Base: internal.ContextClient(ctx).Transport,
349 Source: ReuseTokenSource(nil, src),
350 },
351 }
352}
353
354// ReuseTokenSource returns a TokenSource which repeatedly returns the
355// same token as long as it's valid, starting with t.
356// When its cached token is invalid, a new token is obtained from src.
357//
358// ReuseTokenSource is typically used to reuse tokens from a cache
359// (such as a file on disk) between runs of a program, rather than
360// obtaining new tokens unnecessarily.
361//
362// The initial token t may be nil, in which case the TokenSource is
363// wrapped in a caching version if it isn't one already. This also
364// means it's always safe to wrap ReuseTokenSource around any other
365// TokenSource without adverse effects.
366func ReuseTokenSource(t *Token, src TokenSource) TokenSource {
367 // Don't wrap a reuseTokenSource in itself. That would work,
368 // but cause an unnecessary number of mutex operations.
369 // Just build the equivalent one.
370 if rt, ok := src.(*reuseTokenSource); ok {
371 if t == nil {
372 // Just use it directly.
373 return rt
374 }
375 src = rt.new
376 }
377 return &reuseTokenSource{
378 t: t,
379 new: src,
380 }
381}
diff --git a/vendor/golang.org/x/oauth2/token.go b/vendor/golang.org/x/oauth2/token.go
new file mode 100644
index 0000000..8227203
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/token.go
@@ -0,0 +1,178 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package oauth2
6
7import (
8 "context"
9 "fmt"
10 "net/http"
11 "net/url"
12 "strconv"
13 "strings"
14 "time"
15
16 "golang.org/x/oauth2/internal"
17)
18
19// expiryDelta determines how earlier a token should be considered
20// expired than its actual expiration time. It is used to avoid late
21// expirations due to client-server time mismatches.
22const expiryDelta = 10 * time.Second
23
24// Token represents the credentials used to authorize
25// the requests to access protected resources on the OAuth 2.0
26// provider's backend.
27//
28// Most users of this package should not access fields of Token
29// directly. They're exported mostly for use by related packages
30// implementing derivative OAuth2 flows.
31type Token struct {
32 // AccessToken is the token that authorizes and authenticates
33 // the requests.
34 AccessToken string `json:"access_token"`
35
36 // TokenType is the type of token.
37 // The Type method returns either this or "Bearer", the default.
38 TokenType string `json:"token_type,omitempty"`
39
40 // RefreshToken is a token that's used by the application
41 // (as opposed to the user) to refresh the access token
42 // if it expires.
43 RefreshToken string `json:"refresh_token,omitempty"`
44
45 // Expiry is the optional expiration time of the access token.
46 //
47 // If zero, TokenSource implementations will reuse the same
48 // token forever and RefreshToken or equivalent
49 // mechanisms for that TokenSource will not be used.
50 Expiry time.Time `json:"expiry,omitempty"`
51
52 // raw optionally contains extra metadata from the server
53 // when updating a token.
54 raw interface{}
55}
56
57// Type returns t.TokenType if non-empty, else "Bearer".
58func (t *Token) Type() string {
59 if strings.EqualFold(t.TokenType, "bearer") {
60 return "Bearer"
61 }
62 if strings.EqualFold(t.TokenType, "mac") {
63 return "MAC"
64 }
65 if strings.EqualFold(t.TokenType, "basic") {
66 return "Basic"
67 }
68 if t.TokenType != "" {
69 return t.TokenType
70 }
71 return "Bearer"
72}
73
74// SetAuthHeader sets the Authorization header to r using the access
75// token in t.
76//
77// This method is unnecessary when using Transport or an HTTP Client
78// returned by this package.
79func (t *Token) SetAuthHeader(r *http.Request) {
80 r.Header.Set("Authorization", t.Type()+" "+t.AccessToken)
81}
82
83// WithExtra returns a new Token that's a clone of t, but using the
84// provided raw extra map. This is only intended for use by packages
85// implementing derivative OAuth2 flows.
86func (t *Token) WithExtra(extra interface{}) *Token {
87 t2 := new(Token)
88 *t2 = *t
89 t2.raw = extra
90 return t2
91}
92
93// Extra returns an extra field.
94// Extra fields are key-value pairs returned by the server as a
95// part of the token retrieval response.
96func (t *Token) Extra(key string) interface{} {
97 if raw, ok := t.raw.(map[string]interface{}); ok {
98 return raw[key]
99 }
100
101 vals, ok := t.raw.(url.Values)
102 if !ok {
103 return nil
104 }
105
106 v := vals.Get(key)
107 switch s := strings.TrimSpace(v); strings.Count(s, ".") {
108 case 0: // Contains no "."; try to parse as int
109 if i, err := strconv.ParseInt(s, 10, 64); err == nil {
110 return i
111 }
112 case 1: // Contains a single "."; try to parse as float
113 if f, err := strconv.ParseFloat(s, 64); err == nil {
114 return f
115 }
116 }
117
118 return v
119}
120
121// timeNow is time.Now but pulled out as a variable for tests.
122var timeNow = time.Now
123
124// expired reports whether the token is expired.
125// t must be non-nil.
126func (t *Token) expired() bool {
127 if t.Expiry.IsZero() {
128 return false
129 }
130 return t.Expiry.Round(0).Add(-expiryDelta).Before(timeNow())
131}
132
133// Valid reports whether t is non-nil, has an AccessToken, and is not expired.
134func (t *Token) Valid() bool {
135 return t != nil && t.AccessToken != "" && !t.expired()
136}
137
138// tokenFromInternal maps an *internal.Token struct into
139// a *Token struct.
140func tokenFromInternal(t *internal.Token) *Token {
141 if t == nil {
142 return nil
143 }
144 return &Token{
145 AccessToken: t.AccessToken,
146 TokenType: t.TokenType,
147 RefreshToken: t.RefreshToken,
148 Expiry: t.Expiry,
149 raw: t.Raw,
150 }
151}
152
153// retrieveToken takes a *Config and uses that to retrieve an *internal.Token.
154// This token is then mapped from *internal.Token into an *oauth2.Token which is returned along
155// with an error..
156func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) {
157 tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v, internal.AuthStyle(c.Endpoint.AuthStyle))
158 if err != nil {
159 if rErr, ok := err.(*internal.RetrieveError); ok {
160 return nil, (*RetrieveError)(rErr)
161 }
162 return nil, err
163 }
164 return tokenFromInternal(tk), nil
165}
166
167// RetrieveError is the error returned when the token endpoint returns a
168// non-2XX HTTP status code.
169type RetrieveError struct {
170 Response *http.Response
171 // Body is the body that was consumed by reading Response.Body.
172 // It may be truncated.
173 Body []byte
174}
175
176func (r *RetrieveError) Error() string {
177 return fmt.Sprintf("oauth2: cannot fetch token: %v\nResponse: %s", r.Response.Status, r.Body)
178}
diff --git a/vendor/golang.org/x/oauth2/transport.go b/vendor/golang.org/x/oauth2/transport.go
new file mode 100644
index 0000000..aa0d34f
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/transport.go
@@ -0,0 +1,144 @@
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package oauth2
6
7import (
8 "errors"
9 "io"
10 "net/http"
11 "sync"
12)
13
14// Transport is an http.RoundTripper that makes OAuth 2.0 HTTP requests,
15// wrapping a base RoundTripper and adding an Authorization header
16// with a token from the supplied Sources.
17//
18// Transport is a low-level mechanism. Most code will use the
19// higher-level Config.Client method instead.
20type Transport struct {
21 // Source supplies the token to add to outgoing requests'
22 // Authorization headers.
23 Source TokenSource
24
25 // Base is the base RoundTripper used to make HTTP requests.
26 // If nil, http.DefaultTransport is used.
27 Base http.RoundTripper
28
29 mu sync.Mutex // guards modReq
30 modReq map[*http.Request]*http.Request // original -> modified
31}
32
33// RoundTrip authorizes and authenticates the request with an
34// access token from Transport's Source.
35func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
36 reqBodyClosed := false
37 if req.Body != nil {
38 defer func() {
39 if !reqBodyClosed {
40 req.Body.Close()
41 }
42 }()
43 }
44
45 if t.Source == nil {
46 return nil, errors.New("oauth2: Transport's Source is nil")
47 }
48 token, err := t.Source.Token()
49 if err != nil {
50 return nil, err
51 }
52
53 req2 := cloneRequest(req) // per RoundTripper contract
54 token.SetAuthHeader(req2)
55 t.setModReq(req, req2)
56 res, err := t.base().RoundTrip(req2)
57
58 // req.Body is assumed to have been closed by the base RoundTripper.
59 reqBodyClosed = true
60
61 if err != nil {
62 t.setModReq(req, nil)
63 return nil, err
64 }
65 res.Body = &onEOFReader{
66 rc: res.Body,
67 fn: func() { t.setModReq(req, nil) },
68 }
69 return res, nil
70}
71
72// CancelRequest cancels an in-flight request by closing its connection.
73func (t *Transport) CancelRequest(req *http.Request) {
74 type canceler interface {
75 CancelRequest(*http.Request)
76 }
77 if cr, ok := t.base().(canceler); ok {
78 t.mu.Lock()
79 modReq := t.modReq[req]
80 delete(t.modReq, req)
81 t.mu.Unlock()
82 cr.CancelRequest(modReq)
83 }
84}
85
86func (t *Transport) base() http.RoundTripper {
87 if t.Base != nil {
88 return t.Base
89 }
90 return http.DefaultTransport
91}
92
93func (t *Transport) setModReq(orig, mod *http.Request) {
94 t.mu.Lock()
95 defer t.mu.Unlock()
96 if t.modReq == nil {
97 t.modReq = make(map[*http.Request]*http.Request)
98 }
99 if mod == nil {
100 delete(t.modReq, orig)
101 } else {
102 t.modReq[orig] = mod
103 }
104}
105
106// cloneRequest returns a clone of the provided *http.Request.
107// The clone is a shallow copy of the struct and its Header map.
108func cloneRequest(r *http.Request) *http.Request {
109 // shallow copy of the struct
110 r2 := new(http.Request)
111 *r2 = *r
112 // deep copy of the Header
113 r2.Header = make(http.Header, len(r.Header))
114 for k, s := range r.Header {
115 r2.Header[k] = append([]string(nil), s...)
116 }
117 return r2
118}
119
120type onEOFReader struct {
121 rc io.ReadCloser
122 fn func()
123}
124
125func (r *onEOFReader) Read(p []byte) (n int, err error) {
126 n, err = r.rc.Read(p)
127 if err == io.EOF {
128 r.runFunc()
129 }
130 return
131}
132
133func (r *onEOFReader) Close() error {
134 err := r.rc.Close()
135 r.runFunc()
136 return err
137}
138
139func (r *onEOFReader) runFunc() {
140 if fn := r.fn; fn != nil {
141 fn()
142 r.fn = nil
143 }
144}