mirror of
https://github.com/metosin/reitit.git
synced 2025-12-17 00:11:11 +00:00
Match is injected into request
This commit is contained in:
parent
6a8f94283a
commit
7cd4c62216
3 changed files with 57 additions and 10 deletions
|
|
@ -1,5 +1,6 @@
|
|||
(ns reitit.middleware
|
||||
(:require [reitit.core :as reitit]))
|
||||
(:require [meta-merge.core :refer [meta-merge]]
|
||||
[reitit.core :as reitit]))
|
||||
|
||||
(defprotocol ExpandMiddleware
|
||||
(expand-middleware [this]))
|
||||
|
|
@ -40,5 +41,9 @@
|
|||
(ensure-handler! path meta scope)
|
||||
((compose-middleware middleware) handler)))
|
||||
|
||||
(defn router [data]
|
||||
(reitit/router data {:compile compile-handler}))
|
||||
(defn router
|
||||
([data]
|
||||
(router data nil))
|
||||
([data opts]
|
||||
(let [opts (meta-merge {:compile compile-handler} opts)]
|
||||
(reitit/router data opts))))
|
||||
|
|
|
|||
|
|
@ -18,15 +18,18 @@
|
|||
(fn
|
||||
([request]
|
||||
(if-let [match (reitit/match-by-path router (:uri request))]
|
||||
((:handler match) request)))
|
||||
((:handler match) (assoc request ::match match))))
|
||||
([request respond raise]
|
||||
(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}))
|
||||
|
||||
(defn get-router [handler]
|
||||
(some-> handler meta ::router))
|
||||
|
||||
(defn get-match [request]
|
||||
(::match request))
|
||||
|
||||
(defn coerce-handler [[path meta] {:keys [expand]}]
|
||||
[path (reduce
|
||||
(fn [acc method]
|
||||
|
|
@ -53,6 +56,10 @@
|
|||
(if-let [handler (resolved-handler (:request-method request))]
|
||||
(handler request respond raise))))))))
|
||||
|
||||
(defn router [data]
|
||||
(reitit/router data {:coerce coerce-handler
|
||||
:compile compile-handler}))
|
||||
(defn router
|
||||
([data]
|
||||
(router data nil))
|
||||
([data opts]
|
||||
(let [opts (meta-merge {:coerce coerce-handler
|
||||
:compile compile-handler} opts)]
|
||||
(reitit/router data opts))))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
(ns reitit.ring-test
|
||||
(:require [clojure.test :refer [deftest testing is]]
|
||||
[reitit.middleware :as middleware]
|
||||
[reitit.ring :as ring])
|
||||
[reitit.ring :as ring]
|
||||
[clojure.set :as set])
|
||||
#?(:clj
|
||||
(:import (clojure.lang ExceptionInfo))))
|
||||
|
||||
|
|
@ -121,4 +122,38 @@
|
|||
respond (partial reset! result), raise ::not-called]
|
||||
(app {:uri "/api/users" :request-method :post} respond raise)
|
||||
(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}}))))))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue