github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/appengine/login/googlesignin/jwt-go/jwt_test.go (about) 1 package jwt_test 2 3 import ( 4 "fmt" 5 "github.com/dgrijalva/jwt-go" 6 "io/ioutil" 7 "net/http" 8 "reflect" 9 "testing" 10 "time" 11 ) 12 13 var ( 14 jwtTestDefaultKey []byte 15 defaultKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return jwtTestDefaultKey, nil } 16 emptyKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, nil } 17 errorKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, fmt.Errorf("error loading key") } 18 nilKeyFunc jwt.Keyfunc = nil 19 ) 20 21 var jwtTestData = []struct { 22 name string 23 tokenString string 24 keyfunc jwt.Keyfunc 25 claims map[string]interface{} 26 valid bool 27 errors uint32 28 }{ 29 { 30 "basic", 31 "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg", 32 defaultKeyFunc, 33 map[string]interface{}{"foo": "bar"}, 34 true, 35 0, 36 }, 37 { 38 "basic expired", 39 "", // autogen 40 defaultKeyFunc, 41 map[string]interface{}{"foo": "bar", "exp": float64(time.Now().Unix() - 100)}, 42 false, 43 jwt.ValidationErrorExpired, 44 }, 45 { 46 "basic nbf", 47 "", // autogen 48 defaultKeyFunc, 49 map[string]interface{}{"foo": "bar", "nbf": float64(time.Now().Unix() + 100)}, 50 false, 51 jwt.ValidationErrorNotValidYet, 52 }, 53 { 54 "expired and nbf", 55 "", // autogen 56 defaultKeyFunc, 57 map[string]interface{}{"foo": "bar", "nbf": float64(time.Now().Unix() + 100), "exp": float64(time.Now().Unix() - 100)}, 58 false, 59 jwt.ValidationErrorNotValidYet | jwt.ValidationErrorExpired, 60 }, 61 { 62 "basic invalid", 63 "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg", 64 defaultKeyFunc, 65 map[string]interface{}{"foo": "bar"}, 66 false, 67 jwt.ValidationErrorSignatureInvalid, 68 }, 69 { 70 "basic nokeyfunc", 71 "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg", 72 nilKeyFunc, 73 map[string]interface{}{"foo": "bar"}, 74 false, 75 jwt.ValidationErrorUnverifiable, 76 }, 77 { 78 "basic nokey", 79 "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg", 80 emptyKeyFunc, 81 map[string]interface{}{"foo": "bar"}, 82 false, 83 jwt.ValidationErrorSignatureInvalid, 84 }, 85 { 86 "basic errorkey", 87 "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg", 88 errorKeyFunc, 89 map[string]interface{}{"foo": "bar"}, 90 false, 91 jwt.ValidationErrorUnverifiable, 92 }, 93 } 94 95 func init() { 96 var e error 97 if jwtTestDefaultKey, e = ioutil.ReadFile("test/sample_key.pub"); e != nil { 98 panic(e) 99 } 100 } 101 102 func makeSample(c map[string]interface{}) string { 103 key, e := ioutil.ReadFile("test/sample_key") 104 if e != nil { 105 panic(e.Error()) 106 } 107 108 token := jwt.New(jwt.SigningMethodRS256) 109 token.Claims = c 110 s, e := token.SignedString(key) 111 112 if e != nil { 113 panic(e.Error()) 114 } 115 116 return s 117 } 118 119 func TestJWT(t *testing.T) { 120 for _, data := range jwtTestData { 121 if data.tokenString == "" { 122 data.tokenString = makeSample(data.claims) 123 } 124 token, err := jwt.Parse(data.tokenString, data.keyfunc) 125 126 if !reflect.DeepEqual(data.claims, token.Claims) { 127 t.Errorf("[%v] Claims mismatch. Expecting: %v Got: %v", data.name, data.claims, token.Claims) 128 } 129 if data.valid && err != nil { 130 t.Errorf("[%v] Error while verifying token: %T:%v", data.name, err, err) 131 } 132 if !data.valid && err == nil { 133 t.Errorf("[%v] Invalid token passed validation", data.name) 134 } 135 if data.errors != 0 { 136 if err == nil { 137 t.Errorf("[%v] Expecting error. Didn't get one.", data.name) 138 } else { 139 // compare the bitfield part of the error 140 if err.(*jwt.ValidationError).Errors != data.errors { 141 t.Errorf("[%v] Errors don't match expectation", data.name) 142 } 143 144 } 145 } 146 } 147 } 148 149 func TestParseRequest(t *testing.T) { 150 // Bearer token request 151 for _, data := range jwtTestData { 152 if data.tokenString == "" { 153 data.tokenString = makeSample(data.claims) 154 } 155 156 r, _ := http.NewRequest("GET", "/", nil) 157 r.Header.Set("Authorization", fmt.Sprintf("Bearer %v", data.tokenString)) 158 token, err := jwt.ParseFromRequest(r, data.keyfunc) 159 160 if token == nil { 161 t.Errorf("[%v] Token was not found: %v", data.name, err) 162 continue 163 } 164 if !reflect.DeepEqual(data.claims, token.Claims) { 165 t.Errorf("[%v] Claims mismatch. Expecting: %v Got: %v", data.name, data.claims, token.Claims) 166 } 167 if data.valid && err != nil { 168 t.Errorf("[%v] Error while verifying token: %v", data.name, err) 169 } 170 if !data.valid && err == nil { 171 t.Errorf("[%v] Invalid token passed validation", data.name) 172 } 173 } 174 } 175 176 // Helper method for benchmarking various methods 177 func benchmarkSigning(b *testing.B, method jwt.SigningMethod, key interface{}) { 178 t := jwt.New(method) 179 b.RunParallel(func(pb *testing.PB) { 180 for pb.Next() { 181 if _, err := t.SignedString(key); err != nil { 182 b.Fatal(err) 183 } 184 } 185 }) 186 187 }