aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/golang.org/x/oauth2/google
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/oauth2/google')
-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
8 files changed, 805 insertions, 0 deletions
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}