Skip to content

Commit

Permalink
Add tests for wrap-authentication and wrap-authorization for async ha…
Browse files Browse the repository at this point in the history
…ndler. Change to not using fn->multi.
  • Loading branch information
burhanloey authored and niwinz committed Jun 2, 2018
1 parent 2d3c11d commit 37aa267
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 13 deletions.
23 changes: 15 additions & 8 deletions src/buddy/auth/middleware.clj
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
(:require [buddy.auth.protocols :as proto]
[buddy.auth.accessrules :as accessrules]
[buddy.auth.http :as http]
[buddy.auth :refer [authenticated? throw-unauthorized]]
[buddy.auth.fnutils :refer [fn->multi]]))
[buddy.auth :refer [authenticated? throw-unauthorized]]))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Authentication
Expand Down Expand Up @@ -56,8 +55,11 @@
handler. When multiple `backends` are given each of them gets a
chance to authenticate the request."
[handler & backends]
(fn->multi [request]
(handler (apply authentication-request request backends))))
(fn
([request]
(handler (apply authentication-request request backends)))
([request respond raise]
(handler (apply authentication-request request backends) respond raise))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Authorization
Expand Down Expand Up @@ -107,7 +109,12 @@
hashmap, or an instance that satisfies IAuthorization
protocol."
[handler backend]
(fn->multi [request]
(try (handler request)
(catch Exception e
(authorization-error request e backend)))))
(fn
([request]
(try (handler request)
(catch Exception e
(authorization-error request e backend))))
([request respond raise]
(try (handler request respond raise)
(catch Exception e
(respond (authorization-error request e backend)))))))
122 changes: 117 additions & 5 deletions test/buddy/auth/middleware_tests.clj
Original file line number Diff line number Diff line change
Expand Up @@ -21,45 +21,103 @@
(when (= data secret)
:valid))))

(defn- async-identity [req respond _]
(respond req))

(deftest wrap-authentication
(testing "Using auth requests"
(let [handler (mw/wrap-authentication identity (auth-backend ::ok ::authdata))
response (handler {::authdata ::ok})]
(is (= (:identity response) :valid))
(is (= (::authdata response) ::ok))))

(testing "Using auth async requests"
(let [handler (-> async-identity
(mw/wrap-authentication (auth-backend ::ok ::authdata)))
response (promise)
exception (promise)]
(handler {::authdata ::ok} response exception)
(is (= (:identity @response) :valid))
(is (= (::authdata @response) ::ok))
(is (not (realized? exception)))))

(testing "Using anon request"
(let [handler (mw/wrap-authentication identity (auth-backend ::ok ::authdata))
response (handler {})]
(is (= (:identity response) nil))
(is (= (::authdata response) nil))))

(testing "Using anon async request"
(let [handler (-> async-identity
(mw/wrap-authentication (auth-backend ::ok ::authdata)))
response (promise)
exception (promise)]
(handler {} response exception)
(is (= (:identity @response) nil))
(is (= (::authdata @response) nil))
(is (not (realized? exception)))))

(testing "Using wrong request"
(let [handler (mw/wrap-authentication identity (auth-backend ::ok ::authdata))
response (handler {::authdata ::fake})]
(is (nil? (:identity response)))
(is (= (::authdata response) ::fake)))))
(is (= (::authdata response) ::fake))))

(testing "Using wrong async request"
(let [handler (-> async-identity
(mw/wrap-authentication (auth-backend ::ok ::authdata)))
response (promise)
exception (promise)]
(handler {::authdata ::fake} response promise)
(is (nil? (:identity @response)))
(is (= (::authdata @response) ::fake))
(is (not (realized? exception))))))

