regexes ignore case. Update tests.

This commit is contained in:
Patrick Jones 2021-08-12 12:59:29 -07:00
parent a55ea9ec6a
commit 98cc3c1201
3 changed files with 99 additions and 23 deletions

View File

@ -11,6 +11,7 @@ import (
"net/url" "net/url"
"regexp" "regexp"
"strconv" "strconv"
"strings"
"time" "time"
"golang.org/x/oauth2" "golang.org/x/oauth2"
@ -61,10 +62,10 @@ var (
validTokenURLPatterns = []*regexp.Regexp{ validTokenURLPatterns = []*regexp.Regexp{
// The complicated part in the middle matches any number of characters that // The complicated part in the middle matches any number of characters that
// aren't period, spaces, or slashes. // aren't period, spaces, or slashes.
regexp.MustCompile("^[^\\.\\s\\/\\\\]+\\.sts\\.googleapis\\.com$"), regexp.MustCompile("(?i)^[^\\.\\s\\/\\\\]+\\.sts\\.googleapis\\.com$"),
regexp.MustCompile("^sts\\.googleapis\\.com$"), regexp.MustCompile("(?i)^sts\\.googleapis\\.com$"),
regexp.MustCompile("^sts\\.[^\\.\\s\\/\\\\]+\\.googleapis\\.com$"), regexp.MustCompile("(?i)^sts\\.[^\\.\\s\\/\\\\]+\\.googleapis\\.com$"),
regexp.MustCompile("^[^\\.\\s\\/\\\\]+-sts\\.googleapis\\.com$"), regexp.MustCompile("(?i)^[^\\.\\s\\/\\\\]+-sts\\.googleapis\\.com$"),
} }
validImpersonateURLPatterns = []*regexp.Regexp{ validImpersonateURLPatterns = []*regexp.Regexp{
regexp.MustCompile("^[^\\.\\s\\/\\\\]+\\.iamcredentials\\.googleapis\\.com$"), regexp.MustCompile("^[^\\.\\s\\/\\\\]+\\.iamcredentials\\.googleapis\\.com$"),
@ -75,16 +76,14 @@ var (
) )
func validateURL(input string, patterns []*regexp.Regexp, scheme string) bool { func validateURL(input string, patterns []*regexp.Regexp, scheme string) bool {
fmt.Println(input)
parsed, err := url.Parse(input) parsed, err := url.Parse(input)
if err != nil { if err != nil {
return false return false
} }
if parsed.Scheme != scheme { if strings.ToLower(parsed.Scheme) != strings.ToLower(scheme) {
return false return false
} }
toTest := parsed.Host toTest := parsed.Host
fmt.Println(toTest)
for _, pattern := range patterns { for _, pattern := range patterns {
valid := pattern.MatchString(toTest) valid := pattern.MatchString(toTest)

View File

@ -10,6 +10,7 @@ import (
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"regexp" "regexp"
"strings"
"testing" "testing"
"time" "time"
) )
@ -99,9 +100,9 @@ func TestToken(t *testing.T) {
func TestValidateURLTokenURL(t *testing.T) { func TestValidateURLTokenURL(t *testing.T) {
var urlValidityTests = []struct { var urlValidityTests = []struct {
input string tokURL string
pattern []*regexp.Regexp pattern []*regexp.Regexp
result bool expectSuccess bool
}{ }{
{"https://east.sts.googleapis.com", validTokenURLPatterns, true}, {"https://east.sts.googleapis.com", validTokenURLPatterns, true},
{"https://sts.googleapis.com", validTokenURLPatterns, true}, {"https://sts.googleapis.com", validTokenURLPatterns, true},
@ -115,12 +116,60 @@ func TestValidateURLTokenURL(t *testing.T) {
{"https://-sts.googleapis.com", validTokenURLPatterns, false}, {"https://-sts.googleapis.com", validTokenURLPatterns, false},
{"https://us-ea.st-1-sts.googleapis.com", validTokenURLPatterns, false}, {"https://us-ea.st-1-sts.googleapis.com", validTokenURLPatterns, false},
{"https://sts.googleapis.com.evil.com/whatever/path", validTokenURLPatterns, false}, {"https://sts.googleapis.com.evil.com/whatever/path", validTokenURLPatterns, false},
{"https://us-eas\\t-1.sts.googleapis.com", validTokenURLPatterns, false},
{"https:/us-ea/st-1.sts.googleapis.com", validTokenURLPatterns, false},
{"https:/us-east 1.sts.googleapis.com", validTokenURLPatterns, false},
{"https://", validTokenURLPatterns, false},
{"http://us-east-1.sts.googleapis.com", validTokenURLPatterns, false},
{"https://us-east-1.sts.googleapis.comevil.com", validTokenURLPatterns, false},
}
//for _, tt := range urlValidityTests {
// t.Run(" "+tt.input, func(t *testing.T) { // We prepend a space ahead of the test input when outputting for sake of readability.
// valid := validateURL(tt.input, tt.pattern, "https")
// if valid != tt.result {
// t.Errorf("got %v, want %v", valid, tt.result)
// }
// })
//}
//for _, el := range urlValidityTests {
// el.input = strings.ToUpper(el.input)
//}
//for _, tt := range urlValidityTests {
// t.Run(" "+tt.input, func(t *testing.T) { // We prepend a space ahead of the test input when outputting for sake of readability.
// valid := validateURL(tt.input, tt.pattern, "https")
// if valid != tt.result {
// t.Errorf("got %v, want %v", valid, tt.result)
// }
// })
//}
ctx := context.Background()
for _, tt := range urlValidityTests {
t.Run(" "+tt.tokURL, func(t *testing.T) { // We prepend a space ahead of the test input when outputting for sake of readability.
config := testConfig
config.TokenURL = tt.tokURL
_, 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")
}
})
}
for _, el := range urlValidityTests {
el.tokURL = strings.ToUpper(el.tokURL)
} }
for _, tt := range urlValidityTests { for _, tt := range urlValidityTests {
t.Run(" "+tt.input, func(t *testing.T) { // We prepend a space ahead of the test input when outputting for sake of readability. t.Run(" "+tt.tokURL, func(t *testing.T) { // We prepend a space ahead of the test input when outputting for sake of readability.
valid := validateURL(tt.input, tt.pattern, "https") config := testConfig
if valid != tt.result { config.TokenURL = tt.tokURL
t.Errorf("got %v, want %v", valid, tt.result) _, 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")
} }
}) })
} }
@ -128,9 +177,9 @@ func TestValidateURLTokenURL(t *testing.T) {
func TestValidateURLImpersonateURL(t *testing.T) { func TestValidateURLImpersonateURL(t *testing.T) {
var urlValidityTests = []struct { var urlValidityTests = []struct {
input string impURL string
pattern []*regexp.Regexp pattern []*regexp.Regexp
result bool expectSuccess bool
}{ }{
{"https://east.iamcredentials.googleapis.com", validImpersonateURLPatterns, true}, {"https://east.iamcredentials.googleapis.com", validImpersonateURLPatterns, true},
{"https://iamcredentials.googleapis.com", validImpersonateURLPatterns, true}, {"https://iamcredentials.googleapis.com", validImpersonateURLPatterns, true},
@ -144,12 +193,42 @@ func TestValidateURLImpersonateURL(t *testing.T) {
{"https://-iamcredentials.googleapis.com", validImpersonateURLPatterns, false}, {"https://-iamcredentials.googleapis.com", validImpersonateURLPatterns, false},
{"https://us-ea.st-1-iamcredentials.googleapis.com", validImpersonateURLPatterns, false}, {"https://us-ea.st-1-iamcredentials.googleapis.com", validImpersonateURLPatterns, false},
{"https://iamcredentials.googleapis.com.evil.com/whatever/path", validImpersonateURLPatterns, false}, {"https://iamcredentials.googleapis.com.evil.com/whatever/path", validImpersonateURLPatterns, false},
{"https://us-eas\\t-1.iamcredentials.googleapis.com", validImpersonateURLPatterns, false},
{"https:/us-ea/st-1.iamcredentials.googleapis.com", validImpersonateURLPatterns, false},
{"https:/us-east 1.iamcredentials.googleapis.com", validImpersonateURLPatterns, false},
{"https://", validImpersonateURLPatterns, false},
{"http://us-east-1.iamcredentials.googleapis.com", validImpersonateURLPatterns, false},
{"https://us-east-1.iamcredentials.googleapis.comevil.com", validImpersonateURLPatterns, false},
}
ctx := context.Background()
for _, tt := range urlValidityTests {
t.Run(" "+tt.impURL, 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 = tt.impURL
_, 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")
}
})
}
for _, el := range urlValidityTests {
el.impURL = strings.ToUpper(el.impURL)
} }
for _, tt := range urlValidityTests { for _, tt := range urlValidityTests {
t.Run(" "+tt.input, func(t *testing.T) { // We prepend a space ahead of the test input when outputting for sake of readability. t.Run(" "+tt.impURL, func(t *testing.T) { // We prepend a space ahead of the test input when outputting for sake of readability.
valid := validateURL(tt.input, tt.pattern, "https") config := testConfig
if valid != tt.result { config.TokenURL = "https://sts.googleapis.com" // Setting the most basic acceptable tokenURL
t.Errorf("got %v, want %v", valid, tt.result) config.ServiceAccountImpersonationURL = tt.impURL
_, 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")
} }
}) })
} }

View File

@ -6,7 +6,6 @@ package externalaccount
import ( import (
"context" "context"
"fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
@ -81,7 +80,6 @@ func TestImpersonation(t *testing.T) {
allURLs := regexp.MustCompile(".+") allURLs := regexp.MustCompile(".+")
ourTS, err := testImpersonateConfig.tokenSource(context.Background(), []*regexp.Regexp{allURLs}, []*regexp.Regexp{allURLs}, "http") ourTS, err := testImpersonateConfig.tokenSource(context.Background(), []*regexp.Regexp{allURLs}, []*regexp.Regexp{allURLs}, "http")
if err != nil { if err != nil {
fmt.Println(testImpersonateConfig.TokenURL)
t.Fatalf("Failed to create TokenSource: %v", err) t.Fatalf("Failed to create TokenSource: %v", err)
} }