Skip to content

Commit 7af32f1

Browse files
jbabroady
authored andcommitted
google: add CredentialsFromJSON
Support obtaining a DefaultCredentials value from JSON data. Also, add an example, and write more package doc. For Go 1.9 and higher, rename DefaultCredentials to Credentials and make the former an alias for the latter. Updates googleapis/google-api-go-client#247. Change-Id: I9f9e234ed79f8e08fa13914d9c6c60e0154a06e5 Reviewed-on: https://go-review.googlesource.com/99795 Reviewed-by: Ross Light <[email protected]> Reviewed-by: Chris Broadfoot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 2f32c3a commit 7af32f1

File tree

7 files changed

+234
-58
lines changed

7 files changed

+234
-58
lines changed

google/default.go

Lines changed: 23 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,6 @@ import (
1818
"golang.org/x/oauth2"
1919
)
2020

21-
// DefaultCredentials holds "Application Default Credentials".
22-
// For more details, see:
23-
// https://developers.google.com/accounts/docs/application-default-credentials
24-
type DefaultCredentials 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-
3521
// DefaultClient returns an HTTP Client that uses the
3622
// DefaultTokenSource to obtain authentication credentials.
3723
func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
@@ -53,25 +39,12 @@ func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSourc
5339
return creds.TokenSource, nil
5440
}
5541

