git.iko.soy/typeable/oauth2-proxy
on 8cbf921 help sign in
273 lines 6.6 kB history raw
1package validation
3import (
4 "strings"
5 "testing"
6 "time"
8 "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options"
9 . "github.com/onsi/gomega"
12func TestValidateCookie(t *testing.T) {
13 alphabet := "abcdefghijklmnopqrstuvwxyz"
15 validName := "_oauth2_proxy"
16 invalidName := "_oauth2;proxy" // Separater character not allowed
17 // 10 times the alphabet should be longer than 256 characters
18 longName := strings.Repeat(alphabet, 10)
19 validSecret := "secretthirtytwobytes+abcdefghijk"
20 invalidSecret := "abcdef" // 6 bytes is not a valid size
21 validBase64Secret := "c2VjcmV0dGhpcnR5dHdvYnl0ZXMrYWJjZGVmZ2hpams" // Base64 encoding of "secretthirtytwobytes+abcdefghijk"
22 invalidBase64Secret := "YWJjZGVmCg" // Base64 encoding of "abcdef"
23 emptyDomains := []string{}
24 domains := []string{
25 "a.localhost",
26 "ba.localhost",
27 "ca.localhost",
28 "cba.localhost",
29 "a.cba.localhost",
30 }
32 invalidNameMsg := "invalid cookie name: \"_oauth2;proxy\""
33 longNameMsg := "cookie name should be under 256 characters: cookie name is 260 characters"
34 missingSecretMsg := "missing setting: cookie-secret"
35 invalidSecretMsg := "cookie_secret must be 16, 24, or 32 bytes to create an AES cipher, but is 6 bytes"
36 invalidBase64SecretMsg := "cookie_secret must be 16, 24, or 32 bytes to create an AES cipher, but is 10 bytes"
37 refreshLongerThanExpireMsg := "cookie_refresh (\"1h0m0s\") must be less than cookie_expire (\"15m0s\")"
38 invalidSameSiteMsg := "cookie_samesite (\"invalid\") must be one of ['', 'lax', 'strict', 'none']"
40 testCases := []struct {
41 name string
42 cookie options.Cookie
43 errStrings []string
44 }{
45 {
46 name: "with valid configuration",
47 cookie: options.Cookie{
48 Name: validName,
49 Secret: validSecret,
50 Domains: domains,
51 Path: "",
52 Expire: time.Hour,
53 Refresh: 15 * time.Minute,
54 Secure: true,
55 HTTPOnly: false,
56 SameSite: "",
57 },
58 errStrings: []string{},
59 },
60 {
61 name: "with no cookie secret",
62 cookie: options.Cookie{
63 Name: validName,
64 Secret: "",
65 Domains: emptyDomains,
66 Path: "",
67 Expire: time.Hour,
68 Refresh: 15 * time.Minute,
69 Secure: true,
70 HTTPOnly: false,
71 SameSite: "",
72 },
73 errStrings: []string{
74 missingSecretMsg,
75 },
76 },
77 {
78 name: "with an invalid cookie secret",
79 cookie: options.Cookie{
80 Name: validName,
81 Secret: invalidSecret,
82 Domains: emptyDomains,
83 Path: "",
84 Expire: time.Hour,
85 Refresh: 15 * time.Minute,
86 Secure: true,
87 HTTPOnly: false,
88 SameSite: "",
89 },
90 errStrings: []string{
91 invalidSecretMsg,
92 },
93 },
94 {
95 name: "with a valid Base64 secret",
96 cookie: options.Cookie{
97 Name: validName,
98 Secret: validBase64Secret,
99 Domains: emptyDomains,
100 Path: "",
101 Expire: time.Hour,
102 Refresh: 15 * time.Minute,
103 Secure: true,
104 HTTPOnly: false,
105 SameSite: "",
106 },
107 errStrings: []string{},
108 },
109 {
110 name: "with an invalid Base64 secret",
111 cookie: options.Cookie{
112 Name: validName,
113 Secret: invalidBase64Secret,
114 Domains: emptyDomains,
115 Path: "",
116 Expire: time.Hour,
117 Refresh: 15 * time.Minute,
118 Secure: true,
119 HTTPOnly: false,
120 SameSite: "",
121 },
122 errStrings: []string{
123 invalidBase64SecretMsg,
124 },
125 },
126 {
127 name: "with an invalid name",
128 cookie: options.Cookie{
129 Name: invalidName,
130 Secret: validSecret,
131 Domains: emptyDomains,
132 Path: "",
133 Expire: time.Hour,
134 Refresh: 15 * time.Minute,
135 Secure: true,
136 HTTPOnly: false,
137 SameSite: "",
138 },
139 errStrings: []string{
140 invalidNameMsg,
141 },
142 },
143 {
144 name: "with a name that is too long",
145 cookie: options.Cookie{
146 Name: longName,
147 Secret: validSecret,
148 Domains: emptyDomains,
149 Path: "",
150 Expire: time.Hour,
151 Refresh: 15 * time.Minute,
152 Secure: true,
153 HTTPOnly: false,
154 SameSite: "",
155 },
156 errStrings: []string{
157 longNameMsg,
158 },
159 },
160 {
161 name: "with refresh longer than expire",
162 cookie: options.Cookie{
163 Name: validName,
164 Secret: validSecret,
165 Domains: emptyDomains,
166 Path: "",
167 Expire: 15 * time.Minute,
168 Refresh: time.Hour,
169 Secure: true,
170 HTTPOnly: false,
171 SameSite: "",
172 },
173 errStrings: []string{
174 refreshLongerThanExpireMsg,
175 },
176 },
177 {
178 name: "with samesite \"none\"",
179 cookie: options.Cookie{
180 Name: validName,
181 Secret: validSecret,
182 Domains: emptyDomains,
183 Path: "",
184 Expire: time.Hour,
185 Refresh: 15 * time.Minute,
186 Secure: true,
187 HTTPOnly: false,
188 SameSite: "none",
189 },
190 errStrings: []string{},
191 },
192 {
193 name: "with samesite \"lax\"",
194 cookie: options.Cookie{
195 Name: validName,
196 Secret: validSecret,
197 Domains: emptyDomains,
198 Path: "",
199 Expire: time.Hour,
200 Refresh: 15 * time.Minute,
201 Secure: true,
202 HTTPOnly: false,
203 SameSite: "none",
204 },
205 errStrings: []string{},
206 },
207 {
208 name: "with samesite \"strict\"",
209 cookie: options.Cookie{
210 Name: validName,
211 Secret: validSecret,
212 Domains: emptyDomains,
213 Path: "",
214 Expire: time.Hour,
215 Refresh: 15 * time.Minute,
216 Secure: true,
217 HTTPOnly: false,
218 SameSite: "none",
219 },
220 errStrings: []string{},
221 },
222 {
223 name: "with samesite \"invalid\"",
224 cookie: options.Cookie{
225 Name: validName,
226 Secret: validSecret,
227 Domains: emptyDomains,
228 Path: "",
229 Expire: time.Hour,
230 Refresh: 15 * time.Minute,
231 Secure: true,
232 HTTPOnly: false,
233 SameSite: "invalid",
234 },
235 errStrings: []string{
236 invalidSameSiteMsg,
237 },
238 },
239 {
240 name: "with a combination of configuration errors",
241 cookie: options.Cookie{
242 Name: invalidName,
243 Secret: invalidSecret,
244 Domains: domains,
245 Path: "",
246 Expire: 15 * time.Minute,
247 Refresh: time.Hour,
248 Secure: true,
249 HTTPOnly: false,
250 SameSite: "invalid",
251 },
252 errStrings: []string{
253 invalidNameMsg,
254 invalidSecretMsg,
255 refreshLongerThanExpireMsg,
256 invalidSameSiteMsg,
257 },
258 },
259 }
261 for _, tc := range testCases {
262 t.Run(tc.name, func(t *testing.T) {
263 errStrings := validateCookie(tc.cookie)
264 g := NewWithT(t)
266 g.Expect(errStrings).To(ConsistOf(tc.errStrings))
267 // Check domains were sorted to the right lengths
268 for i := 0; i < len(tc.cookie.Domains)-1; i++ {
269 g.Expect(len(tc.cookie.Domains[i])).To(BeNumerically(">=", len(tc.cookie.Domains[i+1])))
270 }
271 })
272 }