google: Support scopes for ComputeTokenSource
Scopes have been added as a query parameter to the metadata server.
Change-Id: Ife68db01beeca386e558edd424fa11da508b7287
GitHub-Last-Rev: 1cb4a6ec12f2b17f6a2290a524b18d60246d56ae
GitHub-Pull-Request: golang/oauth2#376
Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/170106
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/google/default.go b/google/default.go
index 5087d84..ad2c092 100644
--- a/google/default.go
+++ b/google/default.go
@@ -73,7 +73,6 @@
// 4. On Google Compute Engine, Google App Engine standard second generation runtimes
// (>= Go 1.11), and Google App Engine flexible environment, it fetches
// credentials from the metadata server.
-// (In this final case any provided scopes are ignored.)
func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials, error) {
// First, try the environment variable.
const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
@@ -109,7 +108,7 @@
id, _ := metadata.ProjectID()
return &DefaultCredentials{
ProjectID: id,
- TokenSource: ComputeTokenSource(""),
+ TokenSource: ComputeTokenSource("", scopes...),
}, nil
}
diff --git a/google/example_test.go b/google/example_test.go
index 4338ca3..3fc9cad 100644
--- a/google/example_test.go
+++ b/google/example_test.go
@@ -126,7 +126,9 @@
// Fetch from Google Compute Engine's metadata server to retrieve
// an access token for the provided account.
// If no account is specified, "default" is used.
- Source: google.ComputeTokenSource(""),
+ // If no scopes are specified, a set of default scopes
+ // are automatically granted.
+ Source: google.ComputeTokenSource("", "https://www.googleapis.com/auth/bigquery"),
},
}
client.Get("...")
diff --git a/google/google.go b/google/google.go
index df8e87d..6eb2aa9 100644
--- a/google/google.go
+++ b/google/google.go
@@ -9,6 +9,7 @@
"encoding/json"
"errors"
"fmt"
+ "net/url"
"strings"
"time"
@@ -151,14 +152,16 @@
// from Google Compute Engine (GCE)'s metadata server. It's only valid to use
// this token source if your program is running on a GCE instance.
// If no account is specified, "default" is used.
+// If no scopes are specified, a set of default scopes are automatically granted.
// Further information about retrieving access tokens from the GCE metadata
// server can be found at https://cloud.google.com/compute/docs/authentication.
-func ComputeTokenSource(account string) oauth2.TokenSource {
- return oauth2.ReuseTokenSource(nil, computeSource{account: account})
+func ComputeTokenSource(account string, scope ...string) oauth2.TokenSource {
+ return oauth2.ReuseTokenSource(nil, computeSource{account: account, scopes: scope})
}
type computeSource struct {
account string
+ scopes []string
}
func (cs computeSource) Token() (*oauth2.Token, error) {
@@ -169,7 +172,13 @@
if acct == "" {
acct = "default"
}
- tokenJSON, err := metadata.Get("instance/service-accounts/" + acct + "/token")
+ tokenURI := "instance/service-accounts/" + acct + "/token"
+ if len(cs.scopes) > 0 {
+ v := url.Values{}
+ v.Set("scopes", strings.Join(cs.scopes, ","))
+ tokenURI = tokenURI + "?" + v.Encode()
+ }
+ tokenJSON, err := metadata.Get(tokenURI)
if err != nil {
return nil, err
}