diff --git a/internal/creds.go b/internal/creds.go index ebb18f3281f..b927fae5c57 100644 --- a/internal/creds.go +++ b/internal/creds.go @@ -63,12 +63,14 @@ const ( serviceAccountKey = "service_account" ) -// credentialsFromJSON returns a google.Credentials based on the input. +// credentialsFromJSON returns a google.Credentials from the JSON data // // - A self-signed JWT flow will be executed if the following conditions are // met: -// (1) Either the scope for self-signed JWT flow is enabled or audiences are -// explicitly provided by users. +// (1) At least one of the following is true: +// (a) Scope for self-signed JWT flow is enabled +// (b) Audiences are explicitly provided by users +// (b) No scope is provided // (2) No service account impersontation // // - Otherwise, executes standard OAuth 2.0 flow @@ -97,7 +99,7 @@ func credentialsFromJSON(ctx context.Context, data []byte, ds *DialSettings) (*g } func isSelfSignedJWTFlow(data []byte, ds *DialSettings) (bool, error) { - if (ds.EnableJwtWithScope || ds.HasCustomAudience()) && + if (ds.EnableJwtWithScope || ds.HasCustomAudience() || len(ds.GetScopes()) == 0) && ds.ImpersonationConfig == nil { // Check if JSON is a service account and if so create a self-signed JWT. var f struct { diff --git a/internal/creds_test.go b/internal/creds_test.go index 39fe9d11b85..ecdae563187 100644 --- a/internal/creds_test.go +++ b/internal/creds_test.go @@ -118,6 +118,56 @@ func TestJWTWithScope(t *testing.T) { } } +func TestJWTWithDefaultScopes(t *testing.T) { + ctx := context.Background() + + // Load a valid JSON file. No way to really test the contents; we just + // verify that there is no error. + ds := &DialSettings{ + CredentialsFile: "testdata/service-account.json", + DefaultScopes: []string{"foo"}, + EnableJwtWithScope: true, + } + if _, err := Creds(ctx, ds); err != nil { + t.Errorf("got %v, wanted no error", err) + } + + // Load valid JSON. No way to really test the contents; we just + // verify that there is no error. + ds = &DialSettings{ + CredentialsJSON: []byte(validServiceAccountJSON), + DefaultScopes: []string{"foo"}, + EnableJwtWithScope: true, + } + if _, err := Creds(ctx, ds); err != nil { + t.Errorf("got %v, wanted no error", err) + } +} + +func TestJWTWithDefaultAudience(t *testing.T) { + ctx := context.Background() + + // Load a valid JSON file. No way to really test the contents; we just + // verify that there is no error. + ds := &DialSettings{ + CredentialsFile: "testdata/service-account.json", + DefaultAudience: "foo", + } + if _, err := Creds(ctx, ds); err != nil { + t.Errorf("got %v, wanted no error", err) + } + + // Load valid JSON. No way to really test the contents; we just + // verify that there is no error. + ds = &DialSettings{ + CredentialsJSON: []byte(validServiceAccountJSON), + DefaultAudience: "foo", + } + if _, err := Creds(ctx, ds); err != nil { + t.Errorf("got %v, wanted no error", err) + } +} + func TestOAuth(t *testing.T) { ctx := context.Background()