1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2024-12-10 11:10:27 +02:00
oauth2-proxy/validator_test.go

422 lines
12 KiB
Go
Raw Normal View History

package main
import (
"os"
"strings"
"testing"
. "github.com/onsi/gomega"
)
Reload authenticated-emails-file upon update This change extracts the UserMap class from NewValidator() so that its LoadAuthenticatedEmailsFile() method can be called concurrently. This method is called by a goroutine containing a fsnotify.Watcher watching the authenticated emails file. Watching isn't forever aborted when the authenticated emails file disappears. The goroutine will call os.Stat() up to twenty times a second if the file is persistently missing, but that's the pathological case, not the common one. The common case is that some editors (including Vim) will perform a rename-and-replace when updating a file, triggering fsnotify.Rename events, and the file will temporarily disappear. This watcher goroutine handles that case. Also, on some platforms (notably Arch Linux), a remove will be preceded by a fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod the same as fsnotify.Remove and fsnotify.Rename. There's no significant penalty to re-adding a file to the watcher. Also contains the following small changes from the summary of commits below: - Minor optimization of email domain search - Fixed api_test.go on Windows - Add deferred File.Close() calls where needed - Log error and return if emails file doesn't parse These are the original commits from #89 squashed into this one: 0c6f2b6 Refactor validator_test to prepare for more tests e0c792b Add more test cases to validator_test a9a9d93 Minor optimization of email domain search b763ea5 Extract LoadAuthenticatedEmailsFile() 8cdaf7f Introduce synchronized UserMap type 1b84eef Add UserMap methods, locking af15dcf Reload authenticated-emails-file upon update 6d95548 Make UserMap operations lock-free Per: - http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang - https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ 75755d5 Fix tests on Windows d0eab2e Ignore email file watcher Chmod events 0b9798b Fix watcher on Ubuntu 12.04 3a8251a WaitForReplacement() to retry emails file watch a57fd29 Add deferred File.Close() calls where needed Because correctness: Don't leak file handles anywhere, and prepare for future panics and early returns. 52ed3fd Log error and return if emails file doesn't parse 40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file 17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
type ValidatorTest struct {
authEmailFileName string
done chan bool
updateSeen bool
Reload authenticated-emails-file upon update This change extracts the UserMap class from NewValidator() so that its LoadAuthenticatedEmailsFile() method can be called concurrently. This method is called by a goroutine containing a fsnotify.Watcher watching the authenticated emails file. Watching isn't forever aborted when the authenticated emails file disappears. The goroutine will call os.Stat() up to twenty times a second if the file is persistently missing, but that's the pathological case, not the common one. The common case is that some editors (including Vim) will perform a rename-and-replace when updating a file, triggering fsnotify.Rename events, and the file will temporarily disappear. This watcher goroutine handles that case. Also, on some platforms (notably Arch Linux), a remove will be preceded by a fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod the same as fsnotify.Remove and fsnotify.Rename. There's no significant penalty to re-adding a file to the watcher. Also contains the following small changes from the summary of commits below: - Minor optimization of email domain search - Fixed api_test.go on Windows - Add deferred File.Close() calls where needed - Log error and return if emails file doesn't parse These are the original commits from #89 squashed into this one: 0c6f2b6 Refactor validator_test to prepare for more tests e0c792b Add more test cases to validator_test a9a9d93 Minor optimization of email domain search b763ea5 Extract LoadAuthenticatedEmailsFile() 8cdaf7f Introduce synchronized UserMap type 1b84eef Add UserMap methods, locking af15dcf Reload authenticated-emails-file upon update 6d95548 Make UserMap operations lock-free Per: - http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang - https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ 75755d5 Fix tests on Windows d0eab2e Ignore email file watcher Chmod events 0b9798b Fix watcher on Ubuntu 12.04 3a8251a WaitForReplacement() to retry emails file watch a57fd29 Add deferred File.Close() calls where needed Because correctness: Don't leak file handles anywhere, and prepare for future panics and early returns. 52ed3fd Log error and return if emails file doesn't parse 40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file 17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
}
func NewValidatorTest(t *testing.T) *ValidatorTest {
vt := &ValidatorTest{}
var err error
f, err := os.CreateTemp("", "test_auth_emails_")
if err != nil {
t.Fatalf("failed to create temp file: %v", err)
}
if err := f.Close(); err != nil {
t.Fatalf("failed to close temp file: %v", err)
}
vt.authEmailFileName = f.Name()
vt.done = make(chan bool, 1)
Reload authenticated-emails-file upon update This change extracts the UserMap class from NewValidator() so that its LoadAuthenticatedEmailsFile() method can be called concurrently. This method is called by a goroutine containing a fsnotify.Watcher watching the authenticated emails file. Watching isn't forever aborted when the authenticated emails file disappears. The goroutine will call os.Stat() up to twenty times a second if the file is persistently missing, but that's the pathological case, not the common one. The common case is that some editors (including Vim) will perform a rename-and-replace when updating a file, triggering fsnotify.Rename events, and the file will temporarily disappear. This watcher goroutine handles that case. Also, on some platforms (notably Arch Linux), a remove will be preceded by a fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod the same as fsnotify.Remove and fsnotify.Rename. There's no significant penalty to re-adding a file to the watcher. Also contains the following small changes from the summary of commits below: - Minor optimization of email domain search - Fixed api_test.go on Windows - Add deferred File.Close() calls where needed - Log error and return if emails file doesn't parse These are the original commits from #89 squashed into this one: 0c6f2b6 Refactor validator_test to prepare for more tests e0c792b Add more test cases to validator_test a9a9d93 Minor optimization of email domain search b763ea5 Extract LoadAuthenticatedEmailsFile() 8cdaf7f Introduce synchronized UserMap type 1b84eef Add UserMap methods, locking af15dcf Reload authenticated-emails-file upon update 6d95548 Make UserMap operations lock-free Per: - http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang - https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ 75755d5 Fix tests on Windows d0eab2e Ignore email file watcher Chmod events 0b9798b Fix watcher on Ubuntu 12.04 3a8251a WaitForReplacement() to retry emails file watch a57fd29 Add deferred File.Close() calls where needed Because correctness: Don't leak file handles anywhere, and prepare for future panics and early returns. 52ed3fd Log error and return if emails file doesn't parse 40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file 17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
return vt
}
Reload authenticated-emails-file upon update This change extracts the UserMap class from NewValidator() so that its LoadAuthenticatedEmailsFile() method can be called concurrently. This method is called by a goroutine containing a fsnotify.Watcher watching the authenticated emails file. Watching isn't forever aborted when the authenticated emails file disappears. The goroutine will call os.Stat() up to twenty times a second if the file is persistently missing, but that's the pathological case, not the common one. The common case is that some editors (including Vim) will perform a rename-and-replace when updating a file, triggering fsnotify.Rename events, and the file will temporarily disappear. This watcher goroutine handles that case. Also, on some platforms (notably Arch Linux), a remove will be preceded by a fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod the same as fsnotify.Remove and fsnotify.Rename. There's no significant penalty to re-adding a file to the watcher. Also contains the following small changes from the summary of commits below: - Minor optimization of email domain search - Fixed api_test.go on Windows - Add deferred File.Close() calls where needed - Log error and return if emails file doesn't parse These are the original commits from #89 squashed into this one: 0c6f2b6 Refactor validator_test to prepare for more tests e0c792b Add more test cases to validator_test a9a9d93 Minor optimization of email domain search b763ea5 Extract LoadAuthenticatedEmailsFile() 8cdaf7f Introduce synchronized UserMap type 1b84eef Add UserMap methods, locking af15dcf Reload authenticated-emails-file upon update 6d95548 Make UserMap operations lock-free Per: - http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang - https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ 75755d5 Fix tests on Windows d0eab2e Ignore email file watcher Chmod events 0b9798b Fix watcher on Ubuntu 12.04 3a8251a WaitForReplacement() to retry emails file watch a57fd29 Add deferred File.Close() calls where needed Because correctness: Don't leak file handles anywhere, and prepare for future panics and early returns. 52ed3fd Log error and return if emails file doesn't parse 40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file 17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
func (vt *ValidatorTest) TearDown() {
vt.done <- true
os.Remove(vt.authEmailFileName)
Reload authenticated-emails-file upon update This change extracts the UserMap class from NewValidator() so that its LoadAuthenticatedEmailsFile() method can be called concurrently. This method is called by a goroutine containing a fsnotify.Watcher watching the authenticated emails file. Watching isn't forever aborted when the authenticated emails file disappears. The goroutine will call os.Stat() up to twenty times a second if the file is persistently missing, but that's the pathological case, not the common one. The common case is that some editors (including Vim) will perform a rename-and-replace when updating a file, triggering fsnotify.Rename events, and the file will temporarily disappear. This watcher goroutine handles that case. Also, on some platforms (notably Arch Linux), a remove will be preceded by a fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod the same as fsnotify.Remove and fsnotify.Rename. There's no significant penalty to re-adding a file to the watcher. Also contains the following small changes from the summary of commits below: - Minor optimization of email domain search - Fixed api_test.go on Windows - Add deferred File.Close() calls where needed - Log error and return if emails file doesn't parse These are the original commits from #89 squashed into this one: 0c6f2b6 Refactor validator_test to prepare for more tests e0c792b Add more test cases to validator_test a9a9d93 Minor optimization of email domain search b763ea5 Extract LoadAuthenticatedEmailsFile() 8cdaf7f Introduce synchronized UserMap type 1b84eef Add UserMap methods, locking af15dcf Reload authenticated-emails-file upon update 6d95548 Make UserMap operations lock-free Per: - http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang - https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ 75755d5 Fix tests on Windows d0eab2e Ignore email file watcher Chmod events 0b9798b Fix watcher on Ubuntu 12.04 3a8251a WaitForReplacement() to retry emails file watch a57fd29 Add deferred File.Close() calls where needed Because correctness: Don't leak file handles anywhere, and prepare for future panics and early returns. 52ed3fd Log error and return if emails file doesn't parse 40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file 17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
}
func (vt *ValidatorTest) NewValidator(domains []string,
updated chan<- bool) func(string) bool {
return newValidatorImpl(domains, vt.authEmailFileName,
Ensure watcher tests don't block during shutdown These test failures from #93 inspired this change: https://travis-ci.org/bitly/google_auth_proxy/jobs/62474406 https://travis-ci.org/bitly/google_auth_proxy/jobs/62474407 Both tests exhibited this pattern: 2015/05/13 22:10:54 validating: is xyzzy@example.com valid? false 2015/05/13 22:10:54 watching interrupted on event: "/tmp/test_auth_emails_300880185": CHMOD 2015/05/13 22:10:54 watching resumed for /tmp/test_auth_emails_300880185 2015/05/13 22:10:54 reloading after event: "/tmp/test_auth_emails_300880185": CHMOD panic: test timed out after 1m0s [snip] goroutine 175 [chan send]: github.com/bitly/google_auth_proxy.(*ValidatorTest).TearDown(0xc2080bc330) /home/travis/gopath/src/github.com/bitly/google_auth_proxy/validator_test.go:27 +0x43 github.com/bitly/google_auth_proxy.TestValidatorOverwriteEmailListViaRenameAndReplace(0xc2080f2480) /home/travis/gopath/src/github.com/bitly/google_auth_proxy/validator_watcher_test.go:103 +0x3b9 [snip] goroutine 177 [chan send]: github.com/bitly/google_auth_proxy.func·017() /home/travis/gopath/src/github.com/bitly/google_auth_proxy/validator_test.go:34 +0x41 I realized that the spurious CHMOD events were causing calls to `func() { updated <- true }` (from validator_test.go:34), which caused the goroutine running the watcher to block. At the same time, ValidatorTest.TearDown was blocked by trying to send into the `done` channel. The solution was to create a flag that ensured only one value was ever sent into the update channel.
2015-05-14 00:30:22 +02:00
vt.done, func() {
2018-11-29 16:26:41 +02:00
if vt.updateSeen == false {
Ensure watcher tests don't block during shutdown These test failures from #93 inspired this change: https://travis-ci.org/bitly/google_auth_proxy/jobs/62474406 https://travis-ci.org/bitly/google_auth_proxy/jobs/62474407 Both tests exhibited this pattern: 2015/05/13 22:10:54 validating: is xyzzy@example.com valid? false 2015/05/13 22:10:54 watching interrupted on event: "/tmp/test_auth_emails_300880185": CHMOD 2015/05/13 22:10:54 watching resumed for /tmp/test_auth_emails_300880185 2015/05/13 22:10:54 reloading after event: "/tmp/test_auth_emails_300880185": CHMOD panic: test timed out after 1m0s [snip] goroutine 175 [chan send]: github.com/bitly/google_auth_proxy.(*ValidatorTest).TearDown(0xc2080bc330) /home/travis/gopath/src/github.com/bitly/google_auth_proxy/validator_test.go:27 +0x43 github.com/bitly/google_auth_proxy.TestValidatorOverwriteEmailListViaRenameAndReplace(0xc2080f2480) /home/travis/gopath/src/github.com/bitly/google_auth_proxy/validator_watcher_test.go:103 +0x3b9 [snip] goroutine 177 [chan send]: github.com/bitly/google_auth_proxy.func·017() /home/travis/gopath/src/github.com/bitly/google_auth_proxy/validator_test.go:34 +0x41 I realized that the spurious CHMOD events were causing calls to `func() { updated <- true }` (from validator_test.go:34), which caused the goroutine running the watcher to block. At the same time, ValidatorTest.TearDown was blocked by trying to send into the `done` channel. The solution was to create a flag that ensured only one value was ever sent into the update channel.
2015-05-14 00:30:22 +02:00
updated <- true
2018-11-29 16:26:41 +02:00
vt.updateSeen = true
Ensure watcher tests don't block during shutdown These test failures from #93 inspired this change: https://travis-ci.org/bitly/google_auth_proxy/jobs/62474406 https://travis-ci.org/bitly/google_auth_proxy/jobs/62474407 Both tests exhibited this pattern: 2015/05/13 22:10:54 validating: is xyzzy@example.com valid? false 2015/05/13 22:10:54 watching interrupted on event: "/tmp/test_auth_emails_300880185": CHMOD 2015/05/13 22:10:54 watching resumed for /tmp/test_auth_emails_300880185 2015/05/13 22:10:54 reloading after event: "/tmp/test_auth_emails_300880185": CHMOD panic: test timed out after 1m0s [snip] goroutine 175 [chan send]: github.com/bitly/google_auth_proxy.(*ValidatorTest).TearDown(0xc2080bc330) /home/travis/gopath/src/github.com/bitly/google_auth_proxy/validator_test.go:27 +0x43 github.com/bitly/google_auth_proxy.TestValidatorOverwriteEmailListViaRenameAndReplace(0xc2080f2480) /home/travis/gopath/src/github.com/bitly/google_auth_proxy/validator_watcher_test.go:103 +0x3b9 [snip] goroutine 177 [chan send]: github.com/bitly/google_auth_proxy.func·017() /home/travis/gopath/src/github.com/bitly/google_auth_proxy/validator_test.go:34 +0x41 I realized that the spurious CHMOD events were causing calls to `func() { updated <- true }` (from validator_test.go:34), which caused the goroutine running the watcher to block. At the same time, ValidatorTest.TearDown was blocked by trying to send into the `done` channel. The solution was to create a flag that ensured only one value was ever sent into the update channel.
2015-05-14 00:30:22 +02:00
}
})
}
Reload authenticated-emails-file upon update This change extracts the UserMap class from NewValidator() so that its LoadAuthenticatedEmailsFile() method can be called concurrently. This method is called by a goroutine containing a fsnotify.Watcher watching the authenticated emails file. Watching isn't forever aborted when the authenticated emails file disappears. The goroutine will call os.Stat() up to twenty times a second if the file is persistently missing, but that's the pathological case, not the common one. The common case is that some editors (including Vim) will perform a rename-and-replace when updating a file, triggering fsnotify.Rename events, and the file will temporarily disappear. This watcher goroutine handles that case. Also, on some platforms (notably Arch Linux), a remove will be preceded by a fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod the same as fsnotify.Remove and fsnotify.Rename. There's no significant penalty to re-adding a file to the watcher. Also contains the following small changes from the summary of commits below: - Minor optimization of email domain search - Fixed api_test.go on Windows - Add deferred File.Close() calls where needed - Log error and return if emails file doesn't parse These are the original commits from #89 squashed into this one: 0c6f2b6 Refactor validator_test to prepare for more tests e0c792b Add more test cases to validator_test a9a9d93 Minor optimization of email domain search b763ea5 Extract LoadAuthenticatedEmailsFile() 8cdaf7f Introduce synchronized UserMap type 1b84eef Add UserMap methods, locking af15dcf Reload authenticated-emails-file upon update 6d95548 Make UserMap operations lock-free Per: - http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang - https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ 75755d5 Fix tests on Windows d0eab2e Ignore email file watcher Chmod events 0b9798b Fix watcher on Ubuntu 12.04 3a8251a WaitForReplacement() to retry emails file watch a57fd29 Add deferred File.Close() calls where needed Because correctness: Don't leak file handles anywhere, and prepare for future panics and early returns. 52ed3fd Log error and return if emails file doesn't parse 40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file 17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
func (vt *ValidatorTest) WriteEmails(t *testing.T, emails []string) {
f, err := os.OpenFile(vt.authEmailFileName, os.O_WRONLY, 0600)
if err != nil {
t.Fatalf("failed to open auth email file: %v", err)
}
if _, err := f.WriteString(strings.Join(emails, "\n")); err != nil {
t.Fatalf("failed to write emails to auth email file: %v", err)
}
if err := f.Close(); err != nil {
t.Fatalf("failed to close auth email file: %v", err)
Reload authenticated-emails-file upon update This change extracts the UserMap class from NewValidator() so that its LoadAuthenticatedEmailsFile() method can be called concurrently. This method is called by a goroutine containing a fsnotify.Watcher watching the authenticated emails file. Watching isn't forever aborted when the authenticated emails file disappears. The goroutine will call os.Stat() up to twenty times a second if the file is persistently missing, but that's the pathological case, not the common one. The common case is that some editors (including Vim) will perform a rename-and-replace when updating a file, triggering fsnotify.Rename events, and the file will temporarily disappear. This watcher goroutine handles that case. Also, on some platforms (notably Arch Linux), a remove will be preceded by a fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod the same as fsnotify.Remove and fsnotify.Rename. There's no significant penalty to re-adding a file to the watcher. Also contains the following small changes from the summary of commits below: - Minor optimization of email domain search - Fixed api_test.go on Windows - Add deferred File.Close() calls where needed - Log error and return if emails file doesn't parse These are the original commits from #89 squashed into this one: 0c6f2b6 Refactor validator_test to prepare for more tests e0c792b Add more test cases to validator_test a9a9d93 Minor optimization of email domain search b763ea5 Extract LoadAuthenticatedEmailsFile() 8cdaf7f Introduce synchronized UserMap type 1b84eef Add UserMap methods, locking af15dcf Reload authenticated-emails-file upon update 6d95548 Make UserMap operations lock-free Per: - http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang - https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ 75755d5 Fix tests on Windows d0eab2e Ignore email file watcher Chmod events 0b9798b Fix watcher on Ubuntu 12.04 3a8251a WaitForReplacement() to retry emails file watch a57fd29 Add deferred File.Close() calls where needed Because correctness: Don't leak file handles anywhere, and prepare for future panics and early returns. 52ed3fd Log error and return if emails file doesn't parse 40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file 17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
}
}
func TestValidatorOverwriteEmailListDirectly(t *testing.T) {
testCasesPreUpdate := []struct {
name string
email string
expectedAuthZ bool
}{
{
name: "FirstEmailInList",
email: "xyzzy@example.com",
expectedAuthZ: true,
},
{
name: "SecondEmailInList",
email: "plugh@example.com",
expectedAuthZ: true,
},
{
name: "EmailNotInListThatMatchesNoDomains",
email: "xyzzy.plugh@example.com",
expectedAuthZ: false,
},
}
testCasesPostUpdate := []struct {
name string
email string
expectedAuthZ bool
}{
{
name: "email removed from list",
email: "xyzzy@example.com",
expectedAuthZ: false,
},
{
name: "email retained in list",
email: "plugh@example.com",
expectedAuthZ: true,
},
{
name: "email added to list",
email: "xyzzy.plugh@example.com",
expectedAuthZ: true,
},
}
vt := NewValidatorTest(t)
defer vt.TearDown()
vt.WriteEmails(t, []string{
"xyzzy@example.com",
"plugh@example.com",
})
updated := make(chan bool)
validator := vt.NewValidator([]string(nil), updated)
for _, tc := range testCasesPreUpdate {
t.Run(tc.name, func(t *testing.T) {
g := NewWithT(t)
authorized := validator(tc.email)
g.Expect(authorized).To(Equal(tc.expectedAuthZ))
})
}
vt.WriteEmails(t, []string{
"xyzzy.plugh@example.com",
"plugh@example.com",
})
<-updated
for _, tc := range testCasesPostUpdate {
t.Run(tc.name, func(t *testing.T) {
g := NewWithT(t)
authorized := validator(tc.email)
g.Expect(authorized).To(Equal(tc.expectedAuthZ))
})
}
}
func TestValidatorCases(t *testing.T) {
testCases := []struct {
name string
allowedEmails []string
allowedDomains []string
email string
expectedAuthZ bool
}{
{
name: "EmailNotInCorrect1stSubDomainsNotInEmails",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{".example0.com", ".example1.com"},
email: "foo.bar@example0.com",
expectedAuthZ: false,
},
{
name: "EmailNotInCorrect1stSubDomainsNotInEmailsWildcard",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{"*.example0.com", "*.example1.com"},
email: "foo.bar@example0.com",
expectedAuthZ: false,
},
{
name: "EmailInFirstDomain",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{".example0.com", ".example1.com"},
email: "foo@bar.example0.com",
expectedAuthZ: true,
},
{
name: "EmailInFirstDomainWildcard",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{"*.example0.com", "*.example1.com"},
email: "foo@bar.example0.com",
expectedAuthZ: true,
},
{
name: "EmailNotInCorrect2ndSubDomainsNotInEmails",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{".example0.com", ".example1.com"},
email: "baz.quux@example1.com",
expectedAuthZ: false,
},
{
name: "EmailInSecondDomain",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{".example0.com", ".example1.com"},
email: "baz@quux.example1.com",
expectedAuthZ: true,
},
{
name: "EmailInSecondDomainWildcard",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{"*.example0.com", "*.example1.com"},
email: "baz@quux.example1.com",
expectedAuthZ: true,
},
{
name: "EmailInFirstEmailList",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{".example0.com", ".example1.com"},
email: "xyzzy@example.com",
expectedAuthZ: true,
},
{
name: "EmailInFirstEmailListWildcard",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{"*.example0.com", "*.example1.com"},
email: "xyzzy@example.com",
expectedAuthZ: true,
},
{
name: "EmailNotInDomainsNotInEmails",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{".example0.com", ".example1.com"},
email: "xyzzy.plugh@example.com",
expectedAuthZ: false,
},
{
name: "EmailInLastEmailList",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{".example0.com", ".example1.com"},
email: "plugh@example.com",
expectedAuthZ: true,
},
{
name: "EmailIn1stSubdomain",
allowedEmails: nil,
allowedDomains: []string{"us.example.com", "de.example.com", "example.com"},
email: "xyzzy@us.example.com",
expectedAuthZ: true,
},
{
name: "EmailIn2ndSubdomain",
allowedEmails: nil,
allowedDomains: []string{"us.example.com", "de.example.com", "example.com"},
email: "xyzzy@de.example.com",
expectedAuthZ: true,
},
{
name: "EmailNotInAnySubdomain",
allowedEmails: nil,
allowedDomains: []string{"us.example.com", "de.example.com", "example.com"},
email: "global@au.example.com",
expectedAuthZ: false,
},
{
name: "EmailInLastSubdomain",
allowedEmails: nil,
allowedDomains: []string{"us.example.com", "de.example.com", "example.com"},
email: "xyzzy@example.com",
expectedAuthZ: true,
},
{
name: "EmailDomainNotCompletelyMatch",
allowedEmails: nil,
allowedDomains: []string{".example.com", ".example1.com"},
email: "something@fooexample.com",
expectedAuthZ: false,
},
{
name: "HackerExtraDomainPrefix1",
allowedEmails: nil,
allowedDomains: []string{".mycompany.com"},
email: "something@evilhackmycompany.com",
expectedAuthZ: false,
},
{
name: "HackerExtraDomainPrefix2",
allowedEmails: nil,
allowedDomains: []string{".mycompany.com"},
email: "something@ext.evilhackmycompany.com",
expectedAuthZ: false,
},
{
name: "EmptyDomainAndEmailList",
allowedEmails: []string(nil),
allowedDomains: []string(nil),
email: "foo.bar@example.com",
expectedAuthZ: false,
},
{
name: "EmailMatchWithAllowedEmails",
email: "foo.bar@example.com",
allowedEmails: []string{"foo.bar@example.com"},
allowedDomains: []string{"example.com"},
expectedAuthZ: true,
},
{
name: "EmailFromSameDomainButNotInList",
email: "baz.quux@example.com",
allowedEmails: []string{"foo.bar@example.com"},
allowedDomains: []string(nil),
expectedAuthZ: false,
},
{
name: "EmailMatchOnDomain",
email: "foo.bar@example.com",
allowedEmails: []string(nil),
allowedDomains: []string{"example.com"},
expectedAuthZ: true,
},
{
name: "EmailMatchOnDomain2",
email: "baz.quux@example.com",
allowedEmails: []string(nil),
allowedDomains: []string{"example.com"},
expectedAuthZ: true,
},
{
name: "EmailFromFirstDomainShouldValidate",
email: "foo.bar@example0.com",
allowedEmails: []string{"Foo.Bar@Example.Com"},
allowedDomains: []string{"example0.com", "example1.com"},
expectedAuthZ: true,
},
{
name: "EmailFromSecondDomainShouldValidate",
email: "baz.quux@example1.com",
allowedEmails: []string{"Foo.Bar@Example.Com"},
allowedDomains: []string{"example0.com", "example1.com"},
expectedAuthZ: true,
},
{
name: "FirstEmailInListShouldValidate",
email: "xyzzy@example.com",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{"example0.com", "example1.com"},
expectedAuthZ: true,
},
{
name: "SecondEmailInListShouldValidate",
email: "plugh@example.com",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{"example0.com", "example1.com"},
expectedAuthZ: true,
},
{
name: "EmailNotInListThatMatchesNoDomains ",
email: "xyzzy.plugh@example.com",
allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
allowedDomains: []string{"example0.com", "example1.com"},
expectedAuthZ: false,
},
{
name: "LoadedEmailAddressesAreNotLowerCased",
email: "foo.bar@example.com",
allowedEmails: []string{"Foo.Bar@Example.Com"},
allowedDomains: []string{"Frobozz.Com"},
expectedAuthZ: true,
},
{
name: "ValidatedEmailAddressesAreNotLowerCased",
email: "Foo.Bar@Example.Com",
allowedEmails: []string{"Foo.Bar@Example.Com"},
allowedDomains: []string{"Frobozz.Com"},
expectedAuthZ: true,
},
{
name: "LoadedDomainsAreNotLowerCased",
email: "foo.bar@frobozz.com",
allowedEmails: []string{"Foo.Bar@Example.Com"},
allowedDomains: []string{"Frobozz.Com"},
expectedAuthZ: true,
},
{
name: "ValidatedDomainsAreNotLowerCased",
email: "foo.bar@Frobozz.Com",
allowedEmails: []string{"Foo.Bar@Example.Com"},
allowedDomains: []string{"Frobozz.Com"},
expectedAuthZ: true,
},
{
name: "IgnoreSpacesInAuthEmails",
email: "foo.bar@example.com",
allowedEmails: []string{" foo.bar@example.com "},
allowedDomains: []string(nil),
expectedAuthZ: true,
},
{
name: "IgnorePrefixSpacesInAuthEmails",
email: "foo.bar@example.com",
allowedEmails: []string{" foo.bar@example.com"},
allowedDomains: []string(nil),
expectedAuthZ: true,
},
{
name: "CheckForEqualityNotSuffix",
email: "foo@evilcompany.com",
allowedEmails: []string(nil),
allowedDomains: []string{".company.com"},
expectedAuthZ: false,
},
{
name: "CheckForEqualityNotSuffix2",
email: "foo@evilcompany.com",
allowedEmails: []string(nil),
allowedDomains: []string{"company.com"},
expectedAuthZ: false,
},
{
name: "CheckForEqualityNotSuffixWildcard",
email: "foo@evilcompany.com",
allowedEmails: []string(nil),
allowedDomains: []string{"*.company.com"},
expectedAuthZ: false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
vt := NewValidatorTest(t)
defer vt.TearDown()
g := NewWithT(t)
vt.WriteEmails(t, tc.allowedEmails)
validator := vt.NewValidator(tc.allowedDomains, nil)
authorized := validator(tc.email)
g.Expect(authorized).To(Equal(tc.expectedAuthZ))
})
}
}