git.iko.soy/typeable/oauth2-proxy
on v3.2.0 help sign in
typeable/oauth2-proxy/providers/session_state_test.go
317 lines 9.4 kB history raw
1package providers
3import (
4 "fmt"
5 "testing"
6 "time"
8 "github.com/pusher/oauth2_proxy/cookie"
9 "github.com/stretchr/testify/assert"
12const secret = "0123456789abcdefghijklmnopqrstuv"
13const altSecret = "0000000000abcdefghijklmnopqrstuv"
15func TestSessionStateSerialization(t *testing.T) {
16 c, err := cookie.NewCipher([]byte(secret))
17 assert.Equal(t, nil, err)
18 c2, err := cookie.NewCipher([]byte(altSecret))
19 assert.Equal(t, nil, err)
20 s := &SessionState{
21 Email: "user@domain.com",
22 AccessToken: "token1234",
23 IDToken: "rawtoken1234",
24 ExpiresOn: time.Now().Add(time.Duration(1) * time.Hour),
25 RefreshToken: "refresh4321",
26 }
27 encoded, err := s.EncodeSessionState(c)
28 assert.Equal(t, nil, err)
30 ss, err := DecodeSessionState(encoded, c)
31 t.Logf("%#v", ss)
32 assert.Equal(t, nil, err)
33 assert.Equal(t, "user", ss.User)
34 assert.Equal(t, s.Email, ss.Email)
35 assert.Equal(t, s.AccessToken, ss.AccessToken)
36 assert.Equal(t, s.IDToken, ss.IDToken)
37 assert.Equal(t, s.ExpiresOn.Unix(), ss.ExpiresOn.Unix())
38 assert.Equal(t, s.RefreshToken, ss.RefreshToken)
40 // ensure a different cipher can't decode properly (ie: it gets gibberish)
41 ss, err = DecodeSessionState(encoded, c2)
42 t.Logf("%#v", ss)
43 assert.Equal(t, nil, err)
44 assert.NotEqual(t, "user", ss.User)
45 assert.NotEqual(t, s.Email, ss.Email)
46 assert.Equal(t, s.ExpiresOn.Unix(), ss.ExpiresOn.Unix())
47 assert.NotEqual(t, s.AccessToken, ss.AccessToken)
48 assert.NotEqual(t, s.IDToken, ss.IDToken)
49 assert.NotEqual(t, s.RefreshToken, ss.RefreshToken)
52func TestSessionStateSerializationWithUser(t *testing.T) {
53 c, err := cookie.NewCipher([]byte(secret))
54 assert.Equal(t, nil, err)
55 c2, err := cookie.NewCipher([]byte(altSecret))
56 assert.Equal(t, nil, err)
57 s := &SessionState{
58 User: "just-user",
59 Email: "user@domain.com",
60 AccessToken: "token1234",
61 ExpiresOn: time.Now().Add(time.Duration(1) * time.Hour),
62 RefreshToken: "refresh4321",
63 }
64 encoded, err := s.EncodeSessionState(c)
65 assert.Equal(t, nil, err)
67 ss, err := DecodeSessionState(encoded, c)
68 t.Logf("%#v", ss)
69 assert.Equal(t, nil, err)
70 assert.Equal(t, s.User, ss.User)
71 assert.Equal(t, s.Email, ss.Email)
72 assert.Equal(t, s.AccessToken, ss.AccessToken)
73 assert.Equal(t, s.ExpiresOn.Unix(), ss.ExpiresOn.Unix())
74 assert.Equal(t, s.RefreshToken, ss.RefreshToken)
76 // ensure a different cipher can't decode properly (ie: it gets gibberish)
77 ss, err = DecodeSessionState(encoded, c2)
78 t.Logf("%#v", ss)
79 assert.Equal(t, nil, err)
80 assert.NotEqual(t, s.User, ss.User)
81 assert.NotEqual(t, s.Email, ss.Email)
82 assert.Equal(t, s.ExpiresOn.Unix(), ss.ExpiresOn.Unix())
83 assert.NotEqual(t, s.AccessToken, ss.AccessToken)
84 assert.NotEqual(t, s.RefreshToken, ss.RefreshToken)
87func TestSessionStateSerializationNoCipher(t *testing.T) {
88 s := &SessionState{
89 Email: "user@domain.com",
90 AccessToken: "token1234",
91 ExpiresOn: time.Now().Add(time.Duration(1) * time.Hour),
92 RefreshToken: "refresh4321",
93 }
94 encoded, err := s.EncodeSessionState(nil)
95 assert.Equal(t, nil, err)
97 // only email should have been serialized
98 ss, err := DecodeSessionState(encoded, nil)
99 assert.Equal(t, nil, err)
100 assert.Equal(t, "user", ss.User)
101 assert.Equal(t, s.Email, ss.Email)
102 assert.Equal(t, "", ss.AccessToken)
103 assert.Equal(t, "", ss.RefreshToken)
106func TestSessionStateSerializationNoCipherWithUser(t *testing.T) {
107 s := &SessionState{
108 User: "just-user",
109 Email: "user@domain.com",
110 AccessToken: "token1234",
111 ExpiresOn: time.Now().Add(time.Duration(1) * time.Hour),
112 RefreshToken: "refresh4321",
113 }
114 encoded, err := s.EncodeSessionState(nil)
115 assert.Equal(t, nil, err)
117 // only email should have been serialized
118 ss, err := DecodeSessionState(encoded, nil)
119 assert.Equal(t, nil, err)
120 assert.Equal(t, s.User, ss.User)
121 assert.Equal(t, s.Email, ss.Email)
122 assert.Equal(t, "", ss.AccessToken)
123 assert.Equal(t, "", ss.RefreshToken)
126func TestExpired(t *testing.T) {
127 s := &SessionState{ExpiresOn: time.Now().Add(time.Duration(-1) * time.Minute)}
128 assert.Equal(t, true, s.IsExpired())
130 s = &SessionState{ExpiresOn: time.Now().Add(time.Duration(1) * time.Minute)}
131 assert.Equal(t, false, s.IsExpired())
133 s = &SessionState{}
134 assert.Equal(t, false, s.IsExpired())
137type testCase struct {
138 SessionState
139 Encoded string
140 Cipher *cookie.Cipher
141 Error bool
144// TestEncodeSessionState tests EncodeSessionState with the test vector
145//
146// Currently only tests without cipher here because we have no way to mock
147// the random generator used in EncodeSessionState.
148func TestEncodeSessionState(t *testing.T) {
149 e := time.Now().Add(time.Duration(1) * time.Hour)
151 testCases := []testCase{
152 {
153 SessionState: SessionState{
154 Email: "user@domain.com",
155 User: "just-user",
156 },
157 Encoded: `{"Email":"user@domain.com","User":"just-user"}`,
158 },
159 {
160 SessionState: SessionState{
161 Email: "user@domain.com",
162 User: "just-user",
163 AccessToken: "token1234",
164 IDToken: "rawtoken1234",
165 ExpiresOn: e,
166 RefreshToken: "refresh4321",
167 },
168 Encoded: `{"Email":"user@domain.com","User":"just-user"}`,
169 },
170 }
172 for i, tc := range testCases {
173 encoded, err := tc.EncodeSessionState(tc.Cipher)
174 t.Logf("i:%d Encoded:%#v SessionState:%#v Error:%#v", i, encoded, tc.SessionState, err)
175 if tc.Error {
176 assert.Error(t, err)
177 assert.Empty(t, encoded)
178 continue
179 }
180 assert.NoError(t, err)
181 assert.JSONEq(t, tc.Encoded, encoded)
182 }
185// TestDecodeSessionState tests DecodeSessionState with the test vector
186func TestDecodeSessionState(t *testing.T) {
187 e := time.Now().Add(time.Duration(1) * time.Hour)
188 eJSON, _ := e.MarshalJSON()
189 eString := string(eJSON)
190 eUnix := e.Unix()
192 c, err := cookie.NewCipher([]byte(secret))
193 assert.NoError(t, err)
195 testCases := []testCase{
196 {
197 SessionState: SessionState{
198 Email: "user@domain.com",
199 User: "just-user",
200 },
201 Encoded: `{"Email":"user@domain.com","User":"just-user"}`,
202 },
203 {
204 SessionState: SessionState{
205 Email: "user@domain.com",
206 User: "user",
207 },
208 Encoded: `{"Email":"user@domain.com"}`,
209 },
210 {
211 SessionState: SessionState{
212 User: "just-user",
213 },
214 Encoded: `{"User":"just-user"}`,
215 },
216 {
217 SessionState: SessionState{
218 Email: "user@domain.com",
219 User: "just-user",
220 },
221 Encoded: fmt.Sprintf(`{"Email":"user@domain.com","User":"just-user","AccessToken":"I6s+ml+/MldBMgHIiC35BTKTh57skGX24w==","IDToken":"xojNdyyjB1HgYWh6XMtXY/Ph5eCVxa1cNsklJw==","RefreshToken":"qEX0x6RmASxo4dhlBG6YuRs9Syn/e9sHu/+K","ExpiresOn":%s}`, eString),
222 },
223 {
224 SessionState: SessionState{
225 Email: "user@domain.com",
226 User: "just-user",
227 AccessToken: "token1234",
228 IDToken: "rawtoken1234",
229 ExpiresOn: e,
230 RefreshToken: "refresh4321",
231 },
232 Encoded: fmt.Sprintf(`{"Email":"FsKKYrTWZWrxSOAqA/fTNAUZS5QWCqOBjuAbBlbVOw==","User":"rT6JP3dxQhxUhkWrrd7yt6c1mDVyQCVVxw==","AccessToken":"I6s+ml+/MldBMgHIiC35BTKTh57skGX24w==","IDToken":"xojNdyyjB1HgYWh6XMtXY/Ph5eCVxa1cNsklJw==","RefreshToken":"qEX0x6RmASxo4dhlBG6YuRs9Syn/e9sHu/+K","ExpiresOn":%s}`, eString),
233 Cipher: c,
234 },
235 {
236 SessionState: SessionState{
237 Email: "user@domain.com",
238 User: "just-user",
239 },
240 Encoded: `{"Email":"EGTllJcOFC16b7LBYzLekaHAC5SMMSPdyUrg8hd25g==","User":"rT6JP3dxQhxUhkWrrd7yt6c1mDVyQCVVxw=="}`,
241 Cipher: c,
242 },
243 {
244 Encoded: `{"Email":"user@domain.com","User":"just-user","AccessToken":"X"}`,
245 Cipher: c,
246 Error: true,
247 },
248 {
249 Encoded: `{"Email":"user@domain.com","User":"just-user","IDToken":"XXXX"}`,
250 Cipher: c,
251 Error: true,
252 },
253 {
254 SessionState: SessionState{
255 User: "just-user",
256 Email: "user@domain.com",
257 },
258 Encoded: "email:user@domain.com user:just-user",
259 },
260 {
261 Encoded: "email:user@domain.com user:just-user||||",
262 Error: true,
263 },
264 {
265 Encoded: "email:user@domain.com user:just-user",
266 Cipher: c,
267 Error: true,
268 },
269 {
270 Encoded: "email:user@domain.com user:just-user|||99999999999999999999|",
271 Cipher: c,
272 Error: true,
273 },
274 {
275 SessionState: SessionState{
276 Email: "user@domain.com",
277 User: "just-user",
278 AccessToken: "token1234",
279 ExpiresOn: e,
280 RefreshToken: "refresh4321",
281 },
282 Encoded: fmt.Sprintf("email:user@domain.com user:just-user|I6s+ml+/MldBMgHIiC35BTKTh57skGX24w==|%d|qEX0x6RmASxo4dhlBG6YuRs9Syn/e9sHu/+K", eUnix),
283 Cipher: c,
284 },
285 {
286 SessionState: SessionState{
287 Email: "user@domain.com",
288 User: "just-user",
289 AccessToken: "token1234",
290 IDToken: "rawtoken1234",
291 ExpiresOn: e,
292 RefreshToken: "refresh4321",
293 },
294 Encoded: fmt.Sprintf("email:user@domain.com user:just-user|I6s+ml+/MldBMgHIiC35BTKTh57skGX24w==|xojNdyyjB1HgYWh6XMtXY/Ph5eCVxa1cNsklJw==|%d|qEX0x6RmASxo4dhlBG6YuRs9Syn/e9sHu/+K", eUnix),
295 Cipher: c,
296 },
297 }
299 for i, tc := range testCases {
300 ss, err := DecodeSessionState(tc.Encoded, tc.Cipher)
301 t.Logf("i:%d Encoded:%#v SessionState:%#v Error:%#v", i, tc.Encoded, ss, err)
302 if tc.Error {
303 assert.Error(t, err)
304 assert.Nil(t, ss)
305 continue
306 }
307 assert.NoError(t, err)
308 if assert.NotNil(t, ss) {
309 assert.Equal(t, tc.User, ss.User)
310 assert.Equal(t, tc.Email, ss.Email)
311 assert.Equal(t, tc.AccessToken, ss.AccessToken)
312 assert.Equal(t, tc.RefreshToken, ss.RefreshToken)
313 assert.Equal(t, tc.IDToken, ss.IDToken)
314 assert.Equal(t, tc.ExpiresOn.Unix(), ss.ExpiresOn.Unix())
315 }
316 }