From c1fb85aa9738a262d899a82e4fddcbef5a809621 Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Thu, 12 Aug 2021 10:24:45 -0500 Subject: [PATCH 1/4] feat(option): add internaloption to force the client to use a certain credential --- internal/creds | 0 internal/creds.go | 3 + internal/creds_test.go | 59 ++++++++++++++++++++ internal/settings.go | 1 + option/internaloption/internaloption.go | 13 +++++ option/internaloption/internaloption_test.go | 25 +++++++++ 6 files changed, 101 insertions(+) create mode 100644 internal/creds create mode 100644 option/internaloption/internaloption_test.go diff --git a/internal/creds b/internal/creds new file mode 100644 index 00000000000..e69de29bb2d diff --git a/internal/creds.go b/internal/creds.go index 855604b75df..b067a179b7a 100644 --- a/internal/creds.go +++ b/internal/creds.go @@ -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 } diff --git a/internal/creds_test.go b/internal/creds_test.go index ecdae563187..34b052dcb29 100644 --- a/internal/creds_test.go +++ b/internal/creds_test.go @@ -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) + } + }) + } +} diff --git a/internal/settings.go b/internal/settings.go index 89c7bc86fa3..1b518485b71 100644 --- a/internal/settings.go +++ b/internal/settings.go @@ -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 diff --git a/option/internaloption/internaloption.go b/option/internaloption/internaloption.go index ed0b7aaf13e..6f73d04e2cb 100644 --- a/option/internaloption/internaloption.go +++ b/option/internaloption/internaloption.go @@ -6,6 +6,7 @@ package internaloption import ( + "golang.org/x/oauth2/google" "google.golang.org/api/internal" "google.golang.org/api/option" ) @@ -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. +// 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) +} diff --git a/option/internaloption/internaloption_test.go b/option/internaloption/internaloption_test.go new file mode 100644 index 00000000000..3de562b8b2a --- /dev/null +++ b/option/internaloption/internaloption_test.go @@ -0,0 +1,25 @@ +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, "") + } +} From 6edd9be130e02708aad14b00568ddcd25ab1b2c0 Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Thu, 12 Aug 2021 11:17:31 -0500 Subject: [PATCH 2/4] Delete extra file --- internal/creds | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 internal/creds diff --git a/internal/creds b/internal/creds deleted file mode 100644 index e69de29bb2d..00000000000 From 8536bddccd740fa930362116dce50f0516e03731 Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Thu, 12 Aug 2021 14:20:42 -0500 Subject: [PATCH 3/4] Add copyright header --- option/internaloption/internaloption_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/option/internaloption/internaloption_test.go b/option/internaloption/internaloption_test.go index 3de562b8b2a..0ad09f8c236 100644 --- a/option/internaloption/internaloption_test.go +++ b/option/internaloption/internaloption_test.go @@ -1,3 +1,7 @@ +// 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 ( From 146ab4f384b35c1a8df89e32b146938cb4caa3da Mon Sep 17 00:00:00 2001 From: Brenna Epp Date: Thu, 19 Aug 2021 12:25:48 -0500 Subject: [PATCH 4/4] fix comment --- option/internaloption/internaloption.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/option/internaloption/internaloption.go b/option/internaloption/internaloption.go index 6f73d04e2cb..02f78ae0302 100644 --- a/option/internaloption/internaloption.go +++ b/option/internaloption/internaloption.go @@ -108,7 +108,7 @@ func (w enableJwtWithScope) Apply(o *internal.DialSettings) { o.EnableJwtWithScope = bool(w) } -// WithCredentials returns a client option to specify authenticates API calls. +// WithCredentials returns a client option to specify credentials which will be used to authenticate API calls. // This credential takes precedence over all other credential options. func WithCredentials(creds *google.Credentials) option.ClientOption { return (*withCreds)(creds)