diff --git a/go.mod b/go.mod index 299ec4484..85ac2cbf8 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,6 @@ require ( require ( cloud.google.com/go/compute v1.20.1 // indirect github.com/golang/protobuf v1.5.3 // indirect - golang.org/x/net v0.20.0 // indirect + golang.org/x/net v0.21.0 // indirect google.golang.org/protobuf v1.31.0 // indirect ) diff --git a/go.sum b/go.sum index cfc19e8cb..ab5659465 100644 --- a/go.sum +++ b/go.sum @@ -11,8 +11,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= diff --git a/google/downscope/downscoping.go b/google/downscope/downscoping.go index 3d4b5532d..ca1f35462 100644 --- a/google/downscope/downscoping.go +++ b/google/downscope/downscoping.go @@ -42,13 +42,16 @@ import ( "io/ioutil" "net/http" "net/url" + "strings" "time" "golang.org/x/oauth2" ) -var ( - identityBindingEndpoint = "https://sts.googleapis.com/v1/token" +const ( + universeDomainPlaceholder = "UNIVERSE_DOMAIN" + identityBindingEndpointTemplate = "https://sts.UNIVERSE_DOMAIN/v1/token" + universeDomainDefault = "googleapis.com" ) type accessBoundary struct { @@ -105,6 +108,18 @@ type DownscopingConfig struct { // access (or set of accesses) that the new token has to a given resource. // There can be a maximum of 10 AccessBoundaryRules. Rules []AccessBoundaryRule + // UniverseDomain is the default service domain for a given Cloud universe. + // The default value is "googleapis.com". Optional. + UniverseDomain string +} + +// identityBindingEndpoint returns the identity binding endpoint with the +// configured universe domain. +func (dc *DownscopingConfig) identityBindingEndpoint() string { + if dc.UniverseDomain == "" { + return strings.Replace(identityBindingEndpointTemplate, universeDomainPlaceholder, universeDomainDefault, 1) + } + return strings.Replace(identityBindingEndpointTemplate, universeDomainPlaceholder, dc.UniverseDomain, 1) } // A downscopingTokenSource is used to retrieve a downscoped token with restricted @@ -114,6 +129,9 @@ type downscopingTokenSource struct { ctx context.Context // config holds the information necessary to generate a downscoped Token. config DownscopingConfig + // identityBindingEndpoint is the identity binding endpoint with the + // configured universe domain. + identityBindingEndpoint string } // NewTokenSource returns a configured downscopingTokenSource. @@ -135,7 +153,11 @@ func NewTokenSource(ctx context.Context, conf DownscopingConfig) (oauth2.TokenSo return nil, fmt.Errorf("downscope: all rules must provide at least one permission: %+v", val) } } - return downscopingTokenSource{ctx: ctx, config: conf}, nil + return downscopingTokenSource{ + ctx: ctx, + config: conf, + identityBindingEndpoint: conf.identityBindingEndpoint(), + }, nil } // Token() uses a downscopingTokenSource to generate an oauth2 Token. @@ -171,7 +193,7 @@ func (dts downscopingTokenSource) Token() (*oauth2.Token, error) { form.Add("options", string(b)) myClient := oauth2.NewClient(dts.ctx, nil) - resp, err := myClient.PostForm(identityBindingEndpoint, form) + resp, err := myClient.PostForm(dts.identityBindingEndpoint, form) if err != nil { return nil, fmt.Errorf("unable to generate POST Request %v", err) } diff --git a/google/downscope/downscoping_test.go b/google/downscope/downscoping_test.go index d5adda19c..ecdd98691 100644 --- a/google/downscope/downscoping_test.go +++ b/google/downscope/downscoping_test.go @@ -38,18 +38,43 @@ func Test_DownscopedTokenSource(t *testing.T) { w.Write([]byte(standardRespBody)) })) - new := []AccessBoundaryRule{ + myTok := oauth2.Token{AccessToken: "Mellon"} + tmpSrc := oauth2.StaticTokenSource(&myTok) + rules := []AccessBoundaryRule{ { AvailableResource: "test1", AvailablePermissions: []string{"Perm1", "Perm2"}, }, } - myTok := oauth2.Token{AccessToken: "Mellon"} - tmpSrc := oauth2.StaticTokenSource(&myTok) - dts := downscopingTokenSource{context.Background(), DownscopingConfig{tmpSrc, new}} - identityBindingEndpoint = ts.URL + dts := downscopingTokenSource{ + ctx: context.Background(), + config: DownscopingConfig{ + RootSource: tmpSrc, + Rules: rules, + }, + identityBindingEndpoint: ts.URL, + } _, err := dts.Token() if err != nil { t.Fatalf("NewDownscopedTokenSource failed with error: %v", err) } } + +func Test_DownscopingConfig(t *testing.T) { + tests := []struct { + universeDomain string + want string + }{ + {"", "https://sts.googleapis.com/v1/token"}, + {"googleapis.com", "https://sts.googleapis.com/v1/token"}, + {"example.com", "https://sts.example.com/v1/token"}, + } + for _, tt := range tests { + c := DownscopingConfig{ + UniverseDomain: tt.universeDomain, + } + if got := c.identityBindingEndpoint(); got != tt.want { + t.Errorf("got %q, want %q", got, tt.want) + } + } +} diff --git a/google/internal/externalaccount/executablecredsource.go b/google/internal/externalaccount/executablecredsource.go index 6497dc022..843d1c330 100644 --- a/google/internal/externalaccount/executablecredsource.go +++ b/google/internal/externalaccount/executablecredsource.go @@ -19,7 +19,7 @@ import ( "time" ) -var serviceAccountImpersonationRE = regexp.MustCompile("https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/(.*@.*):generateAccessToken") +var serviceAccountImpersonationRE = regexp.MustCompile("https://iamcredentials\\..+/v1/projects/-/serviceAccounts/(.*@.*):generateAccessToken") const ( executableSupportedMaxVersion = 1 diff --git a/google/internal/externalaccount/executablecredsource_test.go b/google/internal/externalaccount/executablecredsource_test.go index df8a906b9..18ee049ff 100644 --- a/google/internal/externalaccount/executablecredsource_test.go +++ b/google/internal/externalaccount/executablecredsource_test.go @@ -1021,3 +1021,37 @@ func TestRetrieveOutputFileSubjectTokenJwt(t *testing.T) { }) } } + +func TestServiceAccountImpersonationRE(t *testing.T) { + tests := []struct { + name string + serviceAccountImpersonationURL string + want string + }{ + { + name: "universe domain Google Default Universe (GDU) googleapis.com", + serviceAccountImpersonationURL: "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/test@project.iam.gserviceaccount.com:generateAccessToken", + want: "test@project.iam.gserviceaccount.com", + }, + { + name: "email does not match", + serviceAccountImpersonationURL: "test@project.iam.gserviceaccount.com", + want: "", + }, + { + name: "universe domain non-GDU", + serviceAccountImpersonationURL: "https://iamcredentials.apis-tpclp.goog/v1/projects/-/serviceAccounts/test@project.iam.gserviceaccount.com:generateAccessToken", + want: "test@project.iam.gserviceaccount.com", + }, + } + for _, tt := range tests { + matches := serviceAccountImpersonationRE.FindStringSubmatch(tt.serviceAccountImpersonationURL) + if matches == nil { + if tt.want != "" { + t.Errorf("%q: got nil, want %q", tt.name, tt.want) + } + } else if matches[1] != tt.want { + t.Errorf("%q: got %q, want %q", tt.name, matches[1], tt.want) + } + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy