google: Support scopes for ComputeTokenSource

This commit is contained in:
Steven Buss 2019-03-29 15:41:50 -07:00
parent c85d3e98c9
commit 1cb4a6ec12
3 changed files with 16 additions and 6 deletions

View File

@ -73,7 +73,6 @@ func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSourc
// 4. On Google Compute Engine, Google App Engine standard second generation runtimes // 4. On Google Compute Engine, Google App Engine standard second generation runtimes
// (>= Go 1.11), and Google App Engine flexible environment, it fetches // (>= Go 1.11), and Google App Engine flexible environment, it fetches
// credentials from the metadata server. // credentials from the metadata server.
// (In this final case any provided scopes are ignored.)
func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials, error) { func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials, error) {
// First, try the environment variable. // First, try the environment variable.
const envVar = "GOOGLE_APPLICATION_CREDENTIALS" const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
@ -109,7 +108,7 @@ func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials
id, _ := metadata.ProjectID() id, _ := metadata.ProjectID()
return &DefaultCredentials{ return &DefaultCredentials{
ProjectID: id, ProjectID: id,
TokenSource: ComputeTokenSource(""), TokenSource: ComputeTokenSource("", scopes...),
}, nil }, nil
} }

View File

@ -126,7 +126,9 @@ func ExampleComputeTokenSource() {
// Fetch from Google Compute Engine's metadata server to retrieve // Fetch from Google Compute Engine's metadata server to retrieve
// an access token for the provided account. // an access token for the provided account.
// If no account is specified, "default" is used. // 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("...") client.Get("...")

View File

@ -9,6 +9,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"net/url"
"strings" "strings"
"time" "time"
@ -151,14 +152,16 @@ func (f *credentialsFile) tokenSource(ctx context.Context, scopes []string) (oau
// from Google Compute Engine (GCE)'s metadata server. It's only valid to use // 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. // this token source if your program is running on a GCE instance.
// If no account is specified, "default" is used. // 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 // Further information about retrieving access tokens from the GCE metadata
// server can be found at https://cloud.google.com/compute/docs/authentication. // server can be found at https://cloud.google.com/compute/docs/authentication.
func ComputeTokenSource(account string) oauth2.TokenSource { func ComputeTokenSource(account string, scope ...string) oauth2.TokenSource {
return oauth2.ReuseTokenSource(nil, computeSource{account: account}) return oauth2.ReuseTokenSource(nil, computeSource{account: account, scopes: scope})
} }
type computeSource struct { type computeSource struct {
account string account string
scopes []string
} }
func (cs computeSource) Token() (*oauth2.Token, error) { func (cs computeSource) Token() (*oauth2.Token, error) {
@ -169,7 +172,13 @@ func (cs computeSource) Token() (*oauth2.Token, error) {
if acct == "" { if acct == "" {
acct = "default" 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 { if err != nil {
return nil, err return nil, err
} }