fix(idtoken): allow WithCredentialsJSON to work with NewClient (#570)
Added new `internaloption.SkipDialSettingsValidation` that makes the call
to validate ClientOptions a no-op.
diff --git a/idtoken/idtoken.go b/idtoken/idtoken.go
index a5ee882..67c8965 100644
--- a/idtoken/idtoken.go
+++ b/idtoken/idtoken.go
@@ -16,6 +16,7 @@
"google.golang.org/api/internal"
"google.golang.org/api/option"
+ "google.golang.org/api/option/internaloption"
htransport "google.golang.org/api/transport/http"
)
@@ -50,7 +51,9 @@
if err != nil {
return nil, err
}
- opts = append(opts, option.WithTokenSource(ts))
+ // Skip DialSettings validation so added TokenSource will not conflict with user
+ // provided credentials.
+ opts = append(opts, option.WithTokenSource(ts), internaloption.SkipDialSettingsValidation())
t, err := htransport.NewTransport(ctx, http.DefaultTransport, opts...)
if err != nil {
return nil, err
diff --git a/integration-tests/idtoken/idtoken_test.go b/integration-tests/idtoken/idtoken_test.go
index e2cc4e9..65f3169 100644
--- a/integration-tests/idtoken/idtoken_test.go
+++ b/integration-tests/idtoken/idtoken_test.go
@@ -14,6 +14,7 @@
"testing"
"golang.org/x/oauth2"
+ "golang.org/x/oauth2/google"
"google.golang.org/api/idtoken"
"google.golang.org/api/option"
)
@@ -47,7 +48,7 @@
}
}
-func TestNewClient(t *testing.T) {
+func TestNewClient_WithCredentialFile(t *testing.T) {
aud := os.Getenv(envTokenAudience)
client, err := idtoken.NewClient(context.Background(), aud, option.WithCredentialsFile(os.Getenv(envCredentialFile)))
if err != nil {
@@ -65,3 +66,27 @@
t.Fatalf("got %q, want %q", validTok.Audience, aud)
}
}
+
+func TestNewClient_WithCredentialJSON(t *testing.T) {
+ aud := os.Getenv(envTokenAudience)
+ ctx := context.Background()
+ creds, err := google.FindDefaultCredentials(ctx)
+ if err != nil {
+ t.Fatalf("unable to find default creds: %v", err)
+ }
+ client, err := idtoken.NewClient(ctx, aud, option.WithCredentialsJSON(creds.JSON))
+ if err != nil {
+ t.Fatalf("unable to create Client: %v", err)
+ }
+ tok, err := client.Transport.(*oauth2.Transport).Source.Token()
+ if err != nil {
+ t.Fatalf("unable to retrieve Token: %v", err)
+ }
+ validTok, err := idtoken.Validate(context.Background(), tok.AccessToken, aud)
+ if err != nil {
+ t.Fatalf("token validation failed: %v", err)
+ }
+ if validTok.Audience != aud {
+ t.Fatalf("got %q, want %q", validTok.Audience, aud)
+ }
+}
diff --git a/internal/settings.go b/internal/settings.go
index f435519..3b779c2 100644
--- a/internal/settings.go
+++ b/internal/settings.go
@@ -38,6 +38,7 @@
TelemetryDisabled bool
ClientCertSource func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
CustomClaims map[string]interface{}
+ SkipValidation bool
// Google API system parameters. For more information please read:
// https://cloud.google.com/apis/docs/system-parameters
@@ -47,6 +48,9 @@
// Validate reports an error if ds is invalid.
func (ds *DialSettings) Validate() error {
+ if ds.SkipValidation {
+ return nil
+ }
hasCreds := ds.APIKey != "" || ds.TokenSource != nil || ds.CredentialsFile != "" || ds.Credentials != nil
if ds.NoAuth && hasCreds {
return errors.New("options.WithoutAuthentication is incompatible with any option that provides credentials")
diff --git a/option/internaloption/internaloption.go b/option/internaloption/internaloption.go
index ff5b530..d5debb7 100644
--- a/option/internaloption/internaloption.go
+++ b/option/internaloption/internaloption.go
@@ -34,7 +34,19 @@
// WithDefaultMTLSEndpoint is an option that indicates the default mTLS endpoint.
//
// It should only be used internally by generated clients.
-//
func WithDefaultMTLSEndpoint(url string) option.ClientOption {
return defaultMTLSEndpointOption(url)
}
+
+// SkipDialSettingsValidation bypasses validation on ClientOptions.
+//
+// It should only be used internally.
+func SkipDialSettingsValidation() option.ClientOption {
+ return skipDialSettingsValidation{}
+}
+
+type skipDialSettingsValidation struct{}
+
+func (s skipDialSettingsValidation) Apply(settings *internal.DialSettings) {
+ settings.SkipValidation = true
+}