github.com/clerkinc/clerk-sdk-go@v1.49.1/clerk/middleware_test.go (about) 1 package clerk 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "reflect" 8 "testing" 9 "time" 10 11 "github.com/go-jose/go-jose/v3" 12 "github.com/go-jose/go-jose/v3/jwt" 13 ) 14 15 func TestWithSession_addSessionToContext(t *testing.T) { 16 apiToken := "apiToken" 17 sessionId := "someSessionId" 18 sessionToken := "someSessionToken" 19 20 client, mux, serverUrl, teardown := setup(apiToken) 21 defer teardown() 22 23 expectedResponse := dummySessionJson 24 25 mux.HandleFunc("/sessions/"+sessionId+"/verify", func(w http.ResponseWriter, req *http.Request) { 26 fmt.Fprint(w, expectedResponse) 27 }) 28 29 dummyHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 30 // this handler should be called after the middleware has added the `ActiveSession` 31 activeSession := r.Context().Value(ActiveSession) 32 resp, _ := json.Marshal(activeSession) 33 fmt.Fprint(w, string(resp)) 34 }) 35 36 mux.Handle("/session", WithSession(client)(dummyHandler)) 37 38 request := setupRequest(&sessionId, &sessionToken) 39 request.URL.Host = serverUrl.Host 40 request.URL.Path = "/v1/session" 41 42 var got Session 43 _, _ = client.Do(request, &got) 44 45 var want Session 46 _ = json.Unmarshal([]byte(expectedResponse), &want) 47 48 if !reflect.DeepEqual(got, want) { 49 t.Errorf("Response = %v, want %v", got, want) 50 } 51 } 52 53 func TestWithSession_returnsErrorIfVerificationFails(t *testing.T) { 54 apiToken := "apiToken" 55 sessionId := "someSessionId" 56 sessionToken := "someSessionToken" 57 58 client, mux, serverUrl, teardown := setup(apiToken) 59 defer teardown() 60 61 mux.HandleFunc("/sessions/"+sessionId+"/verify", func(w http.ResponseWriter, req *http.Request) { 62 // return error 63 w.WriteHeader(400) 64 }) 65 66 dummyHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 67 // this handler should be called after the middleware has added the `ActiveSession` 68 t.Errorf("This should never be called!") 69 }) 70 71 mux.Handle("/session", WithSession(client)(dummyHandler)) 72 73 request := setupRequest(&sessionId, &sessionToken) 74 request.URL.Host = serverUrl.Host 75 request.URL.Path = "/v1/session" 76 77 resp, _ := client.Do(request, nil) 78 79 if resp.StatusCode != http.StatusBadRequest { 80 t.Errorf("Was expecting 400 error code, found %v instead", resp.StatusCode) 81 } 82 } 83 84 func TestWithSession_addSessionClaimsToContext_Header(t *testing.T) { 85 c, mux, serverUrl, teardown := setup("apiToken") 86 defer teardown() 87 88 expectedClaims := dummySessionClaims 89 90 token, pubKey := testGenerateTokenJWT(t, expectedClaims, "kid") 91 92 client := c.(*client) 93 client.jwksCache.set(testBuildJWKS(t, pubKey, jose.RS256, "kid")) 94 95 dummyHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 96 // this handler should be called after the middleware has added the `ActiveClaims` 97 claims := r.Context().Value(ActiveSessionClaims) 98 _ = json.NewEncoder(w).Encode(claims) 99 }) 100 101 mux.Handle("/claims", WithSession(c)(dummyHandler)) 102 103 req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/claims", serverUrl), nil) 104 req.Header.Set("Authorization", token) 105 106 resp, err := http.DefaultClient.Do(req) 107 if err != nil { 108 t.Fatal(err) 109 } 110 111 defer resp.Body.Close() 112 113 var got SessionClaims 114 _ = json.NewDecoder(resp.Body).Decode(&got) 115 116 if !reflect.DeepEqual(got, expectedClaims) { 117 t.Errorf("Response = %v, want %v", got, expectedClaims) 118 } 119 } 120 121 func TestWithSession_addSessionClaimsToContext_Cookie(t *testing.T) { 122 c, mux, serverUrl, teardown := setup("apiToken") 123 defer teardown() 124 125 expectedClaims := dummySessionClaims 126 127 token, pubKey := testGenerateTokenJWT(t, expectedClaims, "kid") 128 129 client := c.(*client) 130 client.jwksCache.set(testBuildJWKS(t, pubKey, jose.RS256, "kid")) 131 132 dummyHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 133 // this handler should be called after the middleware has added the `ActiveClaims` 134 activeClaims := r.Context().Value(ActiveSessionClaims) 135 _ = json.NewEncoder(w).Encode(activeClaims) 136 }) 137 138 mux.Handle("/claims", WithSession(c)(dummyHandler)) 139 140 req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/claims", serverUrl), nil) 141 req.AddCookie(&http.Cookie{ 142 Name: "__session", 143 Value: token, 144 Secure: true, 145 HttpOnly: true, 146 }) 147 148 resp, err := http.DefaultClient.Do(req) 149 if err != nil { 150 t.Fatal(err) 151 } 152 153 defer resp.Body.Close() 154 155 var got SessionClaims 156 _ = json.NewDecoder(resp.Body).Decode(&got) 157 158 if !reflect.DeepEqual(got, expectedClaims) { 159 t.Errorf("Response = %v, want %v", got, expectedClaims) 160 } 161 } 162 163 func TestWithSession_returnsErrorIfTokenVerificationFails(t *testing.T) { 164 c, mux, serverUrl, teardown := setup("apiToken") 165 defer teardown() 166 167 expectedClaims := dummySessionClaims 168 expectedClaims.Expiry = jwt.NewNumericDate(time.Now().Add(time.Second * -1)) 169 170 token, pubKey := testGenerateTokenJWT(t, expectedClaims, "kid") 171 172 client := c.(*client) 173 client.jwksCache.set(testBuildJWKS(t, pubKey, jose.RS256, "kid")) 174 175 dummyHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 176 // this handler should be called after the middleware has added the `ActiveClaims` 177 activeClaims := r.Context().Value(ActiveSessionClaims) 178 _ = json.NewEncoder(w).Encode(activeClaims) 179 }) 180 181 mux.Handle("/claims", WithSession(c)(dummyHandler)) 182 183 req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/claims", serverUrl), nil) 184 req.Header.Set("Authorization", token) 185 186 resp, _ := http.DefaultClient.Do(req) 187 188 if resp.StatusCode != http.StatusUnauthorized { 189 t.Errorf("Was expecting 401 error code, found %v instead", resp.StatusCode) 190 } 191 } 192 193 func TestWithSession_returnsErrorIfTokenMissing(t *testing.T) { 194 apiToken := "apiToken" 195 196 c, mux, serverUrl, teardown := setup(apiToken) 197 defer teardown() 198 199 dummyHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 200 // this handler should be called after the middleware has added the `ActiveSession` 201 t.Errorf("This should never be called!") 202 }) 203 204 mux.Handle("/claims", WithSession(c)(dummyHandler)) 205 206 req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/claims", serverUrl), nil) 207 208 resp, _ := http.DefaultClient.Do(req) 209 210 if resp.StatusCode != http.StatusBadRequest { 211 t.Errorf("Was expecting 400 error code, found %v instead", resp.StatusCode) 212 } 213 }