Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(option): add internaloption to force use of certain credential #1162

Merged
merged 10 commits into from Aug 31, 2021
3 changes: 3 additions & 0 deletions internal/creds.go
Expand Up @@ -31,6 +31,9 @@ func Creds(ctx context.Context, ds *DialSettings) (*google.Credentials, error) {
}

func baseCreds(ctx context.Context, ds *DialSettings) (*google.Credentials, error) {
if ds.InternalCredentials != nil {
return ds.InternalCredentials, nil
}
if ds.Credentials != nil {
return ds.Credentials, nil
}
Expand Down
59 changes: 59 additions & 0 deletions internal/creds_test.go
Expand Up @@ -236,3 +236,62 @@ func TestQuotaProjectFromCreds(t *testing.T) {
t.Errorf("QuotaProjectFromCreds(quotaProjectJSON): want %q, got %q", want, got)
}
}

func TestCredsWithCredentials(t *testing.T) {
tests := []struct {
name string
ds *DialSettings
want string
}{
{
name: "only normal opt",
ds: &DialSettings{
Credentials: &google.Credentials{
TokenSource: oauth2.StaticTokenSource(&oauth2.Token{
AccessToken: "normal",
}),
},
},
want: "normal",
},
{
name: "normal and internal creds opt",
ds: &DialSettings{
Credentials: &google.Credentials{
TokenSource: oauth2.StaticTokenSource(&oauth2.Token{
AccessToken: "normal",
}),
},
InternalCredentials: &google.Credentials{
TokenSource: oauth2.StaticTokenSource(&oauth2.Token{
AccessToken: "internal",
}),
},
},
want: "internal",
},
{
name: "only internal creds opt",
ds: &DialSettings{
InternalCredentials: &google.Credentials{
TokenSource: oauth2.StaticTokenSource(&oauth2.Token{
AccessToken: "internal",
}),
},
},
want: "internal",
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
creds, err := Creds(context.Background(), tc.ds)
if err != nil {
t.Fatalf("got %v, want nil error", err)
}
if tok, _ := creds.TokenSource.Token(); tok.AccessToken != tc.want {
t.Fatalf("tok.AccessToken = %q, want %q", tok.AccessToken, tc.want)
}
})
}
}
1 change: 1 addition & 0 deletions internal/settings.go
Expand Up @@ -45,6 +45,7 @@ type DialSettings struct {
SkipValidation bool
ImpersonationConfig *impersonate.Config
EnableDirectPath bool
InternalCredentials *google.Credentials

// Google API system parameters. For more information please read:
// https://cloud.google.com/apis/docs/system-parameters
Expand Down
13 changes: 13 additions & 0 deletions option/internaloption/internaloption.go
Expand Up @@ -6,6 +6,7 @@
package internaloption

import (
"golang.org/x/oauth2/google"
"google.golang.org/api/internal"
"google.golang.org/api/option"
)
Expand Down Expand Up @@ -106,3 +107,15 @@ type enableJwtWithScope bool
func (w enableJwtWithScope) Apply(o *internal.DialSettings) {
o.EnableJwtWithScope = bool(w)
}

// WithCredentials returns a client option to specify authenticates API calls.
BrennaEpp marked this conversation as resolved.
Show resolved Hide resolved
// This credential takes precedence over all other credential options.
func WithCredentials(creds *google.Credentials) option.ClientOption {
return (*withCreds)(creds)
}

type withCreds google.Credentials

func (w *withCreds) Apply(o *internal.DialSettings) {
o.InternalCredentials = (*google.Credentials)(w)
}
29 changes: 29 additions & 0 deletions option/internaloption/internaloption_test.go
@@ -0,0 +1,29 @@
// Copyright 2021 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package internaloption

import (
"testing"

"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/internal"
)

func TestWithCredentials(t *testing.T) {
want := "fakeToken"
fakeCreds := &google.Credentials{
TokenSource: oauth2.StaticTokenSource(&oauth2.Token{AccessToken: want}),
}
opt := WithCredentials(fakeCreds)
ds := &internal.DialSettings{}
opt.Apply(ds)
if ds.InternalCredentials == nil || ds.InternalCredentials.TokenSource == nil {
t.Errorf("ds.InternalCredentials should be initialized")
}
if tok, err := ds.InternalCredentials.TokenSource.Token(); err != nil || tok.AccessToken != "fakeToken" {
t.Errorf("ts.Token() = %q, want %q", tok.AccessToken, "")
}
}