Skip to content

Commit

Permalink
google: add Credentials.UniverseDomain to support TPC
Browse files Browse the repository at this point in the history
Read and expose universe_domain from service account JSON files in
CredentialsFromJSONWithParams to support TPC in 1p clients.

Change-Id: I3518a0ec8be5ff7235b946cffd88b26ac8d303cf
Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/531715
Run-TryBot: Cody Oss <codyoss@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cody Oss <codyoss@google.com>
  • Loading branch information
quartzmo authored and codyoss committed Sep 29, 2023
1 parent 43b6a7b commit 8d6d45b
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 13 deletions.
25 changes: 21 additions & 4 deletions google/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ import (
"golang.org/x/oauth2/authhandler"
)

const adcSetupURL = "https://cloud.google.com/docs/authentication/external/set-up-adc"
const (
adcSetupURL = "https://cloud.google.com/docs/authentication/external/set-up-adc"
universeDomainDefault = "googleapis.com"
)

// Credentials holds Google credentials, including "Application Default Credentials".
// For more details, see:
Expand All @@ -37,6 +40,18 @@ type Credentials struct {
// environment and not with a credentials file, e.g. when code is
// running on Google Cloud Platform.
JSON []byte

// universeDomain is the default service domain for a given Cloud universe.
universeDomain string
}

// UniverseDomain returns the default service domain for a given Cloud universe.
// The default value is "googleapis.com".
func (c *Credentials) UniverseDomain() string {
if c.universeDomain == "" {
return universeDomainDefault
}
return c.universeDomain
}

// DefaultCredentials is the old name of Credentials.
Expand Down Expand Up @@ -200,15 +215,17 @@ func CredentialsFromJSONWithParams(ctx context.Context, jsonData []byte, params
if err := json.Unmarshal(jsonData, &f); err != nil {
return nil, err
}

ts, err := f.tokenSource(ctx, params)
if err != nil {
return nil, err
}
ts = newErrWrappingTokenSource(ts)
return &Credentials{
ProjectID: f.ProjectID,
TokenSource: ts,
JSON: jsonData,
ProjectID: f.ProjectID,
TokenSource: ts,
JSON: jsonData,
universeDomain: f.UniverseDomain,
}, nil
}

Expand Down
43 changes: 43 additions & 0 deletions google/default_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package google

import (
"context"
"testing"
)

var jwtJSONKeyUniverseDomain = []byte(`{
"type": "service_account",
"project_id": "fake_project",
"universe_domain": "example.com",
"private_key_id": "268f54e43a1af97cfc71731688434f45aca15c8b",
"private_key": "super secret key",
"client_email": "gopher@developer.gserviceaccount.com",
"client_id": "gopher.apps.googleusercontent.com",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gopher%40fake_project.iam.gserviceaccount.com"
}`)

func TestCredentialsFromJSONWithParams_UniverseDomain(t *testing.T) {
ctx := context.Background()
scope := "https://www.googleapis.com/auth/cloud-platform"
params := CredentialsParams{
Scopes: []string{scope},
}
creds, err := CredentialsFromJSONWithParams(ctx, jwtJSONKeyUniverseDomain, params)
if err != nil {
t.Fatal(err)
}

if want := "fake_project"; creds.ProjectID != want {
t.Fatalf("got %q, want %q", creds.ProjectID, want)
}
if want := "example.com"; creds.UniverseDomain() != want {
t.Fatalf("got %q, want %q", creds.UniverseDomain(), want)
}
}
19 changes: 10 additions & 9 deletions google/google.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ import (

// Endpoint is Google's OAuth 2.0 default endpoint.
var Endpoint = oauth2.Endpoint{
AuthURL: "https://accounts.google.com/o/oauth2/auth",
TokenURL: "https://oauth2.googleapis.com/token",
AuthURL: "https://accounts.google.com/o/oauth2/auth",
TokenURL: "https://oauth2.googleapis.com/token",
DeviceAuthURL: "https://oauth2.googleapis.com/device/code",
AuthStyle: oauth2.AuthStyleInParams,
AuthStyle: oauth2.AuthStyleInParams,
}

// MTLSTokenURL is Google's OAuth 2.0 default mTLS endpoint.
Expand Down Expand Up @@ -109,12 +109,13 @@ type credentialsFile struct {
Type string `json:"type"`

// Service Account fields
ClientEmail string `json:"client_email"`
PrivateKeyID string `json:"private_key_id"`
PrivateKey string `json:"private_key"`
AuthURL string `json:"auth_uri"`
TokenURL string `json:"token_uri"`
ProjectID string `json:"project_id"`
ClientEmail string `json:"client_email"`
PrivateKeyID string `json:"private_key_id"`
PrivateKey string `json:"private_key"`
AuthURL string `json:"auth_uri"`
TokenURL string `json:"token_uri"`
ProjectID string `json:"project_id"`
UniverseDomain string `json:"universe_domain"`

// User Credential fields
// (These typically come from gcloud auth.)
Expand Down

0 comments on commit 8d6d45b

Please sign in to comment.