(deftest wrap-authentication-with-multiple-backends
(let [backends [(auth-backend ::ok-1 ::authdata)
(auth-backend ::ok-2 ::authdata2)]
handler (apply mw/wrap-authentication identity backends)]
handler (apply mw/wrap-authentication identity backends)
async-handler (apply mw/wrap-authentication async-identity backends)]

(testing "backend #1 succeeds"
(let [response (handler {::authdata ::ok-1})]
(is (= (:identity response) :valid))
(is (= (::authdata response) ::ok-1))))

(testing "backend #1 succeeds for async"
(let [response (promise)
exception (promise)]
(async-handler {::authdata ::ok-1} response exception)
(is (= (:identity @response) :valid))
(is (= (::authdata @response) ::ok-1))
(is (not (realized? exception)))))

(testing "backend #2 succeeds"
(let [response (handler {::authdata2 ::ok-2})]
(is (= (:identity response) :valid))
(is (= (::authdata2 response) ::ok-2))))

(testing "backend #2 succeeds for async"
(let [response (promise)
exception (promise)]
(async-handler {::authdata2 ::ok-2} response exception)
(is (= (:identity @response) :valid))
(is (= (::authdata2 @response) ::ok-2))
(is (not (realized? exception)))))

(testing "no backends succeeds"
(let [response (handler {::authdata ::fake})]
(is (nil? (:identity response)))
(is (= (::authdata response) ::fake))))

(testing "no backends succeeds for async"
(let [response (promise)
exception (promise)]
(async-handler {::authdata ::fake} response exception)
(is (nil? (:identity @response)))
(is (= (::authdata @response) ::fake))
(is (not (realized? exception)))))

(testing "handler called exactly once"
(let [state (atom 0)
counter (fn [request] (swap! state inc) request)
Expand All @@ -69,9 +127,30 @@
(is (= (::authdata response) ::fake))
(is (= @state 1))))

(testing "async handler called exactly once"
(let [state (atom 0)
counter (fn [request respond raise]
(swap! state inc)
(respond request))
handler (apply mw/wrap-authentication counter backends)
response (promise)
exception (promise)]
(handler {::authdata ::fake} response exception)
(is (nil? (:identity @response)))
(is (= (::authdata @response) ::fake))
(is (= @state 1))
(is (not (realized? exception)))))

(testing "with zero backends"
(let [request {:uri "/"}]
(is (= ((mw/wrap-authentication identity) request) request))))))
(is (= ((mw/wrap-authentication identity) request) request))))

(testing "with zero backends for async"
(let [request {:uri "/"}
response (promise)
exception (promise)]
((mw/wrap-authentication async-identity) request response exception)
(is (= @response request))))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Authorization middleware testing
Expand All @@ -87,7 +166,15 @@
(testing "Simple authorized request"
(let [handler (mw/wrap-authorization identity autz-backend)
response (handler {:foo :bar})]
(= (:ok response) :bar)))
(is (= (:foo response) :bar))))

(testing "Simple authorized async request"
(let [handler (mw/wrap-authorization async-identity autz-backend)
response (promise)
exception (promise)]
(handler {:foo :bar} response exception)
(is (= (:foo @response) :bar))
(is (not (realized? exception)))))

(testing "Unauthorized request"
(let [handler (fn [req]
Expand All @@ -98,6 +185,18 @@
(is (= (:status response) 401))
(is (= (:data response) {:foo :bar}))))

(testing "Unauthorized async request"
(let [handler (fn [req respond raise]
(throw-unauthorized {:foo :bar}))
handler (mw/wrap-authorization handler autz-backend)
response (promise)
exception (promise)]
(handler {} response exception)
(is (= (:body @response) "error"))
(is (= (:status @response) 401))
(is (= (:data @response) {:foo :bar}))
(is (not (realized? exception)))))

;; (testing "Unauthorized request with custom exception"
;; (let [handler (fn [req]
;; (throw (proxy [Exception proto/IAuthorization] []
Expand All @@ -118,4 +217,17 @@
response (handler {})]
(is (= (:body response) "error"))
(is (= (:status response) 401))
(is (= (:data response) {:foo :bar})))))
(is (= (:data response) {:foo :bar}))))

(testing "Unauthorized async request with backend as function"
(let [backend (fn [request data] {:body "error" :status 401 :data data})
handler (fn [req respond raise]
(throw-unauthorized {:foo :bar}))
handler (mw/wrap-authorization handler backend)
response (promise)
exception (promise)]
(handler {} response exception)
(is (= (:body @response) "error"))
(is (= (:status @response) 401))
(is (= (:data @response) {:foo :bar}))
(is (not (realized? exception))))))

0 comments on commit 37aa267

Please sign in to comment.