56-
// FindDefaultCredentials searches for "Application Default Credentials".
57-
//
58-
// It looks for credentials in the following places,
59-
// preferring the first location found:
60-
//
61-
// 1. A JSON file whose path is specified by the
62-
// GOOGLE_APPLICATION_CREDENTIALS environment variable.
63-
// 2. A JSON file in a location known to the gcloud command-line tool.
64-
// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
65-
// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
66-
// 3. On Google App Engine it uses the appengine.AccessToken function.
67-
// 4. On Google Compute Engine and Google App Engine Managed VMs, it fetches
68-
// credentials from the metadata server.
69-
// (In this final case any provided scopes are ignored.)
70-
func FindDefaultCredentials(ctx context.Context, scope ...string) (*DefaultCredentials, error) {
42+
// Common implementation for FindDefaultCredentials.
43+
func findDefaultCredentials(ctx context.Context, scopes []string) (*DefaultCredentials, error) {
7144
// First, try the environment variable.
7245
const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
7346
if filename := os.Getenv(envVar); filename != "" {
74-
creds, err := readCredentialsFile(ctx, filename, scope)
47+
creds, err := readCredentialsFile(ctx, filename, scopes)
7548
if err != nil {
7649
return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err)
7750
}
@@ -80,7 +53,7 @@ func FindDefaultCredentials(ctx context.Context, scope ...string) (*DefaultCrede
8053

8154
// Second, try a well-known file.
8255
filename := wellKnownFile()
83-
if creds, err := readCredentialsFile(ctx, filename, scope); err == nil {
56+
if creds, err := readCredentialsFile(ctx, filename, scopes); err == nil {
8457
return creds, nil
8558
} else if !os.IsNotExist(err) {
8659
return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err)
@@ -90,7 +63,7 @@ func FindDefaultCredentials(ctx context.Context, scope ...string) (*DefaultCrede
9063
if appengineTokenFunc != nil && !appengineFlex {
9164
return &DefaultCredentials{
9265
ProjectID: appengineAppIDFunc(ctx),
93-
TokenSource: AppEngineTokenSource(ctx, scope...),
66+
TokenSource: AppEngineTokenSource(ctx, scopes...),
9467
}, nil
9568
}
9669

@@ -108,6 +81,23 @@ func FindDefaultCredentials(ctx context.Context, scope ...string) (*DefaultCrede
10881
return nil, fmt.Errorf("google: could not find default credentials. See %v for more information.", url)
10982
}
11083

84+
// Common implementation for CredentialsFromJSON.
85+
func credentialsFromJSON(ctx context.Context, jsonData []byte, scopes []string) (*DefaultCredentials, error) {
86+
var f credentialsFile
87+
if err := json.Unmarshal(jsonData, &f); err != nil {
88+
return nil, err
89+
}
90+
ts, err := f.tokenSource(ctx, append([]string(nil), scopes...))
91+
if err != nil {
92+
return nil, err
93+
}
94+
return &DefaultCredentials{
95+
ProjectID: f.ProjectID,
96+
TokenSource: ts,
97+
JSON: jsonData,
98+
}, nil
99+
}
100+
111101
func wellKnownFile() string {
112102
const f = "application_default_credentials.json"
113103
if runtime.GOOS == "windows" {
@@ -121,17 +111,5 @@ func readCredentialsFile(ctx context.Context, filename string, scopes []string)
121111
if err != nil {
122112
return nil, err
123113
}
124-
var f credentialsFile
125-
if err := json.Unmarshal(b, &f); err != nil {
126-
return nil, err
127-
}
128-
ts, err := f.tokenSource(ctx, append([]string(nil), scopes...))
129-
if err != nil {
130-
return nil, err
131-
}
132-
return &DefaultCredentials{
133-
ProjectID: f.ProjectID,
134-
TokenSource: ts,
135-
JSON: b,
136-
}, nil
114+
return CredentialsFromJSON(ctx, b, scopes...)
137115
}

google/doc_go19.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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 go1.9
6+
7+
// Package google provides support for making OAuth2 authorized and authenticated
8+
// HTTP requests to Google APIs. It supports the Web server flow, client-side
9+
// credentials, service accounts, Google Compute Engine service accounts, and Google
10+
// App Engine service accounts.
11+
//
12+
// A brief overview of the package follows. For more information, please read
13+
// https://developers.google.com/accounts/docs/OAuth2
14+
// and
15+
// https://developers.google.com/accounts/docs/application-default-credentials.
16+
//
17+
// OAuth2 Configs
18+
//
19+
// Two functions in this package return golang.org/x/oauth2.Config values from Google credential
20+
// data. Google supports two JSON formats for OAuth2 credentials: one is handled by ConfigFromJSON,
21+
// the other by JWTConfigFromJSON. The returned Config can be used to obtain a TokenSource or
22+
// create an http.Client.
23+
//
24+
//
25+
// Credentials
26+
//
27+
// The Credentials type represents Google credentials, including Application Default
28+
// Credentials.
29+
//
30+
// Use FindDefaultCredentials to obtain Application Default Credentials.
31+
// FindDefaultCredentials looks in some well-known places for a credentials file, and
32+
// will call AppEngineTokenSource or ComputeTokenSource as needed.
33+
//
34+
// DefaultClient and DefaultTokenSource are convenience methods. They first call FindDefaultCredentials,
35+
// then use the credentials to construct an http.Client or an oauth2.TokenSource.
36+
//
37+
// Use CredentialsFromJSON to obtain credentials from either of the two JSON formats
38+
// described in OAuth2 Configs, above. The TokenSource in the returned value is the
39+
// same as the one obtained from the oauth2.Config returned from ConfigFromJSON or
40+
// JWTConfigFromJSON, but the Credentials may contain additional information
41+
// that is useful is some circumstances.
42+
package google // import "golang.org/x/oauth2/google"

google/doc_not_go19.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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 !go1.9
6+
7+
// Package google provides support for making OAuth2 authorized and authenticated
8+
// HTTP requests to Google APIs. It supports the Web server flow, client-side
9+
// credentials, service accounts, Google Compute Engine service accounts, and Google
10+
// App Engine service accounts.
11+
//
12+
// A brief overview of the package follows. For more information, please read
13+
// https://developers.google.com/accounts/docs/OAuth2
14+
// and
15+
// https://developers.google.com/accounts/docs/application-default-credentials.
16+
//
17+
// OAuth2 Configs
18+
//
19+
// Two functions in this package return golang.org/x/oauth2.Config values from Google credential
20+
// data. Google supports two JSON formats for OAuth2 credentials: one is handled by ConfigFromJSON,
21+
// the other by JWTConfigFromJSON. The returned Config can be used to obtain a TokenSource or
22+
// create an http.Client.
23+
//
24+
//
25+
// Credentials
26+
//
27+
// The DefaultCredentials type represents Google Application Default Credentials, as
28+
// well as other forms of credential.
29+
//
30+
// Use FindDefaultCredentials to obtain Application Default Credentials.
31+
// FindDefaultCredentials looks in some well-known places for a credentials file, and
32+
// will call AppEngineTokenSource or ComputeTokenSource as needed.
33+
//
34+
// DefaultClient and DefaultTokenSource are convenience methods. They first call FindDefaultCredentials,
35+
// then use the credentials to construct an http.Client or an oauth2.TokenSource.
36+
//
37+
// Use CredentialsFromJSON to obtain credentials from either of the two JSON
38+
// formats described in OAuth2 Configs, above. (The DefaultCredentials returned may
39+
// not be "Application Default Credentials".) The TokenSource in the returned value
40+
// is the same as the one obtained from the oauth2.Config returned from
41+
// ConfigFromJSON or JWTConfigFromJSON, but the DefaultCredentials may contain
42+
// additional information that is useful is some circumstances.
43+
package google // import "golang.org/x/oauth2/google"

google/example_test.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// +build appenginevm appengine
6-
75
package google_test
86

97
import (
@@ -12,6 +10,7 @@ import (
1210
"log"
1311
"net/http"
1412

13+
"golang.org/x/net/context"
1514
"golang.org/x/oauth2"
1615
"golang.org/x/oauth2/google"
1716
"golang.org/x/oauth2/jwt"
@@ -148,3 +147,16 @@ func ExampleComputeTokenSource() {
148147
}
149148
client.Get("...")
150149
}
150+
151+
func ExampleCredentialsFromJSON() {
152+
ctx := context.Background()
153+
data, err := ioutil.ReadFile("/path/to/key-file.json")
154+
if err != nil {
155+
log.Fatal(err)
156+
}
157+
creds, err := google.CredentialsFromJSON(ctx, data, "https://www.googleapis.com/auth/bigquery")
158+
if err != nil {
159+
log.Fatal(err)
160+
}
161+
_ = creds // TODO: Use creds.
162+
}

google/go19.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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 go1.9
6+
7+
package google
8+
9+
import (
10+
"golang.org/x/net/context"
11+
"golang.org/x/oauth2"
12+
)
13+
14+
// Credentials holds Google credentials, including "Application Default Credentials".
15+
// For more details, see:
16+
// https://developers.google.com/accounts/docs/application-default-credentials
17+
type Credentials struct {
18+
ProjectID string // may be empty
19+
TokenSource oauth2.TokenSource
20+
21+
// JSON contains the raw bytes from a JSON credentials file.
22+
// This field may be nil if authentication is provided by the
23+
// environment and not with a credentials file, e.g. when code is
24+
// running on Google Cloud Platform.
25+
JSON []byte
26+
}
27+
28+
// DefaultCredentials is the old name of Credentials.
29+
//
30+
// Deprecated: use Credentials instead.
31+
type DefaultCredentials = Credentials
32+
33+
// FindDefaultCredentials searches for "Application Default Credentials".
34+
//
35+
// It looks for credentials in the following places,
36+
// preferring the first location found:
37+
//
38+
// 1. A JSON file whose path is specified by the
39+
// GOOGLE_APPLICATION_CREDENTIALS environment variable.
40+
// 2. A JSON file in a location known to the gcloud command-line tool.
41+
// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
42+
// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
43+
// 3. On Google App Engine it uses the appengine.AccessToken function.
44+
// 4. On Google Compute Engine and Google App Engine Managed VMs, it fetches
45+
// credentials from the metadata server.
46+
// (In this final case any provided scopes are ignored.)
47+
func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials, error) {
48+
return findDefaultCredentials(ctx, scopes)
49+
}
50+
51+
// CredentialsFromJSON obtains Google credentials from a JSON value. The JSON can
52+
// represent either a Google Developers Console client_credentials.json file (as in
53+
// ConfigFromJSON) or a Google Developers service account key file (as in
54+
// JWTConfigFromJSON).
55+
func CredentialsFromJSON(ctx context.Context, jsonData []byte, scopes ...string) (*Credentials, error) {
56+
return credentialsFromJSON(ctx, jsonData, scopes)
57+
}

google/google.go

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// Package google provides support for making OAuth2 authorized and
6-
// authenticated HTTP requests to Google APIs.
7-
// It supports the Web server flow, client-side credentials, service accounts,
8-
// Google Compute Engine service accounts, and Google App Engine service
9-
// accounts.
10-
//
11-
// For more information, please read
12-
// https://developers.google.com/accounts/docs/OAuth2
13-
// and
14-
// https://developers.google.com/accounts/docs/application-default-credentials.
15-
package google // import "golang.org/x/oauth2/google"
5+
package google
166

177
import (
188
"encoding/json"

google/not_go19.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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 !go1.9
6+
7+
package google
8+
9+
import (
10+
"golang.org/x/net/context"
11+
"golang.org/x/oauth2"
12+
)
13+
14+
// DefaultCredentials holds Google credentials, including "Application Default Credentials".
15+
// For more details, see:
16+
// https://developers.google.com/accounts/docs/application-default-credentials
17+
type DefaultCredentials struct {
18+
ProjectID string // may be empty
19+
TokenSource oauth2.TokenSource
20+
21+
// JSON contains the raw bytes from a JSON credentials file.
22+
// This field may be nil if authentication is provided by the
23+
// environment and not with a credentials file, e.g. when code is
24+
// running on Google Cloud Platform.
25+
JSON []byte
26+
}
27+
28+
// FindDefaultCredentials searches for "Application Default Credentials".
29+
//
30+
// It looks for credentials in the following places,
31+
// preferring the first location found:
32+
//
33+
// 1. A JSON file whose path is specified by the
34+
// GOOGLE_APPLICATION_CREDENTIALS environment variable.
35+
// 2. A JSON file in a location known to the gcloud command-line tool.
36+
// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
37+
// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
38+
// 3. On Google App Engine it uses the appengine.AccessToken function.
39+
// 4. On Google Compute Engine and Google App Engine Managed VMs, it fetches
40+
// credentials from the metadata server.
41+
// (In this final case any provided scopes are ignored.)
42+
func FindDefaultCredentials(ctx context.Context, scopes ...string) (*DefaultCredentials, error) {
43+
return findDefaultCredentials(ctx, scopes)
44+
}
45+
46+
// CredentialsFromJSON obtains Google credentials from a JSON value. The JSON can
47+
// represent either a Google Developers Console client_credentials.json file (as in
48+
// ConfigFromJSON) or a Google Developers service account key file (as in
49+
// JWTConfigFromJSON).
50+
//
51+
// Note: despite the name, the returned credentials may not be Application Default Credentials.
52+
func CredentialsFromJSON(ctx context.Context, jsonData []byte, scopes ...string) (*DefaultCredentials, error) {
53+
return credentialsFromJSON(ctx, jsonData, scopes)
54+
}

0 commit comments

Comments
 (0)