/test/clauth/test/middleware.clj

https://github.com/pelle/clauth · Clojure · 297 lines · 252 code · 38 blank · 7 comment · 54 complexity · df5d1182d7149a02244e05d11a935e38 MD5 · raw file

  1. (ns clauth.test.middleware
  2. (:require [clojure.test :refer :all]
  3. [clauth.middleware :as base]))
  4. (deftest extract-requested-uri
  5. (is (= "/"
  6. (base/requested-uri {})))
  7. (is (= "/hello"
  8. (base/requested-uri {:uri "/hello"})))
  9. (is (= "/hello?one=1&two=2"
  10. (base/requested-uri {:uri "/hello" :query-string "one=1&two=2"}))))
  11. (deftest assoc-session-value
  12. (is (= {:session {:hello 1}}
  13. (base/assoc-session {} {} :hello 1)))
  14. (is (= {:session {:hello 1 :old 2}}
  15. (base/assoc-session {} {:session {:old 2}} :hello 1)))
  16. (is (= {:session {:hello 1 :old 3}}
  17. (base/assoc-session {:session {:old 3}} {:session {:old 2}} :hello 1)))
  18. (is (= {:session {:old 4}}
  19. (base/assoc-session {:session {:old 3}} {:session {:old 2}} :old 4))))
  20. (deftest bearer-token-from-header
  21. ;; authorization success adds oauth-token on request map
  22. (is (= "secrettoken"
  23. (:access-token
  24. ((base/wrap-bearer-token (fn [req] req) #{"secrettoken"})
  25. {:headers {"authorization" "Bearer secrettoken"}})))
  26. "find matching token")
  27. (is (nil? (:access-token
  28. ((base/wrap-bearer-token (fn [req] req) #{"secrettoken"})
  29. {:headers {"authorization" "Bearer wrongtoken"}})))
  30. "should only return matching token")
  31. (is (nil? (:access-token
  32. ((base/wrap-bearer-token (fn [req] req) #{"secrettoken"})
  33. {:headers {}}))) "should not set if no token present"))
  34. (deftest bearer-token-from-params
  35. ;; authorization success adds oauth-token on request map
  36. (is (= "secrettoken"
  37. (:access-token
  38. ((base/wrap-bearer-token (fn [req] req) #{"secrettoken"})
  39. {:params {:access_token "secrettoken"}})))
  40. "find matching token")
  41. (is (nil? (:access-token
  42. ((base/wrap-bearer-token (fn [req] req) #{"secrettoken"})
  43. { :params {:access_token "wrongtoken"}})))
  44. "should only return matching token")
  45. (is (nil? (:access-token
  46. ((base/wrap-bearer-token (fn [req] req) #{"secrettoken"})
  47. {}))) "should not set if no token present"))
  48. (deftest bearer-token-from-cookies
  49. ;; authorization success adds oauth-token on request map
  50. (is (= "secrettoken"
  51. (:access-token
  52. ((base/wrap-bearer-token (fn [req] req) #{"secrettoken"})
  53. {:cookies {"access_token" { :value "secrettoken"}}})))
  54. "find matching token")
  55. (is (nil? (:access-token
  56. ((base/wrap-bearer-token (fn [req] req) #{"secrettoken"})
  57. {:cookies {"access_token" { :value "wrongtoken"}}})))
  58. "should only return matching token")
  59. (is (nil? (:access-token
  60. ((base/wrap-bearer-token (fn [req] req) #{"secrettoken"})
  61. {}))) "should not set if no token present"))
  62. (deftest bearer-token-from-session
  63. ;; authorization success adds oauth-token on request map
  64. (is (= "secrettoken"
  65. (:access-token
  66. ((base/wrap-bearer-token (fn [req] req) #{"secrettoken"})
  67. {:session {:access_token "secrettoken"}})))
  68. "find matching token")
  69. (is (nil? (:access-token
  70. ((base/wrap-bearer-token (fn [req] req) #{"secrettoken"})
  71. {:session {:access_token "wrongtoken"}})))
  72. "should only return matching token")
  73. (is (nil? (:access-token
  74. ((base/wrap-bearer-token (fn [req] req) #{"secrettoken"})
  75. {}))) "should not set if no token present"))
  76. (deftest require-token
  77. ;; authorization success adds oauth-token on request map
  78. (is (= 200 (:status
  79. ((base/require-bearer-token!
  80. (fn [req] {:status 200}) #{"secrettoken"})
  81. {:headers {"authorization" "Bearer secrettoken"}})))
  82. "find matching token")
  83. (let [response ((base/require-bearer-token!
  84. (fn [req] {:status 200}) #{"secrettoken"})
  85. {:headers {"accept" "text/html"}
  86. :query-string "test=123"
  87. :uri "/protected"})]
  88. (is (= 302 (:status response)) "redirect")
  89. (is (= "/login" ((:headers response) "Location")) "to login")
  90. (is (= "/protected?test=123" ((:session response) :return-to))
  91. "set return-to"))
  92. (is (= 401 (:status
  93. ((base/require-bearer-token!
  94. (fn [req] {:status 200}) #{"secrettoken"})
  95. {:headers {"authorization" "Bearer wrongtoken"}})))
  96. "should only return matching token")
  97. (is (= 401 (:status
  98. ((base/require-bearer-token!
  99. (fn [req] {:status 200}) #{"secrettoken"})
  100. {:headers {}}))) "should not set if no token present"))
  101. (deftest require-user-session
  102. (is (= 200 (:status
  103. ((base/require-user-session!
  104. (fn [req] {:status 200}) #{"secrettoken"})
  105. {:session {:access_token "secrettoken"}}))) "allow from session")
  106. (let [response ((base/require-user-session!
  107. (fn [req] {:status 200}) #{"secrettoken"})
  108. {:headers {"accept" "text/html"}
  109. :query-string "test=123"
  110. :uri "/protected"})]
  111. (is (= 302 (:status response)) "redirect")
  112. (is (= "/login" ((:headers response) "Location")) "to login")
  113. (is (= "/protected?test=123" ((:session response) :return-to))
  114. "set return-to"))
  115. (is (= 403 (:status
  116. ((base/require-user-session!
  117. (fn [req] {:status 200}) #{"secrettoken"})
  118. {:headers {"authorization" "Bearer secrettoken"}})))
  119. "Disallow from auth header")
  120. (is (= 403 (:status
  121. ((base/require-user-session!
  122. (fn [req] {:status 200}) #{"secrettoken"})
  123. {:cookies {"access_token" {:value "secrettoken"}}})))
  124. "Disallow from cookies")
  125. (is (= 403 (:status
  126. ((base/require-user-session!
  127. (fn [req] {:status 200}) #{"secrettoken"})
  128. {:params {:access_token "secrettoken"}})))
  129. "Disallow from params"))
  130. (deftest request-is-html
  131. (is (not (base/is-html? {})))
  132. (is (not (base/is-html? {:headers {"accept" "*/*"}})))
  133. (is (not (base/is-html? {:headers {"accept" "application/json"}})))
  134. (is (base/is-html? {:headers {"accept" "text/html"}}))
  135. (is (base/is-html? {:headers {"accept" "application/xhtml+xml"}}))
  136. (is (base/is-html?
  137. {:headers
  138. {"accept"
  139. "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}})))
  140. (deftest request-is-form
  141. (is (not (base/is-form? {})))
  142. (is (not (base/is-form? {:content-type "application/json"
  143. :access-token "abcde"
  144. :session {:access_token "abcde"}})))
  145. (is (not (base/is-form? {:content-type "application/xml"
  146. :access-token "abcde"
  147. :session {:access_token "abcde"}})))
  148. (is (base/is-form? {:content-type "application/x-www-form-urlencoded"
  149. :access-token "abcde"
  150. :session {:access_token "abcde"}}))
  151. (is (base/is-form? {:content-type "multipart/form-data"
  152. :access-token "abcde"
  153. :session {:access_token "abcde"}}))
  154. (is (not (base/is-form? {:content-type "application/json"})))
  155. (is (not (base/is-form? {:content-type "application/xml"})))
  156. (is (base/is-form? {:content-type "application/x-www-form-urlencoded"}))
  157. (is (base/is-form? {:content-type "multipart/form-data"}))
  158. (is (not (base/is-form? {:content-type "application/json"
  159. :access-token "abcde"})))
  160. (is (not (base/is-form? {:content-type "application/xml"
  161. :access-token "abcde"})))
  162. (is (not (base/is-form? {:content-type "application/x-www-form-urlencoded"
  163. :access-token "abcde"})))
  164. (is (not (base/is-form? {:content-type "multipart/form-data"
  165. :access-token "abcde"}))))
  166. (deftest request-if-html
  167. (is (not (base/if-html {} true false)))
  168. (is (not (base/if-html {:headers {"accept" "*/*"}} true false)))
  169. (is (not (base/if-html {:headers {"accept" "application/json"}} true false)))
  170. (is (base/if-html {:headers {"accept" "text/html"}} true false))
  171. (is (base/if-html {:headers {"accept" "application/xhtml+xml"}} true false))
  172. (is (base/if-html
  173. {:headers
  174. {"accept"
  175. "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}}
  176. true false)))
  177. (deftest request-if-form
  178. (is (not (base/if-form {} true false)))
  179. (is (not (base/if-form {:content-type "application/json"} true false)))
  180. (is (not (base/if-form {:content-type "application/xml"} true false)))
  181. (is (base/if-form {:content-type "application/x-www-form-urlencoded"
  182. :access-token "abcde"
  183. :session {:access_token "abcde"}}
  184. true false))
  185. (is (base/if-form {:content-type "multipart/form-data"
  186. :access-token "abcde"
  187. :session {:access_token "abcde"}}
  188. true false)))
  189. (deftest csrf-token-extraction
  190. (is (nil? (base/csrf-token {})))
  191. (is (= "token" (base/csrf-token {:session {:csrf-token "token"}})))
  192. (is (= "token" (base/csrf-token {:csrf-token "token"}))))
  193. (deftest csrf-is-added-to-session
  194. ;; Should add a csrf-token entry to request if none is in session
  195. (is (not (nil? (:csrf-token (base/with-csrf-token {})))))
  196. ;; should not add to request if one is already in request
  197. (is (nil? (:csrf-token (base/with-csrf-token
  198. {:session {:csrf-token "existing"}})))))
  199. (deftest protects-against-csrf
  200. (let [handler (base/csrf-protect! (fn [req] req))]
  201. (is (not (nil?
  202. (:csrf-token
  203. (:session
  204. (handler {:request-method :get
  205. :headers { "accept" "text/html"}
  206. :access-token "abcde"
  207. :session {:access_token "abcde"}}))))))
  208. (is (= "existing"
  209. (:csrf-token
  210. (:session
  211. (handler {:request-method :get
  212. :session {:csrf-token "existing"}}))))))
  213. (let [handler (base/csrf-protect! (fn [req] {:status 200}))]
  214. (is (= 403 (:status
  215. (handler {:request-method :post
  216. :content-type "application/x-www-form-urlencoded"
  217. :access-token "abcde"
  218. :session {:access_token "abcde"}})))
  219. "should fail for html post without token")
  220. (is (= 200 (:status
  221. (handler
  222. {:request-method :post
  223. :content-type "application/json"
  224. :access-token "abcde"
  225. :session {:access_token "abcde"}})))
  226. "should allow non html")
  227. (is (= 200 (:status
  228. (handler {:request-method :get
  229. :headers {"accept" "text/html"}
  230. :access-token "abcde"
  231. :session {:access_token "abcde"}}))))
  232. (is (not (nil? (:csrf-token
  233. (:session
  234. (handler {:request-method :get
  235. :headers {"accept" "text/html"}}))))))
  236. (let [response (handler {:request-method :get
  237. :headers {"accept" "text/html"}
  238. :session {:csrf-token "existing"}})]
  239. (is (nil? (:session response))))
  240. (is (= 200 (:status
  241. (handler {:request-method :post
  242. :content-type "application/x-www-form-urlencoded"
  243. :access-token "abcde"
  244. :session {:csrf-token "secrettoken"
  245. :access_token "abcde"}
  246. :params {:csrf-token "secrettoken"}}))))
  247. (is (= 403 (:status
  248. (handler {:request-method :post
  249. :content-type "application/x-www-form-urlencoded"
  250. :access-token "abcde"
  251. :session {:csrf-token "secrettoken"
  252. :access_token "abcde"}
  253. :params {:csrf-token "badtoken"}}))))
  254. (is (= 403 (:status
  255. (handler {:request-method :post
  256. :content-type "application/x-www-form-urlencoded"
  257. :access-token "abcde"
  258. :session {base/csrf-token "secrettoken"
  259. :access_token "abcde"}}))))))