]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/golang.org/x/oauth2/google/default.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / golang.org / x / oauth2 / google / default.go
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
5 package google
6
7 import (
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
24 type 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.
38 type DefaultCredentials = Credentials
39
40 // DefaultClient returns an HTTP Client that uses the
41 // DefaultTokenSource to obtain authentication credentials.
42 func 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.
53 func 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.)
77 func 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).
125 func 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
141 func 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
149 func 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 }