Skip to content
This repository was archived by the owner on Jan 24, 2019. It is now read-only.

Commit ade9502

Browse files
committed
Merge pull request #66 from 18F/enforce-cookie-secret
Catch more options errors at once; add test
2 parents 30e5b63 + d751bbe commit ade9502

2 files changed

Lines changed: 109 additions & 8 deletions

File tree

options.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package main
22

33
import (
4-
"errors"
54
"fmt"
65
"net/url"
76
"regexp"
7+
"strings"
88
"time"
99
)
1010

@@ -45,29 +45,33 @@ func NewOptions() *Options {
4545
}
4646

4747
func (o *Options) Validate() error {
48+
msgs := make([]string, 0)
4849
if len(o.Upstreams) < 1 {
49-
return errors.New("missing setting: upstream")
50+
msgs = append(msgs, "missing setting: upstream")
5051
}
5152
if o.CookieSecret == "" {
52-
errors.New("missing setting: cookie-secret")
53+
msgs = append(msgs, "missing setting: cookie-secret")
5354
}
5455
if o.ClientID == "" {
55-
return errors.New("missing setting: client-id")
56+
msgs = append(msgs, "missing setting: client-id")
5657
}
5758
if o.ClientSecret == "" {
58-
return errors.New("missing setting: client-secret")
59+
msgs = append(msgs, "missing setting: client-secret")
5960
}
6061

6162
redirectUrl, err := url.Parse(o.RedirectUrl)
6263
if err != nil {
63-
return fmt.Errorf("error parsing redirect-url=%q %s", o.RedirectUrl, err)
64+
msgs = append(msgs, fmt.Sprintf(
65+
"error parsing redirect-url=%q %s", o.RedirectUrl, err))
6466
}
6567
o.redirectUrl = redirectUrl
6668

6769
for _, u := range o.Upstreams {
6870
upstreamUrl, err := url.Parse(u)
6971
if err != nil {
70-
return fmt.Errorf("error parsing upstream=%q %s", upstreamUrl, err)
72+
msgs = append(msgs, fmt.Sprintf(
73+
"error parsing upstream=%q %s",
74+
upstreamUrl, err))
7175
}
7276
if upstreamUrl.Path == "" {
7377
upstreamUrl.Path = "/"
@@ -78,10 +82,15 @@ func (o *Options) Validate() error {
7882
for _, u := range o.SkipAuthRegex {
7983
CompiledRegex, err := regexp.Compile(u)
8084
if err != nil {
81-
return fmt.Errorf("error compiling regex=%q %s", u, err)
85+
msgs = append(msgs, fmt.Sprintf(
86+
"error compiling regex=%q %s", u, err))
8287
}
8388
o.CompiledRegex = append(o.CompiledRegex, CompiledRegex)
8489
}
8590

91+
if len(msgs) != 0 {
92+
return fmt.Errorf("Invalid configuration:\n %s",
93+
strings.Join(msgs, "\n "))
94+
}
8695
return nil
8796
}

options_test.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package main
2+
3+
import (
4+
"strings"
5+
"testing"
6+
"net/url"
7+
8+
"github.com/bmizerany/assert"
9+
)
10+
11+
func testOptions() (*Options) {
12+
o := NewOptions()
13+
o.Upstreams = append(o.Upstreams, "http://127.0.0.1:8080/")
14+
o.CookieSecret = "foobar"
15+
o.ClientID = "bazquux"
16+
o.ClientSecret = "xyzzyplugh"
17+
return o
18+
}
19+
20+
func errorMsg(msgs []string)(string) {
21+
result := make([]string, 0)
22+
result = append(result, "Invalid configuration:")
23+
result = append(result, msgs...)
24+
return strings.Join(result, "\n ")
25+
}
26+
27+
func TestNewOptions(t *testing.T) {
28+
o := NewOptions()
29+
err := o.Validate()
30+
assert.NotEqual(t, nil, err)
31+
32+
expected := errorMsg([]string{
33+
"missing setting: upstream",
34+
"missing setting: cookie-secret",
35+
"missing setting: client-id",
36+
"missing setting: client-secret"})
37+
assert.Equal(t, expected, err.Error())
38+
}
39+
40+
func TestInitializedOptions(t *testing.T) {
41+
o := testOptions()
42+
assert.Equal(t, nil, o.Validate())
43+
}
44+
45+
// Note that it's not worth testing nonparseable URLs, since url.Parse()
46+
// seems to parse damn near anything.
47+
func TestRedirectUrl(t *testing.T) {
48+
o := testOptions()
49+
o.RedirectUrl = "https://myhost.com/oauth2/callback"
50+
assert.Equal(t, nil, o.Validate())
51+
expected := &url.URL{
52+
Scheme: "https", Host: "myhost.com", Path: "/oauth2/callback"}
53+
assert.Equal(t, expected, o.redirectUrl)
54+
}
55+
56+
func TestProxyUrls(t *testing.T) {
57+
o := testOptions()
58+
o.Upstreams = append(o.Upstreams, "http://127.0.0.1:8081")
59+
assert.Equal(t, nil, o.Validate())
60+
expected := []*url.URL{
61+
&url.URL{Scheme: "http", Host: "127.0.0.1:8080", Path: "/"},
62+
// note the '/' was added
63+
&url.URL{Scheme: "http", Host: "127.0.0.1:8081", Path: "/"},
64+
}
65+
assert.Equal(t, expected, o.proxyUrls)
66+
}
67+
68+
func TestCompiledRegex(t *testing.T) {
69+
o := testOptions()
70+
regexps := []string{"/foo/.*", "/ba[rz]/quux"}
71+
o.SkipAuthRegex = regexps
72+
assert.Equal(t, nil, o.Validate())
73+
actual := make([]string, 0)
74+
for _, regex := range o.CompiledRegex {
75+
actual = append(actual, regex.String())
76+
}
77+
assert.Equal(t, regexps, actual)
78+
}
79+
80+
func TestCompiledRegexError(t *testing.T) {
81+
o := testOptions()
82+
o.SkipAuthRegex = []string{"(foobaz", "barquux)"}
83+
err := o.Validate()
84+
assert.NotEqual(t, nil, err)
85+
86+
expected := errorMsg([]string{
87+
"error compiling regex=\"(foobaz\" error parsing regexp: " +
88+
"missing closing ): `(foobaz`",
89+
"error compiling regex=\"barquux)\" error parsing regexp: " +
90+
"unexpected ): `barquux)`"})
91+
assert.Equal(t, expected, err.Error())
92+
}

0 commit comments

Comments
 (0)