git.iko.soy/typeable/oauth2-proxy
on master help sign in
typeable/oauth2-proxy/validator_test.go
442 lines 13 kB history raw
1package main
3import (
4 "os"
5 "strings"
6 "testing"
8 . "github.com/onsi/gomega"
9)
11type ValidatorTest struct {
12 authEmailFileName string
13 done chan bool
14 updateSeen bool
17func NewValidatorTest(t *testing.T) *ValidatorTest {
18 vt := &ValidatorTest{}
19 var err error
20 f, err := os.CreateTemp("", "test_auth_emails_")
21 if err != nil {
22 t.Fatalf("failed to create temp file: %v", err)
23 }
24 if err := f.Close(); err != nil {
25 t.Fatalf("failed to close temp file: %v", err)
26 }
27 vt.authEmailFileName = f.Name()
28 vt.done = make(chan bool, 1)
29 return vt
32func (vt *ValidatorTest) TearDown() {
33 vt.done <- true
34 os.Remove(vt.authEmailFileName)
37func (vt *ValidatorTest) NewValidator(domains []string,
38 updated chan<- bool) func(string) bool {
39 return newValidatorImpl(domains, vt.authEmailFileName,
40 vt.done, func() {
41 if vt.updateSeen == false {
42 updated <- true
43 vt.updateSeen = true
44 }
45 })
48func (vt *ValidatorTest) WriteEmails(t *testing.T, emails []string) {
49 f, err := os.OpenFile(vt.authEmailFileName, os.O_WRONLY, 0600)
50 if err != nil {
51 t.Fatalf("failed to open auth email file: %v", err)
52 }
54 if _, err := f.WriteString(strings.Join(emails, "\n")); err != nil {
55 t.Fatalf("failed to write emails to auth email file: %v", err)
56 }
58 if err := f.Close(); err != nil {
59 t.Fatalf("failed to close auth email file: %v", err)
60 }
63func TestValidatorOverwriteEmailListDirectly(t *testing.T) {
64 testCasesPreUpdate := []struct {
65 name string
66 email string
67 expectedAuthZ bool
68 }{
69 {
70 name: "FirstEmailInList",
71 email: "xyzzy@example.com",
72 expectedAuthZ: true,
73 },
74 {
75 name: "SecondEmailInList",
76 email: "plugh@example.com",
77 expectedAuthZ: true,
78 },
79 {
80 name: "EmailNotInListThatMatchesNoDomains",
81 email: "xyzzy.plugh@example.com",
82 expectedAuthZ: false,
83 },
84 }
85 testCasesPostUpdate := []struct {
86 name string
87 email string
88 expectedAuthZ bool
89 }{
90 {
91 name: "email removed from list",
92 email: "xyzzy@example.com",
93 expectedAuthZ: false,
94 },
95 {
96 name: "email retained in list",
97 email: "plugh@example.com",
98 expectedAuthZ: true,
99 },
100 {
101 name: "email added to list",
102 email: "xyzzy.plugh@example.com",
103 expectedAuthZ: true,
104 },
105 }
107 vt := NewValidatorTest(t)
108 defer vt.TearDown()
110 vt.WriteEmails(t, []string{
111 "xyzzy@example.com",
112 "plugh@example.com",
113 })
114 updated := make(chan bool)
115 validator := vt.NewValidator([]string(nil), updated)
117 for _, tc := range testCasesPreUpdate {
118 t.Run(tc.name, func(t *testing.T) {
119 g := NewWithT(t)
120 authorized := validator(tc.email)
121 g.Expect(authorized).To(Equal(tc.expectedAuthZ))
122 })
123 }
125 vt.WriteEmails(t, []string{
126 "xyzzy.plugh@example.com",
127 "plugh@example.com",
128 })
129 <-updated
131 for _, tc := range testCasesPostUpdate {
132 t.Run(tc.name, func(t *testing.T) {
133 g := NewWithT(t)
134 authorized := validator(tc.email)
135 g.Expect(authorized).To(Equal(tc.expectedAuthZ))
136 })
137 }
140func TestValidatorCases(t *testing.T) {
141 testCases := []struct {
142 name string
143 allowedEmails []string
144 allowedDomains []string
145 email string
146 expectedAuthZ bool
147 }{
148 {
149 name: "EmailNotInCorrect1stSubDomainsNotInEmails",
150 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
151 allowedDomains: []string{".example0.com", ".example1.com"},
152 email: "foo.bar@example0.com",
153 expectedAuthZ: false,
154 },
155 {
156 name: "EmailNotInCorrect1stSubDomainsNotInEmailsWildcard",
157 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
158 allowedDomains: []string{"*.example0.com", "*.example1.com"},
159 email: "foo.bar@example0.com",
160 expectedAuthZ: false,
161 },
162 {
163 name: "EmailInFirstDomain",
164 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
165 allowedDomains: []string{".example0.com", ".example1.com"},
166 email: "foo@bar.example0.com",
167 expectedAuthZ: true,
168 },
169 {
170 name: "EmailInFirstDomainWildcard",
171 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
172 allowedDomains: []string{"*.example0.com", "*.example1.com"},
173 email: "foo@bar.example0.com",
174 expectedAuthZ: true,
175 },
176 {
177 name: "EmailNotInCorrect2ndSubDomainsNotInEmails",
178 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
179 allowedDomains: []string{".example0.com", ".example1.com"},
180 email: "baz.quux@example1.com",
181 expectedAuthZ: false,
182 },
183 {
184 name: "EmailInSecondDomain",
185 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
186 allowedDomains: []string{".example0.com", ".example1.com"},
187 email: "baz@quux.example1.com",
188 expectedAuthZ: true,
189 },
190 {
191 name: "EmailInSecondDomainWildcard",
192 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
193 allowedDomains: []string{"*.example0.com", "*.example1.com"},
194 email: "baz@quux.example1.com",
195 expectedAuthZ: true,
196 },
197 {
198 name: "EmailInFirstEmailList",
199 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
200 allowedDomains: []string{".example0.com", ".example1.com"},
201 email: "xyzzy@example.com",
202 expectedAuthZ: true,
203 },
204 {
205 name: "EmailInFirstEmailListWildcard",
206 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
207 allowedDomains: []string{"*.example0.com", "*.example1.com"},
208 email: "xyzzy@example.com",
209 expectedAuthZ: true,
210 },
211 {
212 name: "EmailNotInDomainsNotInEmails",
213 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
214 allowedDomains: []string{".example0.com", ".example1.com"},
215 email: "xyzzy.plugh@example.com",
216 expectedAuthZ: false,
217 },
218 {
219 name: "EmailInLastEmailList",
220 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
221 allowedDomains: []string{".example0.com", ".example1.com"},
222 email: "plugh@example.com",
223 expectedAuthZ: true,
224 },
225 {
226 name: "EmailIn1stSubdomain",
227 allowedEmails: nil,
228 allowedDomains: []string{"us.example.com", "de.example.com", "example.com"},
229 email: "xyzzy@us.example.com",
230 expectedAuthZ: true,
231 },
232 {
233 name: "EmailIn2ndSubdomain",
234 allowedEmails: nil,
235 allowedDomains: []string{"us.example.com", "de.example.com", "example.com"},
236 email: "xyzzy@de.example.com",
237 expectedAuthZ: true,
238 },
239 {
240 name: "EmailNotInAnySubdomain",
241 allowedEmails: nil,
242 allowedDomains: []string{"us.example.com", "de.example.com", "example.com"},
243 email: "global@au.example.com",
244 expectedAuthZ: false,
245 },
246 {
247 name: "EmailInLastSubdomain",
248 allowedEmails: nil,
249 allowedDomains: []string{"us.example.com", "de.example.com", "example.com"},
250 email: "xyzzy@example.com",
251 expectedAuthZ: true,
252 },
253 {
254 name: "EmailDomainNotCompletelyMatch",
255 allowedEmails: nil,
256 allowedDomains: []string{".example.com", ".example1.com"},
257 email: "something@fooexample.com",
258 expectedAuthZ: false,
259 },
260 {
261 name: "HackerExtraDomainPrefix1",
262 allowedEmails: nil,
263 allowedDomains: []string{".mycompany.com"},
264 email: "something@evilhackmycompany.com",
265 expectedAuthZ: false,
266 },
267 {
268 name: "HackerExtraDomainPrefix2",
269 allowedEmails: nil,
270 allowedDomains: []string{".mycompany.com"},
271 email: "something@ext.evilhackmycompany.com",
272 expectedAuthZ: false,
273 },
274 {
275 name: "EmptyDomainAndEmailList",
276 allowedEmails: []string(nil),
277 allowedDomains: []string(nil),
278 email: "foo.bar@example.com",
279 expectedAuthZ: false,
280 },
281 {
282 name: "EmailMatchWithAllowedEmails",
283 email: "foo.bar@example.com",
284 allowedEmails: []string{"foo.bar@example.com"},
285 allowedDomains: []string{"example.com"},
286 expectedAuthZ: true,
287 },
288 {
289 name: "EmailFromSameDomainButNotInList",
290 email: "baz.quux@example.com",
291 allowedEmails: []string{"foo.bar@example.com"},
292 allowedDomains: []string(nil),
293 expectedAuthZ: false,
294 },
295 {
296 name: "EmailMatchOnDomain",
297 email: "foo.bar@example.com",
298 allowedEmails: []string(nil),
299 allowedDomains: []string{"example.com"},
300 expectedAuthZ: true,
301 },
302 {
303 name: "EmailMatchOnDomain2",
304 email: "baz.quux@example.com",
305 allowedEmails: []string(nil),
306 allowedDomains: []string{"example.com"},
307 expectedAuthZ: true,
308 },
309 {
310 name: "EmailFromFirstDomainShouldValidate",
311 email: "foo.bar@example0.com",
312 allowedEmails: []string{"Foo.Bar@Example.Com"},
313 allowedDomains: []string{"example0.com", "example1.com"},
314 expectedAuthZ: true,
315 },
316 {
317 name: "EmailFromSecondDomainShouldValidate",
318 email: "baz.quux@example1.com",
319 allowedEmails: []string{"Foo.Bar@Example.Com"},
320 allowedDomains: []string{"example0.com", "example1.com"},
321 expectedAuthZ: true,
322 },
323 {
324 name: "FirstEmailInListShouldValidate",
325 email: "xyzzy@example.com",
326 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
327 allowedDomains: []string{"example0.com", "example1.com"},
328 expectedAuthZ: true,
329 },
330 {
331 name: "SecondEmailInListShouldValidate",
332 email: "plugh@example.com",
333 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
334 allowedDomains: []string{"example0.com", "example1.com"},
335 expectedAuthZ: true,
336 },
337 {
338 name: "EmailNotInListThatMatchesNoDomains ",
339 email: "xyzzy.plugh@example.com",
340 allowedEmails: []string{"xyzzy@example.com", "plugh@example.com"},
341 allowedDomains: []string{"example0.com", "example1.com"},
342 expectedAuthZ: false,
343 },
344 {
345 name: "LoadedEmailAddressesAreNotLowerCased",
346 email: "foo.bar@example.com",
347 allowedEmails: []string{"Foo.Bar@Example.Com"},
348 allowedDomains: []string{"Frobozz.Com"},
349 expectedAuthZ: true,
350 },
351 {
352 name: "ValidatedEmailAddressesAreNotLowerCased",
353 email: "Foo.Bar@Example.Com",
354 allowedEmails: []string{"Foo.Bar@Example.Com"},
355 allowedDomains: []string{"Frobozz.Com"},
356 expectedAuthZ: true,
357 },
358 {
359 name: "LoadedDomainsAreNotLowerCased",
360 email: "foo.bar@frobozz.com",
361 allowedEmails: []string{"Foo.Bar@Example.Com"},
362 allowedDomains: []string{"Frobozz.Com"},
363 expectedAuthZ: true,
364 },
365 {
366 name: "ValidatedDomainsAreNotLowerCased",
367 email: "foo.bar@Frobozz.Com",
368 allowedEmails: []string{"Foo.Bar@Example.Com"},
369 allowedDomains: []string{"Frobozz.Com"},
370 expectedAuthZ: true,
371 },
372 {
373 name: "IgnoreSpacesInAuthEmails",
374 email: "foo.bar@example.com",
375 allowedEmails: []string{" foo.bar@example.com "},
376 allowedDomains: []string(nil),
377 expectedAuthZ: true,
378 },
379 {
380 name: "IgnorePrefixSpacesInAuthEmails",
381 email: "foo.bar@example.com",
382 allowedEmails: []string{" foo.bar@example.com"},
383 allowedDomains: []string(nil),
384 expectedAuthZ: true,
385 },
386 {
387 name: "CheckForEqualityNotSuffix",
388 email: "foo@evilcompany.com",
389 allowedEmails: []string(nil),
390 allowedDomains: []string{".company.com"},
391 expectedAuthZ: false,
392 },
393 {
394 name: "CheckForEqualityNotSuffix2",
395 email: "foo@evilcompany.com",
396 allowedEmails: []string(nil),
397 allowedDomains: []string{"company.com"},
398 expectedAuthZ: false,
399 },
400 {
401 name: "CheckForEqualityNotSuffixWildcard",
402 email: "foo@evilcompany.com",
403 allowedEmails: []string(nil),
404 allowedDomains: []string{"*.company.com"},
405 expectedAuthZ: false,
406 },
407 {
408 name: "CheckThatTwoAtSignsIsInvalid",
409 email: "attacker@evil.com@company.com",
410 allowedEmails: []string(nil),
411 allowedDomains: []string{"company.com"},
412 expectedAuthZ: false,
413 },
414 {
415 name: "CheckThatTwoAtSignsIsInvalidEvenWithDotPrefix",
416 email: "attacker@evil.com@company.com",
417 allowedEmails: []string(nil),
418 allowedDomains: []string{".company.com"},
419 expectedAuthZ: false,
420 },
421 {
422 name: "CheckThatTwoAtSignsIsInvalidEvenWithWildcardPrefix",
423 email: "attacker@evil.com@foo.company.com",
424 allowedEmails: []string(nil),
425 allowedDomains: []string{"*.company.com"},
426 expectedAuthZ: false,
427 },
428 }
430 for _, tc := range testCases {
431 t.Run(tc.name, func(t *testing.T) {
432 vt := NewValidatorTest(t)
433 defer vt.TearDown()
435 g := NewWithT(t)
436 vt.WriteEmails(t, tc.allowedEmails)
437 validator := vt.NewValidator(tc.allowedDomains, nil)
438 authorized := validator(tc.email)
439 g.Expect(authorized).To(Equal(tc.expectedAuthZ))
440 })
441 }