From 1a04bafa83c27342b9308d785645e1e5423ea10d Mon Sep 17 00:00:00 2001 From: Cody Oss <6331106+codyoss@users.noreply.github.com> Date: Fri, 15 Mar 2024 16:51:06 -0500 Subject: [PATCH] feat(auth): move credentials to base auth package (#9590) We are moving the credentials struct to the base auth package as we intend to use this as the main abstraction for this library. To better support the new idea of universes having access to the full credential object will be crucial for the client libraries. Also, the detect package has been renamed to `credentials` to make it more generic in the future. We have plans on directly exposing packages like `externalaccount` in the future so having a better name here makes sense. This is the first of two large breaking changes for this module. This module not in use by our libraries yet, is version 0.1.X and has always been explicitly labeled experimental in the readme. As such, we feel comfortable making these changes for the long term health of the module. --- auth/auth.go | 108 +++++++++++ auth/{detect => credentials}/compute.go | 2 +- auth/{detect => credentials}/compute_test.go | 2 +- auth/{detect => credentials}/detect.go | 91 +++------- auth/{detect => credentials}/detect_test.go | 169 ++++++++++++------ auth/{detect => credentials}/doc.go | 6 +- auth/{detect => credentials}/example_test.go | 16 +- auth/{detect => credentials}/filetypes.go | 37 ++-- .../internal/externalaccount/aws_provider.go | 0 .../externalaccount/aws_provider_test.go | 0 .../externalaccount/executable_provider.go | 0 .../executable_provider_test.go | 0 .../externalaccount/externalaccount.go | 4 +- .../externalaccount/externalaccount_test.go | 0 .../internal/externalaccount/file_provider.go | 0 .../externalaccount/file_provider_test.go | 0 .../externalaccount/impersonate_test.go | 0 .../internal/externalaccount/info.go | 0 .../internal/externalaccount/info_test.go | 0 .../externalaccount/testdata/3pi_cred.json | 0 .../externalaccount/testdata/3pi_cred.txt | 0 .../internal/externalaccount/url_provider.go | 0 .../externalaccount/url_provider_test.go | 0 .../externalaccountuser.go | 2 +- .../externalaccountuser_test.go | 2 +- .../internal/gdch/gdch.go | 0 .../internal/gdch/gdch_test.go | 0 .../internal/impersonate/impersonate.go | 0 .../internal/impersonate/impersonate_test.go | 0 .../internal/stsexchange/sts_exchange.go | 0 .../internal/stsexchange/sts_exchange_test.go | 0 auth/{detect => credentials}/selfsignedjwt.go | 4 +- .../selfsignedjwt_test.go | 6 +- auth/downscope/example_test.go | 4 +- auth/downscope/integration_test.go | 4 +- auth/grpctransport/directpath.go | 2 +- auth/grpctransport/grpctransport.go | 19 +- auth/grpctransport/grpctransport_test.go | 38 ++-- auth/httptransport/httptransport.go | 6 +- auth/httptransport/httptransport_test.go | 38 ++-- auth/httptransport/transport.go | 9 +- auth/idtoken/file.go | 4 +- auth/impersonate/integration_test.go | 15 +- auth/internal/internal.go | 15 ++ auth/internal/transport/transport.go | 8 +- auth/internal/transport/transport_test.go | 6 +- 46 files changed, 390 insertions(+), 227 deletions(-) rename auth/{detect => credentials}/compute.go (99%) rename auth/{detect => credentials}/compute_test.go (98%) rename auth/{detect => credentials}/detect.go (74%) rename auth/{detect => credentials}/detect_test.go (83%) rename auth/{detect => credentials}/doc.go (96%) rename auth/{detect => credentials}/example_test.go (84%) rename auth/{detect => credentials}/filetypes.go (81%) rename auth/{detect => credentials}/internal/externalaccount/aws_provider.go (100%) rename auth/{detect => credentials}/internal/externalaccount/aws_provider_test.go (100%) rename auth/{detect => credentials}/internal/externalaccount/executable_provider.go (100%) rename auth/{detect => credentials}/internal/externalaccount/executable_provider_test.go (100%) rename auth/{detect => credentials}/internal/externalaccount/externalaccount.go (98%) rename auth/{detect => credentials}/internal/externalaccount/externalaccount_test.go (100%) rename auth/{detect => credentials}/internal/externalaccount/file_provider.go (100%) rename auth/{detect => credentials}/internal/externalaccount/file_provider_test.go (100%) rename auth/{detect => credentials}/internal/externalaccount/impersonate_test.go (100%) rename auth/{detect => credentials}/internal/externalaccount/info.go (100%) rename auth/{detect => credentials}/internal/externalaccount/info_test.go (100%) rename auth/{detect => credentials}/internal/externalaccount/testdata/3pi_cred.json (100%) rename auth/{detect => credentials}/internal/externalaccount/testdata/3pi_cred.txt (100%) rename auth/{detect => credentials}/internal/externalaccount/url_provider.go (100%) rename auth/{detect => credentials}/internal/externalaccount/url_provider_test.go (100%) rename auth/{detect => credentials}/internal/externalaccountuser/externalaccountuser.go (98%) rename auth/{detect => credentials}/internal/externalaccountuser/externalaccountuser_test.go (98%) rename auth/{detect => credentials}/internal/gdch/gdch.go (100%) rename auth/{detect => credentials}/internal/gdch/gdch_test.go (100%) rename auth/{detect => credentials}/internal/impersonate/impersonate.go (100%) rename auth/{detect => credentials}/internal/impersonate/impersonate_test.go (100%) rename auth/{detect => credentials}/internal/stsexchange/sts_exchange.go (100%) rename auth/{detect => credentials}/internal/stsexchange/sts_exchange_test.go (100%) rename auth/{detect => credentials}/selfsignedjwt.go (96%) rename auth/{detect => credentials}/selfsignedjwt_test.go (98%) diff --git a/auth/auth.go b/auth/auth.go index 9099c0b640a..e26802f1ea7 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -40,6 +40,8 @@ const ( // 3 minutes and 45 seconds before expiration. The shortest MDS cache is 4 minutes, // so we give it 15 seconds to refresh it's cache before attempting to refresh a token. defaultExpiryDelta = 215 * time.Second + + universeDomainDefault = "googleapis.com" ) var ( @@ -94,6 +96,112 @@ func (t *Token) isValidWithEarlyExpiry(earlyExpiry time.Duration) bool { return !t.Expiry.Round(0).Add(-earlyExpiry).Before(timeNow()) } +// Credentials holds Google credentials, including +// [Application Default Credentials](https://developers.google.com/accounts/docs/application-default-credentials). +type Credentials struct { + json []byte + projectID CredentialsPropertyProvider + quotaProjectID CredentialsPropertyProvider + // universeDomain is the default service domain for a given Cloud universe. + universeDomain CredentialsPropertyProvider + + TokenProvider +} + +// JSON returns the bytes associated with the the file used to source +// credentials if one was used. +func (c *Credentials) JSON() []byte { + return c.json +} + +// ProjectID returns the associated project ID from the underlying file or +// environment. +func (c *Credentials) ProjectID(ctx context.Context) (string, error) { + if c.projectID == nil { + return internal.GetProjectID(c.json, ""), nil + } + v, err := c.projectID.GetProperty(ctx) + if err != nil { + return "", err + } + return internal.GetProjectID(c.json, v), nil +} + +// QuotaProjectID returns the associated quota project ID from the underlying +// file or environment. +func (c *Credentials) QuotaProjectID(ctx context.Context) (string, error) { + if c.quotaProjectID == nil { + return internal.GetQuotaProject(c.json, ""), nil + } + v, err := c.quotaProjectID.GetProperty(ctx) + if err != nil { + return "", err + } + return internal.GetQuotaProject(c.json, v), nil +} + +// UniverseDomain returns the default service domain for a given Cloud universe. +// The default value is "googleapis.com". +func (c *Credentials) UniverseDomain(ctx context.Context) (string, error) { + if c.universeDomain == nil { + return universeDomainDefault, nil + } + v, err := c.universeDomain.GetProperty(ctx) + if err != nil { + return "", err + } + if v == "" { + return universeDomainDefault, nil + } + return v, err +} + +// CredentialsPropertyProvider provides an implementation to fetch a property +// value for [Credentials]. +type CredentialsPropertyProvider interface { + GetProperty(context.Context) (string, error) +} + +// CredentialsPropertyFunc is a type adapter to allow the use of ordinary +// functions as a [CredentialsPropertyProvider]. +type CredentialsPropertyFunc func(context.Context) (string, error) + +// GetProperty loads the properly value provided the given context. +func (p CredentialsPropertyFunc) GetProperty(ctx context.Context) (string, error) { + return p(ctx) +} + +// CredentialsOptions are used to configure [Credentials]. +type CredentialsOptions struct { + // TokenProvider is a means of sourcing a token for the credentials. Required. + TokenProvider TokenProvider + // JSON is the raw contents of the credentials file if sourced from a file. + JSON []byte + // ProjectIDProvider resolves the project ID associated with the + // credentials. + ProjectIDProvider CredentialsPropertyProvider + // QuotaProjectIDProvider resolves the quota project ID associated with the + // credentials. + QuotaProjectIDProvider CredentialsPropertyProvider + // UniverseDomainProvider resolves the universe domain with the credentials. + UniverseDomainProvider CredentialsPropertyProvider +} + +// NewCredentials returns new [Credentials] from the provided options. Most users +// will want to build this object a function from the +// [cloud.google.com/go/auth/credentials] package. +func NewCredentials(opts *CredentialsOptions) *Credentials { + creds := &Credentials{ + TokenProvider: opts.TokenProvider, + json: opts.JSON, + projectID: opts.ProjectIDProvider, + quotaProjectID: opts.QuotaProjectIDProvider, + universeDomain: opts.UniverseDomainProvider, + } + + return creds +} + // CachedTokenProviderOptions provided options for configuring a // CachedTokenProvider. type CachedTokenProviderOptions struct { diff --git a/auth/detect/compute.go b/auth/credentials/compute.go similarity index 99% rename from auth/detect/compute.go rename to auth/credentials/compute.go index 430026a98a0..74c1d52e0ea 100644 --- a/auth/detect/compute.go +++ b/auth/credentials/compute.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package detect +package credentials import ( "context" diff --git a/auth/detect/compute_test.go b/auth/credentials/compute_test.go similarity index 98% rename from auth/detect/compute_test.go rename to auth/credentials/compute_test.go index 4a1e751fd26..0b5eca6ce41 100644 --- a/auth/detect/compute_test.go +++ b/auth/credentials/compute_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package detect +package credentials import ( "context" diff --git a/auth/detect/detect.go b/auth/credentials/detect.go similarity index 74% rename from auth/detect/detect.go rename to auth/credentials/detect.go index 784c4d74a93..24d153bb8b9 100644 --- a/auth/detect/detect.go +++ b/auth/credentials/detect.go @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -package detect +package credentials import ( + "context" "encoding/json" "errors" "fmt" @@ -38,8 +39,6 @@ const ( // Help on default credentials adcSetupURL = "https://cloud.google.com/docs/authentication/external/set-up-adc" - - universeDomainDefault = "googleapis.com" ) var ( @@ -47,63 +46,14 @@ var ( allowOnGCECheck = true ) -// Credentials holds Google credentials, including -// [Application Default Credentials](https://developers.google.com/accounts/docs/application-default-credentials). -type Credentials struct { - json []byte - projectID string - quotaProjectID string - // universeDomain is the default service domain for a given Cloud universe. - universeDomain string - - auth.TokenProvider -} - -func newCredentials(tokenProvider auth.TokenProvider, json []byte, projectID string, quotaProjectID string, universeDomain string) *Credentials { - return &Credentials{ - json: json, - projectID: internal.GetProjectID(json, projectID), - quotaProjectID: internal.GetQuotaProject(json, quotaProjectID), - TokenProvider: tokenProvider, - universeDomain: universeDomain, - } -} - -// JSON returns the bytes associated with the the file used to source -// credentials if one was used. -func (c *Credentials) JSON() []byte { - return c.json -} - -// ProjectID returns the associated project ID from the underlying file or -// environment. -func (c *Credentials) ProjectID() string { - return c.projectID -} - -// QuotaProjectID returns the associated quota project ID from the underlying -// file or environment. -func (c *Credentials) QuotaProjectID() string { - return c.quotaProjectID -} - -// 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 -} - // OnGCE reports whether this process is running in Google Cloud. func OnGCE() bool { // TODO(codyoss): once all libs use this auth lib move metadata check here return allowOnGCECheck && metadata.OnGCE() } -// DefaultCredentials searches for "Application Default Credentials" and returns -// a credential based on the [Options] provided. +// DetectDefault searches for "Application Default Credentials" and returns +// a credential based on the [DetectOptions] provided. // // It looks for credentials in the following places, preferring the first // location found: @@ -119,7 +69,7 @@ func OnGCE() bool { // - On Google Compute Engine, Google App Engine standard second generation // runtimes, and Google App Engine flexible environment, it fetches // credentials from the metadata server. -func DefaultCredentials(opts *Options) (*Credentials, error) { +func DetectDefault(opts *DetectOptions) (*auth.Credentials, error) { if err := opts.validate(); err != nil { return nil, err } @@ -138,15 +88,19 @@ func DefaultCredentials(opts *Options) (*Credentials, error) { } if OnGCE() { - id, _ := metadata.ProjectID() - return newCredentials(computeTokenProvider(opts.EarlyTokenRefresh, opts.Scopes...), nil, id, "", ""), nil + return auth.NewCredentials(&auth.CredentialsOptions{ + TokenProvider: computeTokenProvider(opts.EarlyTokenRefresh, opts.Scopes...), + ProjectIDProvider: auth.CredentialsPropertyFunc(func(context.Context) (string, error) { + return metadata.ProjectID() + }), + }), nil } return nil, fmt.Errorf("detect: could not find default credentials. See %v for more information", adcSetupURL) } -// Options provides configuration for [DefaultCredentials]. -type Options struct { +// DetectOptions provides configuration for [DetectDefault]. +type DetectOptions struct { // Scopes that credentials tokens should have. Example: // https://www.googleapis.com/auth/cloud-platform. Required if Audience is // not provided. @@ -188,7 +142,7 @@ type Options struct { Client *http.Client } -func (o *Options) validate() error { +func (o *DetectOptions) validate() error { if o == nil { return errors.New("detect: options must be provided") } @@ -201,27 +155,27 @@ func (o *Options) validate() error { return nil } -func (o *Options) tokenURL() string { +func (o *DetectOptions) tokenURL() string { if o.TokenURL != "" { return o.TokenURL } return googleTokenURL } -func (o *Options) scopes() []string { +func (o *DetectOptions) scopes() []string { scopes := make([]string, len(o.Scopes)) copy(scopes, o.Scopes) return scopes } -func (o *Options) client() *http.Client { +func (o *DetectOptions) client() *http.Client { if o.Client != nil { return o.Client } return internal.CloneDefaultClient() } -func readCredentialsFile(filename string, opts *Options) (*Credentials, error) { +func readCredentialsFile(filename string, opts *DetectOptions) (*auth.Credentials, error) { b, err := os.ReadFile(filename) if err != nil { return nil, err @@ -229,7 +183,7 @@ func readCredentialsFile(filename string, opts *Options) (*Credentials, error) { return readCredentialsFileJSON(b, opts) } -func readCredentialsFileJSON(b []byte, opts *Options) (*Credentials, error) { +func readCredentialsFileJSON(b []byte, opts *DetectOptions) (*auth.Credentials, error) { // attempt to parse jsonData as a Google Developers Console client_credentials.json. config := clientCredConfigFromJSON(b, opts) if config != nil { @@ -240,12 +194,15 @@ func readCredentialsFileJSON(b []byte, opts *Options) (*Credentials, error) { if err != nil { return nil, err } - return newCredentials(tp, b, "", "", ""), nil + return auth.NewCredentials(&auth.CredentialsOptions{ + TokenProvider: tp, + JSON: b, + }), nil } return fileCredentials(b, opts) } -func clientCredConfigFromJSON(b []byte, opts *Options) *auth.Options3LO { +func clientCredConfigFromJSON(b []byte, opts *DetectOptions) *auth.Options3LO { var creds internaldetect.ClientCredentialsFile var c *internaldetect.Config3LO if err := json.Unmarshal(b, &creds); err != nil { diff --git a/auth/detect/detect_test.go b/auth/credentials/detect_test.go similarity index 83% rename from auth/detect/detect_test.go rename to auth/credentials/detect_test.go index 57983331b33..20e77cc98f0 100644 --- a/auth/detect/detect_test.go +++ b/auth/credentials/detect_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package detect +package credentials import ( "context" @@ -27,7 +27,7 @@ import ( "time" "cloud.google.com/go/auth" - "cloud.google.com/go/auth/detect/internal/gdch" + "cloud.google.com/go/auth/credentials/internal/gdch" "cloud.google.com/go/auth/internal" "cloud.google.com/go/auth/internal/internaldetect" "cloud.google.com/go/auth/internal/jwt" @@ -40,6 +40,7 @@ type tokResp struct { } func TestDefaultCredentials_GdchServiceAccountKey(t *testing.T) { + ctx := context.Background() aud := "http://sampele-aud.com/" b, err := os.ReadFile("../internal/testdata/gdch.json") if err != nil { @@ -112,22 +113,29 @@ func TestDefaultCredentials_GdchServiceAccountKey(t *testing.T) { t.Fatal(err) } - if _, err := DefaultCredentials(&Options{CredentialsJSON: b}); err == nil { + if _, err := DetectDefault(&DetectOptions{CredentialsJSON: b}); err == nil { t.Fatal("STSAudience should be required") } - creds, err := DefaultCredentials(&Options{ + creds, err := DetectDefault(&DetectOptions{ CredentialsJSON: b, STSAudience: aud, }) if err != nil { t.Fatal(err) } - - if want := "fake_project"; creds.ProjectID() != want { - t.Fatalf("got %q, want %q", creds.ProjectID(), want) + got, err := creds.ProjectID(ctx) + if err != nil { + t.Fatal(err) + } + if want := "fake_project"; got != want { + t.Fatalf("got %q, want %q", got, want) + } + got, err = creds.UniverseDomain(ctx) + if err != nil { + t.Fatal(err) } - if want := "googleapis.com"; creds.UniverseDomain() != want { - t.Fatalf("got %q, want %q", creds.UniverseDomain(), want) + if want := "googleapis.com"; got != want { + t.Fatalf("got %q, want %q", got, want) } tok, err := creds.Token(context.Background()) if err != nil { @@ -142,6 +150,7 @@ func TestDefaultCredentials_GdchServiceAccountKey(t *testing.T) { } func TestDefaultCredentials_ImpersonatedServiceAccountKey(t *testing.T) { + ctx := context.Background() b, err := os.ReadFile("../internal/testdata/imp.json") if err != nil { t.Fatal(err) @@ -168,7 +177,7 @@ func TestDefaultCredentials_ImpersonatedServiceAccountKey(t *testing.T) { t.Fatal(err) } - creds, err := DefaultCredentials(&Options{ + creds, err := DetectDefault(&DetectOptions{ CredentialsJSON: b, Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, UseSelfSignedJWT: true, @@ -176,8 +185,12 @@ func TestDefaultCredentials_ImpersonatedServiceAccountKey(t *testing.T) { if err != nil { t.Fatal(err) } - if want := "googleapis.com"; creds.UniverseDomain() != want { - t.Fatalf("got %q, want %q", creds.UniverseDomain(), want) + got, err := creds.UniverseDomain(ctx) + if err != nil { + t.Fatal(err) + } + if want := "googleapis.com"; got != want { + t.Fatalf("got %q, want %q", got, want) } tok, err := creds.Token(context.Background()) if err != nil { @@ -192,6 +205,7 @@ func TestDefaultCredentials_ImpersonatedServiceAccountKey(t *testing.T) { } func TestDefaultCredentials_UserCredentialsKey(t *testing.T) { + ctx := context.Background() ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") resp := &tokResp{ @@ -204,7 +218,7 @@ func TestDefaultCredentials_UserCredentialsKey(t *testing.T) { } })) - creds, err := DefaultCredentials(&Options{ + creds, err := DetectDefault(&DetectOptions{ CredentialsFile: "../internal/testdata/user.json", Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, TokenURL: ts.URL, @@ -212,11 +226,19 @@ func TestDefaultCredentials_UserCredentialsKey(t *testing.T) { if err != nil { t.Fatal(err) } - if want := "fake_project2"; creds.QuotaProjectID() != want { - t.Fatalf("got %q, want %q", creds.ProjectID(), want) + got, err := creds.QuotaProjectID(ctx) + if err != nil { + t.Fatal(err) + } + if want := "fake_project2"; got != want { + t.Fatalf("got %q, want %q", got, want) + } + got, err = creds.UniverseDomain(ctx) + if err != nil { + t.Fatal(err) } - if want := "googleapis.com"; creds.UniverseDomain() != want { - t.Fatalf("got %q, want %q", creds.UniverseDomain(), want) + if want := "googleapis.com"; got != want { + t.Fatalf("got %q, want %q", got, want) } tok, err := creds.Token(context.Background()) if err != nil { @@ -231,6 +253,7 @@ func TestDefaultCredentials_UserCredentialsKey(t *testing.T) { } func TestDefaultCredentials_UserCredentialsKey_UniverseDomain(t *testing.T) { + ctx := context.Background() ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") resp := &tokResp{ @@ -243,7 +266,7 @@ func TestDefaultCredentials_UserCredentialsKey_UniverseDomain(t *testing.T) { } })) - creds, err := DefaultCredentials(&Options{ + creds, err := DetectDefault(&DetectOptions{ CredentialsFile: "../internal/testdata/user_universe_domain.json", Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, TokenURL: ts.URL, @@ -251,11 +274,19 @@ func TestDefaultCredentials_UserCredentialsKey_UniverseDomain(t *testing.T) { if err != nil { t.Fatal(err) } - if want := "fake_project2"; creds.QuotaProjectID() != want { - t.Fatalf("got %q, want %q", creds.ProjectID(), want) + got, err := creds.QuotaProjectID(ctx) + if err != nil { + t.Fatal(err) + } + if want := "fake_project2"; got != want { + t.Fatalf("got %q, want %q", got, want) + } + got, err = creds.UniverseDomain(ctx) + if err != nil { + t.Fatal(err) } - if want := "googleapis.com"; creds.UniverseDomain() != want { - t.Fatalf("got %q, want %q", creds.UniverseDomain(), want) + if want := "googleapis.com"; got != want { + t.Fatalf("got %q, want %q", got, want) } tok, err := creds.Token(context.Background()) if err != nil { @@ -270,6 +301,7 @@ func TestDefaultCredentials_UserCredentialsKey_UniverseDomain(t *testing.T) { } func TestDefaultCredentials_ServiceAccountKey(t *testing.T) { + ctx := context.Background() b, err := os.ReadFile("../internal/testdata/sa.json") if err != nil { t.Fatal(err) @@ -294,18 +326,26 @@ func TestDefaultCredentials_ServiceAccountKey(t *testing.T) { t.Fatal(err) } - creds, err := DefaultCredentials(&Options{ + creds, err := DetectDefault(&DetectOptions{ CredentialsJSON: b, Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, }) if err != nil { t.Fatal(err) } - if want := "fake_project"; creds.ProjectID() != want { - t.Fatalf("got %q, want %q", creds.ProjectID(), want) + got, err := creds.ProjectID(ctx) + if err != nil { + t.Fatal(err) } - if want := "googleapis.com"; creds.UniverseDomain() != want { - t.Fatalf("got %q, want %q", creds.UniverseDomain(), want) + if want := "fake_project"; got != want { + t.Fatalf("got %q, want %q", got, want) + } + got, err = creds.UniverseDomain(ctx) + if err != nil { + t.Fatal(err) + } + if want := "googleapis.com"; got != want { + t.Fatalf("got %q, want %q", got, want) } tok, err := creds.Token(context.Background()) if err != nil { @@ -320,6 +360,7 @@ func TestDefaultCredentials_ServiceAccountKey(t *testing.T) { } func TestDefaultCredentials_ServiceAccountKeySelfSigned(t *testing.T) { + ctx := context.Background() b, err := os.ReadFile("../internal/testdata/sa.json") if err != nil { t.Fatal(err) @@ -329,7 +370,7 @@ func TestDefaultCredentials_ServiceAccountKeySelfSigned(t *testing.T) { defer func() { now = oldNow }() wantTok := "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImFiY2RlZjEyMzQ1Njc4OTAifQ.eyJpc3MiOiJnb3BoZXJAZmFrZV9wcm9qZWN0LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2NvcGUiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9hdXRoL2Nsb3VkLXBsYXRmb3JtIiwiZXhwIjo5NDk0MTE4MDAsImlhdCI6OTQ5NDA4MjAwLCJhdWQiOiIiLCJzdWIiOiJnb3BoZXJAZmFrZV9wcm9qZWN0LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0.n9Hggd-1Vw4WTQiWkh7q9r5eDsz-khU5vwkZl2VmgdUF3ZxDq1ARzchCNtTifeorzbp9C0i0vCr855G7FZkVCJXPVMcnxbwfMSafUYmVsmutbQiV9eTWfWM0_Ljiwa9GEbv1bN06Lz4LrelPKEaxsDbY6tU8LJUiome_gSMLfLk" - creds, err := DefaultCredentials(&Options{ + creds, err := DetectDefault(&DetectOptions{ CredentialsJSON: b, Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, UseSelfSignedJWT: true, @@ -337,11 +378,20 @@ func TestDefaultCredentials_ServiceAccountKeySelfSigned(t *testing.T) { if err != nil { t.Fatal(err) } - if want := "fake_project"; creds.ProjectID() != want { - t.Fatalf("got %q, want %q", creds.ProjectID(), want) + + got, err := creds.ProjectID(ctx) + if err != nil { + t.Fatal(err) + } + if want := "fake_project"; got != want { + t.Fatalf("got %q, want %q", got, want) + } + got, err = creds.UniverseDomain(ctx) + if err != nil { + t.Fatal(err) } - if want := "googleapis.com"; creds.UniverseDomain() != want { - t.Fatalf("got %q, want %q", creds.UniverseDomain(), want) + if want := "googleapis.com"; got != want { + t.Fatalf("got %q, want %q", got, want) } tok, err := creds.Token(context.Background()) if err != nil { @@ -356,6 +406,7 @@ func TestDefaultCredentials_ServiceAccountKeySelfSigned(t *testing.T) { } func TestDefaultCredentials_ServiceAccountKeySelfSigned_UniverseDomain(t *testing.T) { + ctx := context.Background() b, err := os.ReadFile("../internal/testdata/sa_universe_domain.json") if err != nil { t.Fatal(err) @@ -365,7 +416,7 @@ func TestDefaultCredentials_ServiceAccountKeySelfSigned_UniverseDomain(t *testin defer func() { now = oldNow }() wantTok := "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImFiY2RlZjEyMzQ1Njc4OTAifQ.eyJpc3MiOiJnb3BoZXJAZmFrZV9wcm9qZWN0LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2NvcGUiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9hdXRoL2Nsb3VkLXBsYXRmb3JtIiwiZXhwIjo5NDk0MTE4MDAsImlhdCI6OTQ5NDA4MjAwLCJhdWQiOiIiLCJzdWIiOiJnb3BoZXJAZmFrZV9wcm9qZWN0LmlhbS5nc2VydmljZWFjY291bnQuY29tIn0.n9Hggd-1Vw4WTQiWkh7q9r5eDsz-khU5vwkZl2VmgdUF3ZxDq1ARzchCNtTifeorzbp9C0i0vCr855G7FZkVCJXPVMcnxbwfMSafUYmVsmutbQiV9eTWfWM0_Ljiwa9GEbv1bN06Lz4LrelPKEaxsDbY6tU8LJUiome_gSMLfLk" - creds, err := DefaultCredentials(&Options{ + creds, err := DetectDefault(&DetectOptions{ CredentialsJSON: b, Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, UseSelfSignedJWT: true, @@ -373,11 +424,19 @@ func TestDefaultCredentials_ServiceAccountKeySelfSigned_UniverseDomain(t *testin if err != nil { t.Fatal(err) } - if want := "fake_project"; creds.ProjectID() != want { - t.Fatalf("got %q, want %q", creds.ProjectID(), want) + got, err := creds.ProjectID(ctx) + if err != nil { + t.Fatal(err) + } + if want := "fake_project"; got != want { + t.Fatalf("got %q, want %q", got, want) + } + got, err = creds.UniverseDomain(ctx) + if err != nil { + t.Fatal(err) } - if want := "example.com"; creds.UniverseDomain() != want { - t.Fatalf("got %q, want %q", creds.UniverseDomain(), want) + if want := "example.com"; got != want { + t.Fatalf("got %q, want %q", got, want) } tok, err := creds.Token(context.Background()) if err != nil { @@ -392,6 +451,7 @@ func TestDefaultCredentials_ServiceAccountKeySelfSigned_UniverseDomain(t *testin } func TestDefaultCredentials_ClientCredentials(t *testing.T) { + ctx := context.Background() b, err := os.ReadFile("../internal/testdata/clientcreds_installed.json") if err != nil { t.Fatal(err) @@ -418,7 +478,7 @@ func TestDefaultCredentials_ClientCredentials(t *testing.T) { t.Fatal(err) } - creds, err := DefaultCredentials(&Options{ + creds, err := DetectDefault(&DetectOptions{ CredentialsJSON: b, Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, TokenURL: ts.URL, @@ -437,8 +497,12 @@ func TestDefaultCredentials_ClientCredentials(t *testing.T) { if err != nil { t.Fatal(err) } - if want := "googleapis.com"; creds.UniverseDomain() != want { - t.Fatalf("got %q, want %q", creds.UniverseDomain(), want) + got, err := creds.UniverseDomain(ctx) + if err != nil { + t.Fatal(err) + } + if want := "googleapis.com"; got != want { + t.Fatalf("got %q, want %q", got, want) } tok, err := creds.Token(context.Background()) if err != nil { @@ -454,6 +518,7 @@ func TestDefaultCredentials_ClientCredentials(t *testing.T) { // Better coverage of all external account features tested in the sub-package. func TestDefaultCredentials_ExternalAccountKey(t *testing.T) { + ctx := context.Background() b, err := os.ReadFile("../internal/testdata/exaccount_url.json") if err != nil { t.Fatal(err) @@ -516,7 +581,7 @@ func TestDefaultCredentials_ExternalAccountKey(t *testing.T) { t.Fatal(err) } - creds, err := DefaultCredentials(&Options{ + creds, err := DetectDefault(&DetectOptions{ CredentialsJSON: b, Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, UseSelfSignedJWT: true, @@ -524,8 +589,12 @@ func TestDefaultCredentials_ExternalAccountKey(t *testing.T) { if err != nil { t.Fatal(err) } - if want := "googleapis.com"; creds.UniverseDomain() != want { - t.Fatalf("got %q, want %q", creds.UniverseDomain(), want) + got, err := creds.UniverseDomain(ctx) + if err != nil { + t.Fatal(err) + } + if want := "googleapis.com"; got != want { + t.Fatalf("got %q, want %q", got, want) } tok, err := creds.Token(context.Background()) if err != nil { @@ -577,7 +646,7 @@ func TestDefaultCredentials_ExternalAccountAuthorizedUserKey(t *testing.T) { t.Fatal(err) } - creds, err := DefaultCredentials(&Options{ + creds, err := DetectDefault(&DetectOptions{ CredentialsJSON: b, Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, UseSelfSignedJWT: true, @@ -603,7 +672,7 @@ func TestDefaultCredentials_Fails(t *testing.T) { t.Setenv("APPDATA", "nothingToSeeHere") allowOnGCECheck = false defer func() { allowOnGCECheck = true }() - if _, err := DefaultCredentials(&Options{ + if _, err := DetectDefault(&DetectOptions{ Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, }); !strings.Contains(err.Error(), adcSetupURL) { t.Fatalf("got %v, wanted to contain %v", err, adcSetupURL) @@ -611,7 +680,7 @@ func TestDefaultCredentials_Fails(t *testing.T) { } func TestDefaultCredentials_BadFiletype(t *testing.T) { - if _, err := DefaultCredentials(&Options{ + if _, err := DetectDefault(&DetectOptions{ CredentialsJSON: []byte(`{"type":"42"}`), Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, }); err == nil { @@ -622,21 +691,21 @@ func TestDefaultCredentials_BadFiletype(t *testing.T) { func TestDefaultCredentials_Validate(t *testing.T) { tests := []struct { name string - opts *Options + opts *DetectOptions }{ { name: "missing options", }, { name: "scope and audience provided", - opts: &Options{ + opts: &DetectOptions{ Scopes: []string{"scope"}, Audience: "aud", }, }, { name: "file and json provided", - opts: &Options{ + opts: &DetectOptions{ Scopes: []string{"scope"}, CredentialsFile: "path", CredentialsJSON: []byte(`{"some":"json"}`), @@ -645,7 +714,7 @@ func TestDefaultCredentials_Validate(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if _, err := DefaultCredentials(tt.opts); err == nil { + if _, err := DetectDefault(tt.opts); err == nil { t.Error("got nil, want an error") } }) diff --git a/auth/detect/doc.go b/auth/credentials/doc.go similarity index 96% rename from auth/detect/doc.go rename to auth/credentials/doc.go index 027a59fb6aa..4dcc74f4848 100644 --- a/auth/detect/doc.go +++ b/auth/credentials/doc.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package detect provides support for making OAuth2 authorized and +// Package credentials provides support for making OAuth2 authorized and // authenticated HTTP requests to Google APIs. It supports the Web server flow, // client-side credentials, service accounts, Google Compute Engine service // accounts, Google App Engine service accounts and workload identity federation @@ -77,7 +77,7 @@ // The [Credentials] type represents Google credentials, including Application // Default Credentials. // -// Use [DefaultCredentials] to obtain Application Default Credentials. +// Use [DetectDefault] to obtain Application Default Credentials. // // Application Default Credentials support workload identity federation to // access Google Cloud resources from non-Google Cloud platforms including Amazon @@ -85,4 +85,4 @@ // OpenID Connect (OIDC). Workload identity federation is recommended for // non-Google Cloud environments as it avoids the need to download, manage, and // store service account private keys locally. -package detect +package credentials diff --git a/auth/detect/example_test.go b/auth/credentials/example_test.go similarity index 84% rename from auth/detect/example_test.go rename to auth/credentials/example_test.go index 1bcf64909cd..35564c723fb 100644 --- a/auth/detect/example_test.go +++ b/auth/credentials/example_test.go @@ -12,18 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -package detect_test +package credentials_test import ( "log" "os" - "cloud.google.com/go/auth/detect" + "cloud.google.com/go/auth/credentials" "cloud.google.com/go/auth/httptransport" ) -func ExampleDefaultCredentials() { - creds, err := detect.DefaultCredentials(&detect.Options{ +func ExampleDetectDefault() { + creds, err := credentials.DetectDefault(&credentials.DetectOptions{ Scopes: []string{"https://www.googleapis.com/auth/devstorage.full_control"}, }) if err != nil { @@ -38,7 +38,7 @@ func ExampleDefaultCredentials() { client.Get("...") } -func ExampleDefaultCredentials_withFilepath() { +func ExampleDetectDefault_withFilepath() { // Your credentials should be obtained from the Google // Developer Console (https://console.developers.google.com). // Navigate to your project, then see the "Credentials" page @@ -47,7 +47,7 @@ func ExampleDefaultCredentials_withFilepath() { // select "Service Account", and click "Create Client ID". A JSON // key file will then be downloaded to your computer. filepath := "/path/to/your-project-key.json" - creds, err := detect.DefaultCredentials(&detect.Options{ + creds, err := credentials.DetectDefault(&credentials.DetectOptions{ Scopes: []string{"https://www.googleapis.com/auth/bigquery"}, CredentialsFile: filepath, }) @@ -63,12 +63,12 @@ func ExampleDefaultCredentials_withFilepath() { client.Get("...") } -func ExampleDefaultCredentials_withJSON() { +func ExampleDetectDefault_withJSON() { data, err := os.ReadFile("/path/to/key-file.json") if err != nil { log.Fatal(err) } - creds, err := detect.DefaultCredentials(&detect.Options{ + creds, err := credentials.DetectDefault(&credentials.DetectOptions{ Scopes: []string{"https://www.googleapis.com/auth/bigquery"}, CredentialsJSON: data, }) diff --git a/auth/detect/filetypes.go b/auth/credentials/filetypes.go similarity index 81% rename from auth/detect/filetypes.go rename to auth/credentials/filetypes.go index 3d822d740a4..9bef2afe848 100644 --- a/auth/detect/filetypes.go +++ b/auth/credentials/filetypes.go @@ -12,21 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -package detect +package credentials import ( "errors" "fmt" "cloud.google.com/go/auth" - "cloud.google.com/go/auth/detect/internal/externalaccount" - "cloud.google.com/go/auth/detect/internal/externalaccountuser" - "cloud.google.com/go/auth/detect/internal/gdch" - "cloud.google.com/go/auth/detect/internal/impersonate" + "cloud.google.com/go/auth/credentials/internal/externalaccount" + "cloud.google.com/go/auth/credentials/internal/externalaccountuser" + "cloud.google.com/go/auth/credentials/internal/gdch" + "cloud.google.com/go/auth/credentials/internal/impersonate" + internalauth "cloud.google.com/go/auth/internal" "cloud.google.com/go/auth/internal/internaldetect" ) -func fileCredentials(b []byte, opts *Options) (*Credentials, error) { +func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) { fileType, err := internaldetect.ParseFileType(b) if err != nil { return nil, err @@ -100,12 +101,18 @@ func fileCredentials(b []byte, opts *Options) (*Credentials, error) { default: return nil, fmt.Errorf("detect: unsupported filetype %q", fileType) } - return newCredentials(auth.NewCachedTokenProvider(tp, &auth.CachedTokenProviderOptions{ - ExpireEarly: opts.EarlyTokenRefresh, - }), b, projectID, quotaProjectID, universeDomain), nil + return auth.NewCredentials(&auth.CredentialsOptions{ + TokenProvider: auth.NewCachedTokenProvider(tp, &auth.CachedTokenProviderOptions{ + ExpireEarly: opts.EarlyTokenRefresh, + }), + JSON: b, + ProjectIDProvider: internalauth.StaticCredentialsProperty(projectID), + QuotaProjectIDProvider: internalauth.StaticCredentialsProperty(quotaProjectID), + UniverseDomainProvider: internalauth.StaticCredentialsProperty(universeDomain), + }), nil } -func handleServiceAccount(f *internaldetect.ServiceAccountFile, opts *Options) (auth.TokenProvider, error) { +func handleServiceAccount(f *internaldetect.ServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { if opts.UseSelfSignedJWT { return configureSelfSignedJWT(f, opts) } @@ -123,7 +130,7 @@ func handleServiceAccount(f *internaldetect.ServiceAccountFile, opts *Options) ( return auth.New2LOTokenProvider(opts2LO) } -func handleUserCredential(f *internaldetect.UserCredentialsFile, opts *Options) (auth.TokenProvider, error) { +func handleUserCredential(f *internaldetect.UserCredentialsFile, opts *DetectOptions) (auth.TokenProvider, error) { opts3LO := &auth.Options3LO{ ClientID: f.ClientID, ClientSecret: f.ClientSecret, @@ -137,7 +144,7 @@ func handleUserCredential(f *internaldetect.UserCredentialsFile, opts *Options) return auth.New3LOTokenProvider(opts3LO) } -func handleExternalAccount(f *internaldetect.ExternalAccountFile, opts *Options) (auth.TokenProvider, error) { +func handleExternalAccount(f *internaldetect.ExternalAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { externalOpts := &externalaccount.Options{ Audience: f.Audience, SubjectTokenType: f.SubjectTokenType, @@ -156,7 +163,7 @@ func handleExternalAccount(f *internaldetect.ExternalAccountFile, opts *Options) return externalaccount.NewTokenProvider(externalOpts) } -func handleExternalAccountAuthorizedUser(f *internaldetect.ExternalAccountAuthorizedUserFile, opts *Options) (auth.TokenProvider, error) { +func handleExternalAccountAuthorizedUser(f *internaldetect.ExternalAccountAuthorizedUserFile, opts *DetectOptions) (auth.TokenProvider, error) { externalOpts := &externalaccountuser.Options{ Audience: f.Audience, RefreshToken: f.RefreshToken, @@ -170,7 +177,7 @@ func handleExternalAccountAuthorizedUser(f *internaldetect.ExternalAccountAuthor return externalaccountuser.NewTokenProvider(externalOpts) } -func handleImpersonatedServiceAccount(f *internaldetect.ImpersonatedServiceAccountFile, opts *Options) (auth.TokenProvider, error) { +func handleImpersonatedServiceAccount(f *internaldetect.ImpersonatedServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { if f.ServiceAccountImpersonationURL == "" || f.CredSource == nil { return nil, errors.New("missing 'source_credentials' field or 'service_account_impersonation_url' in credentials") } @@ -188,7 +195,7 @@ func handleImpersonatedServiceAccount(f *internaldetect.ImpersonatedServiceAccou }) } -func handleGDCHServiceAccount(f *internaldetect.GDCHServiceAccountFile, opts *Options) (auth.TokenProvider, error) { +func handleGDCHServiceAccount(f *internaldetect.GDCHServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { return gdch.NewTokenProvider(f, &gdch.Options{ STSAudience: opts.STSAudience, Client: opts.client(), diff --git a/auth/detect/internal/externalaccount/aws_provider.go b/auth/credentials/internal/externalaccount/aws_provider.go similarity index 100% rename from auth/detect/internal/externalaccount/aws_provider.go rename to auth/credentials/internal/externalaccount/aws_provider.go diff --git a/auth/detect/internal/externalaccount/aws_provider_test.go b/auth/credentials/internal/externalaccount/aws_provider_test.go similarity index 100% rename from auth/detect/internal/externalaccount/aws_provider_test.go rename to auth/credentials/internal/externalaccount/aws_provider_test.go diff --git a/auth/detect/internal/externalaccount/executable_provider.go b/auth/credentials/internal/externalaccount/executable_provider.go similarity index 100% rename from auth/detect/internal/externalaccount/executable_provider.go rename to auth/credentials/internal/externalaccount/executable_provider.go diff --git a/auth/detect/internal/externalaccount/executable_provider_test.go b/auth/credentials/internal/externalaccount/executable_provider_test.go similarity index 100% rename from auth/detect/internal/externalaccount/executable_provider_test.go rename to auth/credentials/internal/externalaccount/executable_provider_test.go diff --git a/auth/detect/internal/externalaccount/externalaccount.go b/auth/credentials/internal/externalaccount/externalaccount.go similarity index 98% rename from auth/detect/internal/externalaccount/externalaccount.go rename to auth/credentials/internal/externalaccount/externalaccount.go index 9e97f05e63f..e346e037d5f 100644 --- a/auth/detect/internal/externalaccount/externalaccount.go +++ b/auth/credentials/internal/externalaccount/externalaccount.go @@ -24,8 +24,8 @@ import ( "time" "cloud.google.com/go/auth" - "cloud.google.com/go/auth/detect/internal/impersonate" - "cloud.google.com/go/auth/detect/internal/stsexchange" + "cloud.google.com/go/auth/credentials/internal/impersonate" + "cloud.google.com/go/auth/credentials/internal/stsexchange" "cloud.google.com/go/auth/internal/internaldetect" ) diff --git a/auth/detect/internal/externalaccount/externalaccount_test.go b/auth/credentials/internal/externalaccount/externalaccount_test.go similarity index 100% rename from auth/detect/internal/externalaccount/externalaccount_test.go rename to auth/credentials/internal/externalaccount/externalaccount_test.go diff --git a/auth/detect/internal/externalaccount/file_provider.go b/auth/credentials/internal/externalaccount/file_provider.go similarity index 100% rename from auth/detect/internal/externalaccount/file_provider.go rename to auth/credentials/internal/externalaccount/file_provider.go diff --git a/auth/detect/internal/externalaccount/file_provider_test.go b/auth/credentials/internal/externalaccount/file_provider_test.go similarity index 100% rename from auth/detect/internal/externalaccount/file_provider_test.go rename to auth/credentials/internal/externalaccount/file_provider_test.go diff --git a/auth/detect/internal/externalaccount/impersonate_test.go b/auth/credentials/internal/externalaccount/impersonate_test.go similarity index 100% rename from auth/detect/internal/externalaccount/impersonate_test.go rename to auth/credentials/internal/externalaccount/impersonate_test.go diff --git a/auth/detect/internal/externalaccount/info.go b/auth/credentials/internal/externalaccount/info.go similarity index 100% rename from auth/detect/internal/externalaccount/info.go rename to auth/credentials/internal/externalaccount/info.go diff --git a/auth/detect/internal/externalaccount/info_test.go b/auth/credentials/internal/externalaccount/info_test.go similarity index 100% rename from auth/detect/internal/externalaccount/info_test.go rename to auth/credentials/internal/externalaccount/info_test.go diff --git a/auth/detect/internal/externalaccount/testdata/3pi_cred.json b/auth/credentials/internal/externalaccount/testdata/3pi_cred.json similarity index 100% rename from auth/detect/internal/externalaccount/testdata/3pi_cred.json rename to auth/credentials/internal/externalaccount/testdata/3pi_cred.json diff --git a/auth/detect/internal/externalaccount/testdata/3pi_cred.txt b/auth/credentials/internal/externalaccount/testdata/3pi_cred.txt similarity index 100% rename from auth/detect/internal/externalaccount/testdata/3pi_cred.txt rename to auth/credentials/internal/externalaccount/testdata/3pi_cred.txt diff --git a/auth/detect/internal/externalaccount/url_provider.go b/auth/credentials/internal/externalaccount/url_provider.go similarity index 100% rename from auth/detect/internal/externalaccount/url_provider.go rename to auth/credentials/internal/externalaccount/url_provider.go diff --git a/auth/detect/internal/externalaccount/url_provider_test.go b/auth/credentials/internal/externalaccount/url_provider_test.go similarity index 100% rename from auth/detect/internal/externalaccount/url_provider_test.go rename to auth/credentials/internal/externalaccount/url_provider_test.go diff --git a/auth/detect/internal/externalaccountuser/externalaccountuser.go b/auth/credentials/internal/externalaccountuser/externalaccountuser.go similarity index 98% rename from auth/detect/internal/externalaccountuser/externalaccountuser.go rename to auth/credentials/internal/externalaccountuser/externalaccountuser.go index 6a94708c2e8..3d4276f8b34 100644 --- a/auth/detect/internal/externalaccountuser/externalaccountuser.go +++ b/auth/credentials/internal/externalaccountuser/externalaccountuser.go @@ -21,7 +21,7 @@ import ( "time" "cloud.google.com/go/auth" - "cloud.google.com/go/auth/detect/internal/stsexchange" + "cloud.google.com/go/auth/credentials/internal/stsexchange" "cloud.google.com/go/auth/internal" ) diff --git a/auth/detect/internal/externalaccountuser/externalaccountuser_test.go b/auth/credentials/internal/externalaccountuser/externalaccountuser_test.go similarity index 98% rename from auth/detect/internal/externalaccountuser/externalaccountuser_test.go rename to auth/credentials/internal/externalaccountuser/externalaccountuser_test.go index 279e771b0b8..a54d0de87b2 100644 --- a/auth/detect/internal/externalaccountuser/externalaccountuser_test.go +++ b/auth/credentials/internal/externalaccountuser/externalaccountuser_test.go @@ -22,7 +22,7 @@ import ( "net/http/httptest" "testing" - "cloud.google.com/go/auth/detect/internal/stsexchange" + "cloud.google.com/go/auth/credentials/internal/stsexchange" "cloud.google.com/go/auth/internal" ) diff --git a/auth/detect/internal/gdch/gdch.go b/auth/credentials/internal/gdch/gdch.go similarity index 100% rename from auth/detect/internal/gdch/gdch.go rename to auth/credentials/internal/gdch/gdch.go diff --git a/auth/detect/internal/gdch/gdch_test.go b/auth/credentials/internal/gdch/gdch_test.go similarity index 100% rename from auth/detect/internal/gdch/gdch_test.go rename to auth/credentials/internal/gdch/gdch_test.go diff --git a/auth/detect/internal/impersonate/impersonate.go b/auth/credentials/internal/impersonate/impersonate.go similarity index 100% rename from auth/detect/internal/impersonate/impersonate.go rename to auth/credentials/internal/impersonate/impersonate.go diff --git a/auth/detect/internal/impersonate/impersonate_test.go b/auth/credentials/internal/impersonate/impersonate_test.go similarity index 100% rename from auth/detect/internal/impersonate/impersonate_test.go rename to auth/credentials/internal/impersonate/impersonate_test.go diff --git a/auth/detect/internal/stsexchange/sts_exchange.go b/auth/credentials/internal/stsexchange/sts_exchange.go similarity index 100% rename from auth/detect/internal/stsexchange/sts_exchange.go rename to auth/credentials/internal/stsexchange/sts_exchange.go diff --git a/auth/detect/internal/stsexchange/sts_exchange_test.go b/auth/credentials/internal/stsexchange/sts_exchange_test.go similarity index 100% rename from auth/detect/internal/stsexchange/sts_exchange_test.go rename to auth/credentials/internal/stsexchange/sts_exchange_test.go diff --git a/auth/detect/selfsignedjwt.go b/auth/credentials/selfsignedjwt.go similarity index 96% rename from auth/detect/selfsignedjwt.go rename to auth/credentials/selfsignedjwt.go index b670fd94ce1..c3ea76c1bff 100644 --- a/auth/detect/selfsignedjwt.go +++ b/auth/credentials/selfsignedjwt.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package detect +package credentials import ( "context" @@ -34,7 +34,7 @@ var ( // configureSelfSignedJWT uses the private key in the service account to create // a JWT without making a network call. -func configureSelfSignedJWT(f *internaldetect.ServiceAccountFile, opts *Options) (auth.TokenProvider, error) { +func configureSelfSignedJWT(f *internaldetect.ServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { pk, err := internal.ParseKey([]byte(f.PrivateKey)) if err != nil { return nil, fmt.Errorf("detect: could not parse key: %w", err) diff --git a/auth/detect/selfsignedjwt_test.go b/auth/credentials/selfsignedjwt_test.go similarity index 98% rename from auth/detect/selfsignedjwt_test.go rename to auth/credentials/selfsignedjwt_test.go index 31ef58ec26c..daa6b90c662 100644 --- a/auth/detect/selfsignedjwt_test.go +++ b/auth/credentials/selfsignedjwt_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package detect +package credentials import ( "bytes" @@ -45,7 +45,7 @@ func TestDefaultCredentials_SelfSignedJSON(t *testing.T) { if err != nil { t.Fatal(err) } - tp, err := DefaultCredentials(&Options{ + tp, err := DetectDefault(&DetectOptions{ CredentialsJSON: jsonKey, Audience: "audience", UseSelfSignedJWT: true, @@ -107,7 +107,7 @@ func TestDefaultCredentials_SelfSignedWithScope(t *testing.T) { if err != nil { t.Fatal(err) } - tp, err := DefaultCredentials(&Options{ + tp, err := DetectDefault(&DetectOptions{ CredentialsJSON: jsonKey, Scopes: []string{"scope1", "scope2"}, UseSelfSignedJWT: true, diff --git a/auth/downscope/example_test.go b/auth/downscope/example_test.go index bc12b7e9650..8a1567f96e4 100644 --- a/auth/downscope/example_test.go +++ b/auth/downscope/example_test.go @@ -18,7 +18,7 @@ import ( "context" "fmt" - "cloud.google.com/go/auth/detect" + "cloud.google.com/go/auth/credentials" "cloud.google.com/go/auth/downscope" ) @@ -40,7 +40,7 @@ func ExampleNewTokenProvider() { // This Source can be initialized in multiple ways; the following example uses // Application Default Credentials. - baseProvider, err := detect.DefaultCredentials(&detect.Options{ + baseProvider, err := credentials.DetectDefault(&credentials.DetectOptions{ Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, }) tp, err := downscope.NewTokenProvider(&downscope.Options{BaseProvider: baseProvider, Rules: accessBoundary}) diff --git a/auth/downscope/integration_test.go b/auth/downscope/integration_test.go index 0535a70e004..e173282d17d 100644 --- a/auth/downscope/integration_test.go +++ b/auth/downscope/integration_test.go @@ -23,7 +23,7 @@ import ( "time" "cloud.google.com/go/auth" - "cloud.google.com/go/auth/detect" + "cloud.google.com/go/auth/credentials" "cloud.google.com/go/auth/downscope" "cloud.google.com/go/auth/internal/testutil" "cloud.google.com/go/auth/internal/testutil/testgcs" @@ -39,7 +39,7 @@ const ( func TestDownscopedToken(t *testing.T) { testutil.IntegrationTestCheck(t) - creds, err := detect.DefaultCredentials(&detect.Options{ + creds, err := credentials.DetectDefault(&credentials.DetectOptions{ CredentialsFile: os.Getenv(envServiceAccountFile), Scopes: []string{rootTokenScope}, }) diff --git a/auth/grpctransport/directpath.go b/auth/grpctransport/directpath.go index 652d8feeeb1..b4bbdfc3f69 100644 --- a/auth/grpctransport/directpath.go +++ b/auth/grpctransport/directpath.go @@ -55,7 +55,7 @@ func checkDirectPathEndPoint(endpoint string) bool { return true } -func isTokenProviderDirectPathCompatible(tp auth.TokenProvider, opts *Options) bool { +func isTokenProviderDirectPathCompatible(tp auth.TokenProvider, _ *Options) bool { if tp == nil { return false } diff --git a/auth/grpctransport/grpctransport.go b/auth/grpctransport/grpctransport.go index 59480480ae3..a8bc1ff5cbd 100644 --- a/auth/grpctransport/grpctransport.go +++ b/auth/grpctransport/grpctransport.go @@ -21,11 +21,11 @@ import ( "net/http" "cloud.google.com/go/auth" - "cloud.google.com/go/auth/detect" + "cloud.google.com/go/auth/credentials" "cloud.google.com/go/auth/internal/transport" "go.opencensus.io/plugin/ocgrpc" "google.golang.org/grpc" - "google.golang.org/grpc/credentials" + grpccreds "google.golang.org/grpc/credentials" grpcinsecure "google.golang.org/grpc/credentials/insecure" ) @@ -70,7 +70,7 @@ type Options struct { TokenProvider auth.TokenProvider // DetectOpts configures settings for detect Application Default // Credentials. - DetectOpts *detect.Options + DetectOpts *credentials.DetectOptions // InternalOptions are NOT meant to be set directly by consumers of this // package, they should only be set by generated client code. @@ -99,7 +99,7 @@ func (o *Options) validate() error { return nil } -func (o *Options) resolveDetectOptions() *detect.Options { +func (o *Options) resolveDetectOptions() *credentials.DetectOptions { io := o.InternalOptions // soft-clone these so we are not updating a ref the user holds and may reuse do := transport.CloneDetectOptions(o.DetectOpts) @@ -200,7 +200,7 @@ func dial(ctx context.Context, secure bool, opts *Options) (*grpc.ClientConn, er // Authentication can only be sent when communicating over a secure connection. if !opts.DisableAuthentication { metadata := opts.Metadata - creds, err := detect.DefaultCredentials(opts.resolveDetectOptions()) + creds, err := credentials.DetectDefault(opts.resolveDetectOptions()) if err != nil { return nil, err } @@ -209,7 +209,10 @@ func dial(ctx context.Context, secure bool, opts *Options) (*grpc.ClientConn, er tp = opts.TokenProvider } - qp := creds.QuotaProjectID() + qp, err := creds.QuotaProjectID(ctx) + if err != nil { + return nil, err + } if qp != "" { if metadata == nil { metadata = make(map[string]string, 1) @@ -253,8 +256,8 @@ func (tp *grpcTokenProvider) GetRequestMetadata(ctx context.Context, uri ...stri return nil, err } if tp.secure { - ri, _ := credentials.RequestInfoFromContext(ctx) - if err = credentials.CheckSecurityLevel(ri.AuthInfo, credentials.PrivacyAndIntegrity); err != nil { + ri, _ := grpccreds.RequestInfoFromContext(ctx) + if err = grpccreds.CheckSecurityLevel(ri.AuthInfo, grpccreds.PrivacyAndIntegrity); err != nil { return nil, fmt.Errorf("unable to transfer TokenProvider PerRPCCredentials: %v", err) } } diff --git a/auth/grpctransport/grpctransport_test.go b/auth/grpctransport/grpctransport_test.go index 15f0b1387a0..bcfa85d081d 100644 --- a/auth/grpctransport/grpctransport_test.go +++ b/auth/grpctransport/grpctransport_test.go @@ -21,7 +21,7 @@ import ( "testing" "cloud.google.com/go/auth" - "cloud.google.com/go/auth/detect" + "cloud.google.com/go/auth/credentials" echo "cloud.google.com/go/auth/grpctransport/testdata" "github.com/google/go-cmp/cmp" "google.golang.org/grpc" @@ -88,7 +88,7 @@ func TestDial_FailsValidation(t *testing.T) { name: "has creds with disable options, cred file", opts: &Options{ DisableAuthentication: true, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ CredentialsFile: "abc.123", }, }, @@ -97,7 +97,7 @@ func TestDial_FailsValidation(t *testing.T) { name: "has creds with disable options, cred json", opts: &Options{ DisableAuthentication: true, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ CredentialsJSON: []byte(`{"foo":"bar"}`), }, }, @@ -117,17 +117,17 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { tests := []struct { name string in *Options - want *detect.Options + want *credentials.DetectOptions }{ { name: "base", in: &Options{ - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ Scopes: []string{"scope"}, CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Scopes: []string{"scope"}, CredentialsFile: "/path/to/a/file", }, @@ -138,12 +138,12 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { InternalOptions: &InternalOptions{ EnableJWTWithScope: true, }, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ Scopes: []string{"scope"}, CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Scopes: []string{"scope"}, CredentialsFile: "/path/to/a/file", UseSelfSignedJWT: true, @@ -152,12 +152,12 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { { name: "self-signed, with aud", in: &Options{ - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ Audience: "aud", CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Audience: "aud", CredentialsFile: "/path/to/a/file", UseSelfSignedJWT: true, @@ -170,11 +170,11 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { DefaultScopes: []string{"default"}, DefaultAudience: "default", }, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Scopes: []string{"default"}, CredentialsFile: "/path/to/a/file", }, @@ -186,12 +186,12 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { DefaultScopes: []string{"default"}, DefaultAudience: "default", }, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ Scopes: []string{"non-default"}, CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Scopes: []string{"non-default"}, CredentialsFile: "/path/to/a/file", }, @@ -203,12 +203,12 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { DefaultScopes: []string{"default"}, DefaultAudience: "default", }, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ Audience: "non-default", CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Audience: "non-default", CredentialsFile: "/path/to/a/file", UseSelfSignedJWT: true, @@ -220,11 +220,11 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { InternalOptions: &InternalOptions{ DefaultAudience: "default", }, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Audience: "default", CredentialsFile: "/path/to/a/file", }, @@ -280,7 +280,7 @@ func TestNewClient_DetectedServiceAccount(t *testing.T) { InternalOptions: &InternalOptions{ DefaultEndpoint: l.Addr().String(), }, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ Audience: l.Addr().String(), CredentialsFile: "../internal/testdata/sa.json", UseSelfSignedJWT: true, diff --git a/auth/httptransport/httptransport.go b/auth/httptransport/httptransport.go index 016eb8f920a..f932b3152ff 100644 --- a/auth/httptransport/httptransport.go +++ b/auth/httptransport/httptransport.go @@ -21,7 +21,7 @@ import ( "net/http" "cloud.google.com/go/auth" - "cloud.google.com/go/auth/detect" + detect "cloud.google.com/go/auth/credentials" "cloud.google.com/go/auth/internal" "cloud.google.com/go/auth/internal/transport" ) @@ -58,7 +58,7 @@ type Options struct { ClientCertProvider ClientCertProvider // DetectOpts configures settings for detect Application Default // Credentials. - DetectOpts *detect.Options + DetectOpts *detect.DetectOptions // InternalOptions are NOT meant to be set directly by consumers of this // package, they should only be set by generated client code. @@ -88,7 +88,7 @@ func (o *Options) client() *http.Client { return nil } -func (o *Options) resolveDetectOptions() *detect.Options { +func (o *Options) resolveDetectOptions() *detect.DetectOptions { io := o.InternalOptions // soft-clone these so we are not updating a ref the user holds and may reuse do := transport.CloneDetectOptions(o.DetectOpts) diff --git a/auth/httptransport/httptransport_test.go b/auth/httptransport/httptransport_test.go index deadf0587f7..614b81f00db 100644 --- a/auth/httptransport/httptransport_test.go +++ b/auth/httptransport/httptransport_test.go @@ -22,7 +22,7 @@ import ( "testing" "cloud.google.com/go/auth" - "cloud.google.com/go/auth/detect" + "cloud.google.com/go/auth/credentials" "cloud.google.com/go/auth/internal" "github.com/google/go-cmp/cmp" ) @@ -104,7 +104,7 @@ func TestNewClient_FailsValidation(t *testing.T) { name: "has creds with disable options, cred file", opts: &Options{ DisableAuthentication: true, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ CredentialsFile: "abc.123", }, }, @@ -113,7 +113,7 @@ func TestNewClient_FailsValidation(t *testing.T) { name: "has creds with disable options, cred json", opts: &Options{ DisableAuthentication: true, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ CredentialsJSON: []byte(`{"foo":"bar"}`), }, }, @@ -133,17 +133,17 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { tests := []struct { name string in *Options - want *detect.Options + want *credentials.DetectOptions }{ { name: "base", in: &Options{ - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ Scopes: []string{"scope"}, CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Scopes: []string{"scope"}, CredentialsFile: "/path/to/a/file", }, @@ -154,12 +154,12 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { InternalOptions: &InternalOptions{ EnableJWTWithScope: true, }, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ Scopes: []string{"scope"}, CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Scopes: []string{"scope"}, CredentialsFile: "/path/to/a/file", UseSelfSignedJWT: true, @@ -168,12 +168,12 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { { name: "self-signed, with aud", in: &Options{ - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ Audience: "aud", CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Audience: "aud", CredentialsFile: "/path/to/a/file", UseSelfSignedJWT: true, @@ -186,11 +186,11 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { DefaultScopes: []string{"default"}, DefaultAudience: "default", }, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Scopes: []string{"default"}, CredentialsFile: "/path/to/a/file", }, @@ -202,12 +202,12 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { DefaultScopes: []string{"default"}, DefaultAudience: "default", }, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ Scopes: []string{"non-default"}, CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Scopes: []string{"non-default"}, CredentialsFile: "/path/to/a/file", }, @@ -219,12 +219,12 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { DefaultScopes: []string{"default"}, DefaultAudience: "default", }, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ Audience: "non-default", CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Audience: "non-default", CredentialsFile: "/path/to/a/file", UseSelfSignedJWT: true, @@ -236,11 +236,11 @@ func TestOptions_ResolveDetectOptions(t *testing.T) { InternalOptions: &InternalOptions{ DefaultAudience: "default", }, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ CredentialsFile: "/path/to/a/file", }, }, - want: &detect.Options{ + want: &credentials.DetectOptions{ Audience: "default", CredentialsFile: "/path/to/a/file", }, @@ -277,7 +277,7 @@ func TestNewClient_DetectedServiceAccount(t *testing.T) { InternalOptions: &InternalOptions{ DefaultEndpoint: ts.URL, }, - DetectOpts: &detect.Options{ + DetectOpts: &credentials.DetectOptions{ Audience: ts.URL, CredentialsFile: "../internal/testdata/sa.json", UseSelfSignedJWT: true, diff --git a/auth/httptransport/transport.go b/auth/httptransport/transport.go index 13f076258ac..ad4019153b2 100644 --- a/auth/httptransport/transport.go +++ b/auth/httptransport/transport.go @@ -22,7 +22,7 @@ import ( "time" "cloud.google.com/go/auth" - "cloud.google.com/go/auth/detect" + "cloud.google.com/go/auth/credentials" "cloud.google.com/go/auth/internal" "cloud.google.com/go/auth/internal/transport/cert" "go.opencensus.io/plugin/ochttp" @@ -57,11 +57,14 @@ func newTransport(base http.RoundTripper, opts *Options) (http.RoundTripper, err Key: opts.APIKey, } default: - creds, err := detect.DefaultCredentials(opts.resolveDetectOptions()) + creds, err := credentials.DetectDefault(opts.resolveDetectOptions()) + if err != nil { + return nil, err + } + qp, err := creds.QuotaProjectID(context.Background()) if err != nil { return nil, err } - qp := creds.QuotaProjectID() if qp != "" { if headers == nil { headers = make(map[string][]string, 1) diff --git a/auth/idtoken/file.go b/auth/idtoken/file.go index c904ba1094f..acc563f75d1 100644 --- a/auth/idtoken/file.go +++ b/auth/idtoken/file.go @@ -21,7 +21,7 @@ import ( "strings" "cloud.google.com/go/auth" - "cloud.google.com/go/auth/detect" + "cloud.google.com/go/auth/credentials" "cloud.google.com/go/auth/impersonate" "cloud.google.com/go/auth/internal/internaldetect" ) @@ -86,7 +86,7 @@ func tokenProviderFromBytes(b []byte, opts *Options) (auth.TokenProvider, error) account := filepath.Base(accountURL.ServiceAccountImpersonationURL) account = strings.Split(account, ":")[0] - creds, err := detect.DefaultCredentials(&detect.Options{ + creds, err := credentials.DetectDefault(&credentials.DetectOptions{ Scopes: defaultScopes, CredentialsJSON: b, Client: opts.client(), diff --git a/auth/impersonate/integration_test.go b/auth/impersonate/integration_test.go index be4d240508f..dd4fc4967a4 100644 --- a/auth/impersonate/integration_test.go +++ b/auth/impersonate/integration_test.go @@ -24,7 +24,8 @@ import ( "testing" "time" - "cloud.google.com/go/auth/detect" + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/credentials" "cloud.google.com/go/auth/idtoken" "cloud.google.com/go/auth/impersonate" "cloud.google.com/go/auth/internal/testutil" @@ -96,15 +97,15 @@ func TestCredentialsTokenSourceIntegration(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() - var creds *detect.Credentials + var creds *auth.Credentials if !tt.useDefaultCreds { var err error - creds, err = detect.DefaultCredentials(&detect.Options{ + creds, err = credentials.DetectDefault(&credentials.DetectOptions{ Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, CredentialsFile: tt.baseKeyFile, }) if err != nil { - t.Fatalf("detect.DefaultCredentials() = %v", err) + t.Fatalf("credentials.DetectDefault() = %v", err) } } @@ -161,15 +162,15 @@ func TestIDTokenSourceIntegration(t *testing.T) { for _, tt := range tests { name := tt.name t.Run(name, func(t *testing.T) { - var creds *detect.Credentials + var creds *auth.Credentials if !tt.useDefaultCreds { var err error - creds, err = detect.DefaultCredentials(&detect.Options{ + creds, err = credentials.DetectDefault(&credentials.DetectOptions{ Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, CredentialsFile: tt.baseKeyFile, }) if err != nil { - t.Fatalf("detect.DefaultCredentials() = %v", err) + t.Fatalf("credentials.DetectDefault() = %v", err) } } aud := "http://example.com/" diff --git a/auth/internal/internal.go b/auth/internal/internal.go index 8f0048eaf3c..66953bf9576 100644 --- a/auth/internal/internal.go +++ b/auth/internal/internal.go @@ -15,6 +15,7 @@ package internal import ( + "context" "crypto/rsa" "crypto/x509" "encoding/json" @@ -119,3 +120,17 @@ func GetProjectID(b []byte, override string) string { func ReadAll(r io.Reader) ([]byte, error) { return io.ReadAll(io.LimitReader(r, maxBodySize)) } + +// StaticCredentialsProperty is a helper for creating static credentials +// properties. +func StaticCredentialsProperty(s string) StaticProperty { + return StaticProperty(s) +} + +// StaticProperty always returns that value of the underlying string. +type StaticProperty string + +// GetProperty loads the properly value provided the given context. +func (p StaticProperty) GetProperty(context.Context) (string, error) { + return string(p), nil +} diff --git a/auth/internal/transport/transport.go b/auth/internal/transport/transport.go index e4db6b49d39..1cf75af7c31 100644 --- a/auth/internal/transport/transport.go +++ b/auth/internal/transport/transport.go @@ -16,18 +16,18 @@ // (grpctransport and httptransport). package transport -import "cloud.google.com/go/auth/detect" +import "cloud.google.com/go/auth/credentials" // CloneDetectOptions clones a user set detect option into some new memory that // we can internally manipulate before sending onto the detect package. -func CloneDetectOptions(oldDo *detect.Options) *detect.Options { +func CloneDetectOptions(oldDo *credentials.DetectOptions) *credentials.DetectOptions { if oldDo == nil { // it is valid for users not to set this, but we will need to to default // some options for them in this case so return some initialized memory // to work with. - return &detect.Options{} + return &credentials.DetectOptions{} } - newDo := &detect.Options{ + newDo := &credentials.DetectOptions{ // Simple types Audience: oldDo.Audience, Subject: oldDo.Subject, diff --git a/auth/internal/transport/transport_test.go b/auth/internal/transport/transport_test.go index 8e2e0a50a77..ecd444cc7ae 100644 --- a/auth/internal/transport/transport_test.go +++ b/auth/internal/transport/transport_test.go @@ -20,7 +20,7 @@ import ( "testing" "cloud.google.com/go/auth" - "cloud.google.com/go/auth/detect" + "cloud.google.com/go/auth/credentials" ) // TestCloneDetectOptions_FieldTest is meant to fail every time a new field is @@ -30,7 +30,7 @@ import ( // relevant fields. func TestCloneDetectOptions_FieldTest(t *testing.T) { const WantNumberOfFields = 11 - o := detect.Options{} + o := credentials.DetectOptions{} got := reflect.TypeOf(o).NumField() if got != WantNumberOfFields { t.Errorf("if this fails please read comment above the test: got %v, want %v", got, WantNumberOfFields) @@ -38,7 +38,7 @@ func TestCloneDetectOptions_FieldTest(t *testing.T) { } func TestCloneDetectOptions(t *testing.T) { - oldDo := &detect.Options{ + oldDo := &credentials.DetectOptions{ Audience: "aud", Subject: "sub", EarlyTokenRefresh: 42,