Match is injected into request

This commit is contained in:
Tommi Reiman 2017-08-15 10:05:26 +03:00
parent 6a8f94283a
commit 7cd4c62216
3 changed files with 57 additions and 10 deletions

View file

@ -1,5 +1,6 @@
(ns reitit.middleware (ns reitit.middleware
(:require [reitit.core :as reitit])) (:require [meta-merge.core :refer [meta-merge]]
[reitit.core :as reitit]))
(defprotocol ExpandMiddleware (defprotocol ExpandMiddleware
(expand-middleware [this])) (expand-middleware [this]))
@ -40,5 +41,9 @@
(ensure-handler! path meta scope) (ensure-handler! path meta scope)
((compose-middleware middleware) handler))) ((compose-middleware middleware) handler)))
(defn router [data] (defn router
(reitit/router data {:compile compile-handler})) ([data]
(router data nil))
([data opts]
(let [opts (meta-merge {:compile compile-handler} opts)]
(reitit/router data opts))))

View file

@ -18,15 +18,18 @@
(fn (fn
([request] ([request]
(if-let [match (reitit/match-by-path router (:uri request))] (if-let [match (reitit/match-by-path router (:uri request))]
((:handler match) request))) ((:handler match) (assoc request ::match match))))
([request respond raise] ([request respond raise]
(if-let [match (reitit/match-by-path router (:uri request))] (if-let [match (reitit/match-by-path router (:uri request))]
((:handler match) request respond raise)))) ((:handler match) (assoc request ::match match) respond raise))))
{::router router})) {::router router}))
(defn get-router [handler] (defn get-router [handler]
(some-> handler meta ::router)) (some-> handler meta ::router))
(defn get-match [request]
(::match request))
(defn coerce-handler [[path meta] {:keys [expand]}] (defn coerce-handler [[path meta] {:keys [expand]}]
[path (reduce [path (reduce
(fn [acc method] (fn [acc method]
@ -53,6 +56,10 @@
(if-let [handler (resolved-handler (:request-method request))] (if-let [handler (resolved-handler (:request-method request))]
(handler request respond raise)))))))) (handler request respond raise))))))))
(defn router [data] (defn router
(reitit/router data {:coerce coerce-handler ([data]
:compile compile-handler})) (router data nil))
([data opts]
(let [opts (meta-merge {:coerce coerce-handler
:compile compile-handler} opts)]
(reitit/router data opts))))

View file

@ -1,7 +1,8 @@
(ns reitit.ring-test (ns reitit.ring-test
(:require [clojure.test :refer [deftest testing is]] (:require [clojure.test :refer [deftest testing is]]
[reitit.middleware :as middleware] [reitit.middleware :as middleware]
[reitit.ring :as ring]) [reitit.ring :as ring]
[clojure.set :as set])
#?(:clj #?(:clj
(:import (clojure.lang ExceptionInfo)))) (:import (clojure.lang ExceptionInfo))))
@ -121,4 +122,38 @@
respond (partial reset! result), raise ::not-called] respond (partial reset! result), raise ::not-called]
(app {:uri "/api/users" :request-method :post} respond raise) (app {:uri "/api/users" :request-method :post} respond raise)
(is (= {:status 200, :body [:api :users :post :ok :post :users :api]} (is (= {:status 200, :body [:api :users :post :ok :post :users :api]}
@result))))))) @result))))))
(testing "runtime extensions for meta-data"
(let [enforce-roles (fn [handler]
(fn [{:keys [::roles] :as request}]
(let [required (some-> request
(ring/get-match)
:meta
::roles)]
(if (or (not (seq required))
(set/intersection required roles))
(handler request)
{:status 403 :body "forbidden"}))))
router (ring/router
[["/api"
["/ping" handler]
["/admin" {::roles #{:admin}}
["/ping" handler]]]]
{:meta {:middleware [enforce-roles]}})
app (ring/ring-handler router)]
(testing "public handler"
(is (= {:status 200, :body [:ok]}
(app {:uri "/api/ping" :request-method :get}))))
(testing "runtime-enforced handler"
(testing "without needed roles"
(is (= {:status 403 :body "forbidden"}
(app {:uri "/api/admin/ping"
:request-method :get}))))
(testing "with needed roles"
(is (= {:status 200, :body [:ok]}
(app {:uri "/api/admin/ping"
:request-method :get
::roles #{:admin}}))))))))