forked from remote/oauth2
adding test for workforce pools for new option as requested by bojeil@; adding unit testing; go fmt
This commit is contained in:
@@ -78,6 +78,7 @@ var (
|
|||||||
regexp.MustCompile(`^iamcredentials\.[^\.\s\/\\]+\.googleapis\.com$`),
|
regexp.MustCompile(`^iamcredentials\.[^\.\s\/\\]+\.googleapis\.com$`),
|
||||||
regexp.MustCompile(`^[^\.\s\/\\]+-iamcredentials\.googleapis\.com$`),
|
regexp.MustCompile(`^[^\.\s\/\\]+-iamcredentials\.googleapis\.com$`),
|
||||||
}
|
}
|
||||||
|
validWorkforceAudiencePattern *regexp.Regexp = regexp.MustCompile(`//iam\.googleapis\.com/locations/[^/]+/workforcePools/`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func validateURL(input string, patterns []*regexp.Regexp, scheme string) bool {
|
func validateURL(input string, patterns []*regexp.Regexp, scheme string) bool {
|
||||||
@@ -91,14 +92,17 @@ func validateURL(input string, patterns []*regexp.Regexp, scheme string) bool {
|
|||||||
toTest := parsed.Host
|
toTest := parsed.Host
|
||||||
|
|
||||||
for _, pattern := range patterns {
|
for _, pattern := range patterns {
|
||||||
|
if pattern.MatchString(toTest) {
|
||||||
if valid := pattern.MatchString(toTest); valid {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateWorkforceAudience(input string) bool {
|
||||||
|
return validWorkforceAudiencePattern.MatchString(input)
|
||||||
|
}
|
||||||
|
|
||||||
// TokenSource Returns an external account TokenSource struct. This is to be called by package google to construct a google.Credentials.
|
// TokenSource Returns an external account TokenSource struct. This is to be called by package google to construct a google.Credentials.
|
||||||
func (c *Config) TokenSource(ctx context.Context) (oauth2.TokenSource, error) {
|
func (c *Config) TokenSource(ctx context.Context) (oauth2.TokenSource, error) {
|
||||||
return c.tokenSource(ctx, validTokenURLPatterns, validImpersonateURLPatterns, "https")
|
return c.tokenSource(ctx, validTokenURLPatterns, validImpersonateURLPatterns, "https")
|
||||||
@@ -120,6 +124,13 @@ func (c *Config) tokenSource(ctx context.Context, tokenURLValidPats []*regexp.Re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.WorkforcePoolUserProject != "" {
|
||||||
|
valid := validateWorkforceAudience(c.Audience)
|
||||||
|
if !valid {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: invalid Workforce Pool Audience provided while constructing tokenSource")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ts := tokenSource{
|
ts := tokenSource{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
conf: c,
|
conf: c,
|
||||||
@@ -229,10 +240,10 @@ func (ts tokenSource) Token() (*oauth2.Token, error) {
|
|||||||
ClientID: conf.ClientID,
|
ClientID: conf.ClientID,
|
||||||
ClientSecret: conf.ClientSecret,
|
ClientSecret: conf.ClientSecret,
|
||||||
}
|
}
|
||||||
var options map[string]string
|
var options map[string]interface{}
|
||||||
if (ts.Config.WorkforcePoolUserProject != "") {
|
if conf.WorkforcePoolUserProject != "" {
|
||||||
options = map[string]string{
|
options = map[string]interface{}{
|
||||||
"userProject": ts.Config.WorkforcePoolUserProject,
|
"userProject": conf.WorkforcePoolUserProject,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stsResp, err := exchangeToken(ts.ctx, conf.TokenURL, &stsRequest, clientAuth, header, options)
|
stsResp, err := exchangeToken(ts.ctx, conf.TokenURL, &stsRequest, clientAuth, header, options)
|
||||||
|
|||||||
@@ -210,3 +210,41 @@ func TestValidateURLImpersonateURL(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWorkforcePoolCreation(t *testing.T) {
|
||||||
|
var audienceValidatyTests = []struct {
|
||||||
|
audience string
|
||||||
|
expectSuccess bool
|
||||||
|
}{
|
||||||
|
{"//iam.googleapis.com/locations/global/workforcePools/pool-id/providers/provider-id", true},
|
||||||
|
{"//iam.googleapis.com/locations/eu/workforcePools/pool-id/providers/provider-id", true},
|
||||||
|
{"//iam.googleapis.com/locations/eu/workforcePools/workloadIdentityPools/providers/provider-id", true},
|
||||||
|
{"identitynamespace:1f12345:my_provider", false},
|
||||||
|
{"//iam.googleapis.com/projects/123456/locations/global/workloadIdentityPools/pool-id/providers/provider-id", false},
|
||||||
|
{"//iam.googleapis.com/projects/123456/locations/eu/workloadIdentityPools/pool-id/providers/provider-id", false},
|
||||||
|
{"//iam.googleapis.com/projects/123456/locations/global/workloadIdentityPools/workforcePools/providers/provider-id", false},
|
||||||
|
{"//iamgoogleapis.com/locations/eu/workforcePools/pool-id/providers/provider-id", false},
|
||||||
|
{"//iam.googleapiscom/locations/eu/workforcePools/pool-id/providers/provider-id", false},
|
||||||
|
{"//iam.googleapis.com/locations/workforcePools/pool-id/providers/provider-id", false},
|
||||||
|
{"//iam.googleapis.com/locations/eu/workforcePool/pool-id/providers/provider-id", false},
|
||||||
|
{"//iam.googleapis.com/locations//workforcePool/pool-id/providers/provider-id", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
for _, tt := range audienceValidatyTests {
|
||||||
|
t.Run(" "+tt.audience, func(t *testing.T) { // We prepend a space ahead of the test input when outputting for sake of readability.
|
||||||
|
config := testConfig
|
||||||
|
config.TokenURL = "https://sts.googleapis.com" // Setting the most basic acceptable tokenURL
|
||||||
|
config.ServiceAccountImpersonationURL = "https://iamcredentials.googleapis.com"
|
||||||
|
config.Audience = tt.audience
|
||||||
|
config.WorkforcePoolUserProject = "myProject"
|
||||||
|
_, err := config.TokenSource(ctx)
|
||||||
|
|
||||||
|
if tt.expectSuccess && err != nil {
|
||||||
|
t.Errorf("got %v but want nil", err)
|
||||||
|
} else if !tt.expectSuccess && err == nil {
|
||||||
|
t.Errorf("got nil but expected an error")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user