1
2
3
4
5 package xsrftoken
6
7 import (
8 "encoding/base64"
9 "testing"
10 "time"
11 )
12
13 const (
14 key = "quay"
15 userID = "12345678"
16 actionID = "POST /form"
17 )
18
19 var (
20 now = time.Now()
21 oneMinuteFromNow = now.Add(1 * time.Minute)
22 )
23
24 func TestValidToken(t *testing.T) {
25 tok := generateTokenAtTime(key, userID, actionID, now)
26 if !validTokenAtTime(tok, key, userID, actionID, oneMinuteFromNow, Timeout) {
27 t.Error("One second later: Expected token to be valid")
28 }
29 if !validTokenAtTime(tok, key, userID, actionID, now.Add(Timeout-1*time.Nanosecond), Timeout) {
30 t.Error("Just before timeout: Expected token to be valid")
31 }
32 if !validTokenAtTime(tok, key, userID, actionID, now.Add(-1*time.Minute+1*time.Millisecond), Timeout) {
33 t.Error("One minute in the past: Expected token to be valid")
34 }
35 if !validTokenAtTime(tok, key, userID, actionID, oneMinuteFromNow, time.Hour) {
36 t.Error("One second later: Expected token to be valid")
37 }
38 if !validTokenAtTime(tok, key, userID, actionID, now.Add(time.Minute-1*time.Nanosecond), time.Minute) {
39 t.Error("Just before timeout: Expected token to be valid")
40 }
41 if !validTokenAtTime(tok, key, userID, actionID, now.Add(-1*time.Minute+1*time.Millisecond), time.Hour) {
42 t.Error("One minute in the past: Expected token to be valid")
43 }
44 }
45
46
47 func TestSeparatorReplacement(t *testing.T) {
48 separatorTests := []struct {
49 name string
50 token1 string
51 token2 string
52 }{
53 {
54 "Colon",
55 generateTokenAtTime("foo:bar", "baz", "wah", now),
56 generateTokenAtTime("foo", "bar:baz", "wah", now),
57 },
58 {
59 "Colon and Underscore",
60 generateTokenAtTime("key", ":foo:", "wah", now),
61 generateTokenAtTime("key", "_foo_", "wah", now),
62 },
63 {
64 "Colon and Double Colon",
65 generateTokenAtTime("key", ":foo:", "wah", now),
66 generateTokenAtTime("key", "::foo::", "wah", now),
67 },
68 }
69
70 for _, st := range separatorTests {
71 if st.token1 == st.token2 {
72 t.Errorf("%v: Expected generated tokens to be different", st.name)
73 }
74 }
75 }
76
77 func TestInvalidToken(t *testing.T) {
78 invalidTokenTests := []struct {
79 name, key, userID, actionID string
80 t time.Time
81 timeout time.Duration
82 }{
83 {"Bad key", "foobar", userID, actionID, oneMinuteFromNow, Timeout},
84 {"Bad userID", key, "foobar", actionID, oneMinuteFromNow, Timeout},
85 {"Bad actionID", key, userID, "foobar", oneMinuteFromNow, Timeout},
86 {"Expired", key, userID, actionID, now.Add(Timeout + 1*time.Millisecond), Timeout},
87 {"More than 1 minute from the future", key, userID, actionID, now.Add(-1*time.Nanosecond - 1*time.Minute), Timeout},
88 {"Expired with 1 minute timeout", key, userID, actionID, now.Add(time.Minute + 1*time.Millisecond), time.Minute},
89 }
90
91 tok := generateTokenAtTime(key, userID, actionID, now)
92 for _, itt := range invalidTokenTests {
93 if validTokenAtTime(tok, itt.key, itt.userID, itt.actionID, itt.t, itt.timeout) {
94 t.Errorf("%v: Expected token to be invalid", itt.name)
95 }
96 }
97 }
98
99
100
101 func TestValidateBadData(t *testing.T) {
102 badDataTests := []struct {
103 name, tok string
104 }{
105 {"Invalid Base64", "ASDab24(@)$*=="},
106 {"No delimiter", base64.URLEncoding.EncodeToString([]byte("foobar12345678"))},
107 {"Invalid time", base64.URLEncoding.EncodeToString([]byte("foobar:foobar"))},
108 {"Wrong length", "1234" + generateTokenAtTime(key, userID, actionID, now)},
109 }
110
111 for _, bdt := range badDataTests {
112 if validTokenAtTime(bdt.tok, key, userID, actionID, oneMinuteFromNow, Timeout) {
113 t.Errorf("%v: Expected token to be invalid", bdt.name)
114 }
115 }
116 }
117
View as plain text