mirror of
https://github.com/penpot/penpot.git
synced 2025-05-11 12:16:38 +02:00
feat(backend): move almost all middlewares to api.middleware ns
This commit is contained in:
parent
2e9fb97a98
commit
210fbb9535
3 changed files with 106 additions and 95 deletions
|
@ -6,28 +6,13 @@
|
||||||
|
|
||||||
(ns uxbox.api
|
(ns uxbox.api
|
||||||
(:require [mount.core :refer [defstate]]
|
(:require [mount.core :refer [defstate]]
|
||||||
[clojure.pprint :refer [pprint]]
|
|
||||||
[uxbox.config :as cfg]
|
[uxbox.config :as cfg]
|
||||||
[ring.middleware.session :refer [wrap-session]]
|
|
||||||
[ring.middleware.session.cookie :refer [cookie-store]]
|
|
||||||
[ring.adapter.jetty :as jetty]
|
[ring.adapter.jetty :as jetty]
|
||||||
[promesa.core :as p]
|
|
||||||
[reitit.core :as rc]
|
|
||||||
[reitit.ring :as ring]
|
[reitit.ring :as ring]
|
||||||
[reitit.ring.middleware.muuntaja :as muuntaja]
|
[uxbox.api.middleware :refer [handler router-options]]
|
||||||
[reitit.ring.middleware.multipart :as multipart]
|
|
||||||
[reitit.ring.middleware.parameters :as parameters]
|
|
||||||
;; [reitit.dev.pretty :as pretty]
|
|
||||||
[uxbox.api.middleware :as api-middleware :refer [handler]]
|
|
||||||
[uxbox.api.auth :as api-auth]
|
[uxbox.api.auth :as api-auth]
|
||||||
[uxbox.api.projects :as api-projects]
|
|
||||||
[uxbox.api.pages :as api-pages]
|
[uxbox.api.pages :as api-pages]
|
||||||
[uxbox.api.errors :as api-errors]
|
[uxbox.api.projects :as api-projects]))
|
||||||
[muuntaja.core :as m]
|
|
||||||
[uxbox.util.transit :as t]
|
|
||||||
[uxbox.util.data :refer [normalize-attrs]]
|
|
||||||
[uxbox.util.exceptions :as ex]
|
|
||||||
[uxbox.util.uuid :as uuid]))
|
|
||||||
|
|
||||||
;; --- Top Level Handlers
|
;; --- Top Level Handlers
|
||||||
|
|
||||||
|
@ -59,44 +44,15 @@
|
||||||
["/projects/by-token/:token" {:get (handler #'api-projects/get-by-share-token)}]
|
["/projects/by-token/:token" {:get (handler #'api-projects/get-by-share-token)}]
|
||||||
["/projects/:id" {:put (handler #'api-projects/update)
|
["/projects/:id" {:put (handler #'api-projects/update)
|
||||||
:delete (handler #'api-projects/delete)}]
|
:delete (handler #'api-projects/delete)}]
|
||||||
["/pages" {:get (handler #'api-pages/list)}]
|
["/pages" {:get (handler #'api-pages/list)
|
||||||
|
:post (handler #'api-pages/create)}]
|
||||||
["/pages/:id" {:put (handler #'api-pages/update)
|
["/pages/:id" {:put (handler #'api-pages/update)
|
||||||
:delete (handler #'api-pages/delete)}]
|
:delete (handler #'api-pages/delete)}]
|
||||||
["/pages/:id/metatata" {:put (handler #'api-pages/update-metadata)}]
|
["/pages/:id/metadata" {:put (handler #'api-pages/update-metadata)}]
|
||||||
["/pages/:id/history" {:get (handler #'api-pages/retrieve-history)}]
|
["/pages/:id/history" {:get (handler #'api-pages/retrieve-history)}]
|
||||||
|
["/pages/:id/history/:hid" {:put (handler #'api-pages/update-history)}]
|
||||||
]]
|
]]
|
||||||
|
router-options))
|
||||||
{;;:reitit.middleware/transform dev/print-request-diffs
|
|
||||||
:data {:muuntaja (m/create
|
|
||||||
(update-in m/default-options [:formats "application/transit+json"]
|
|
||||||
merge {:encoder-opts {:handlers t/+write-handlers+}
|
|
||||||
:decoder-opts {:handlers t/+read-handlers+}}))
|
|
||||||
:middleware [
|
|
||||||
;; {:name "CORS Middleware"
|
|
||||||
;; :wrap #(wrap-cors %
|
|
||||||
;; :access-control-allow-origin [#".*"]
|
|
||||||
;; :access-control-allow-methods [:get :put :post :delete]
|
|
||||||
;; :access-control-allow-headers ["x-requested-with"
|
|
||||||
;; "content-type"
|
|
||||||
;; "authorization"])}
|
|
||||||
[wrap-session {:store (cookie-store {:key "a 16-byte secret"})
|
|
||||||
:cookie-name "session"
|
|
||||||
:cookie-attrs {:same-site :lax
|
|
||||||
:http-only true}}]
|
|
||||||
parameters/parameters-middleware
|
|
||||||
api-middleware/normalize-params-middleware
|
|
||||||
;; content-negotiation
|
|
||||||
muuntaja/format-negotiate-middleware
|
|
||||||
;; encoding response body
|
|
||||||
muuntaja/format-response-middleware
|
|
||||||
;; exception handling
|
|
||||||
api-errors/exception-middleware
|
|
||||||
;; decoding request body
|
|
||||||
muuntaja/format-request-middleware
|
|
||||||
;; validation
|
|
||||||
api-middleware/parameters-validation-middleware
|
|
||||||
;; multipart
|
|
||||||
multipart/multipart-middleware]}}))
|
|
||||||
|
|
||||||
(def app
|
(def app
|
||||||
(ring/ring-handler routes (ring/create-default-handler)))
|
(ring/ring-handler routes (ring/create-default-handler)))
|
||||||
|
|
|
@ -5,19 +5,21 @@
|
||||||
;; Copyright (c) 2016-2019 Andrey Antukh <niwi@niwi.nz>
|
;; Copyright (c) 2016-2019 Andrey Antukh <niwi@niwi.nz>
|
||||||
|
|
||||||
(ns uxbox.api.middleware
|
(ns uxbox.api.middleware
|
||||||
(:require [reitit.core :as rc]
|
(:require [muuntaja.core :as m]
|
||||||
[struct.core :as st]
|
|
||||||
[promesa.core :as p]
|
[promesa.core :as p]
|
||||||
|
[reitit.core :as rc]
|
||||||
|
[reitit.ring.middleware.multipart :as multipart]
|
||||||
|
[reitit.ring.middleware.muuntaja :as muuntaja]
|
||||||
|
[reitit.ring.middleware.parameters :as parameters]
|
||||||
|
[ring.middleware.session :refer [wrap-session]]
|
||||||
|
[ring.middleware.session.cookie :refer [cookie-store]]
|
||||||
|
[struct.core :as st]
|
||||||
|
[uxbox.api.errors :as api-errors]
|
||||||
[uxbox.util.data :refer [normalize-attrs]]
|
[uxbox.util.data :refer [normalize-attrs]]
|
||||||
[uxbox.util.exceptions :as ex]))
|
[uxbox.util.exceptions :as ex]
|
||||||
|
[uxbox.util.transit :as t]))
|
||||||
|
|
||||||
;; (extend-protocol rc/Expand
|
(defn- transform-handler
|
||||||
;; clojure.lang.Var
|
|
||||||
;; (expand [this opts]
|
|
||||||
;; (merge (rc/expand (deref this) opts)
|
|
||||||
;; {::handler-metadata (meta this)})))
|
|
||||||
|
|
||||||
(defn transform-handler
|
|
||||||
[handler]
|
[handler]
|
||||||
(fn [request respond raise]
|
(fn [request respond raise]
|
||||||
(try
|
(try
|
||||||
|
@ -30,17 +32,7 @@
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
(raise e)))))
|
(raise e)))))
|
||||||
|
|
||||||
(defn handler
|
(def ^:private normalize-params-middleware
|
||||||
[invar]
|
|
||||||
(let [metadata (meta invar)
|
|
||||||
hlrdata (-> metadata
|
|
||||||
(dissoc :arglist :line :column :file :ns)
|
|
||||||
(assoc :handler (transform-handler (var-get invar))
|
|
||||||
:fullname (symbol (str (:ns metadata)) (str (:name metadata)))))]
|
|
||||||
(cond-> hlrdata
|
|
||||||
(:doc metadata) (assoc :description (:doc metadata)))))
|
|
||||||
|
|
||||||
(def normalize-params-middleware
|
|
||||||
{:name ::normalize-params-middleware
|
{:name ::normalize-params-middleware
|
||||||
:wrap (fn [handler]
|
:wrap (fn [handler]
|
||||||
(letfn [(transform-request [request]
|
(letfn [(transform-request [request]
|
||||||
|
@ -58,9 +50,7 @@
|
||||||
(raise e))))))))})
|
(raise e))))))))})
|
||||||
|
|
||||||
|
|
||||||
;; --- Validation
|
(def ^:private parameters-validation-middleware
|
||||||
|
|
||||||
(def parameters-validation-middleware
|
|
||||||
(letfn [(prepare [parameters]
|
(letfn [(prepare [parameters]
|
||||||
(reduce-kv
|
(reduce-kv
|
||||||
(fn [acc key spec]
|
(fn [acc key spec]
|
||||||
|
@ -81,21 +71,72 @@
|
||||||
(ex/raise :type :parameters-validation
|
(ex/raise :type :parameters-validation
|
||||||
:code (:key spec)
|
:code (:key spec)
|
||||||
:context errors
|
:context errors
|
||||||
|
:value (get req key)
|
||||||
:message "Invalid data")
|
:message "Invalid data")
|
||||||
|
|
||||||
(assoc-in req [:parameters (:key spec)] result))))
|
(assoc-in req [:parameters (:key spec)] result))))
|
||||||
request parameters))]
|
request parameters))
|
||||||
|
|
||||||
|
(compile [route opts]
|
||||||
|
(when-let [parameters (:parameters route)]
|
||||||
|
(let [parameters (prepare parameters)]
|
||||||
|
(fn [handler]
|
||||||
|
(fn
|
||||||
|
([request]
|
||||||
|
(handler (validate request parameters)))
|
||||||
|
([request respond raise]
|
||||||
|
(try
|
||||||
|
(handler (validate request parameters false) respond raise)
|
||||||
|
(catch Exception e
|
||||||
|
(raise e)))))))))]
|
||||||
{:name ::parameters-validation-middleware
|
{:name ::parameters-validation-middleware
|
||||||
:compile (fn [route opts]
|
:compile compile}))
|
||||||
(when-let [parameters (:parameters route)]
|
|
||||||
(let [parameters (prepare parameters)]
|
(def ^:private session-middleware
|
||||||
(fn [handler]
|
(let [options {:store (cookie-store {:key "a 16-byte secret"})
|
||||||
(fn
|
:cookie-name "session"
|
||||||
([request]
|
:cookie-attrs {:same-site :lax :http-only true}}]
|
||||||
(handler (validate request parameters)))
|
{:name ::session-middleware
|
||||||
([request respond raise]
|
:wrap #(wrap-session % options)}))
|
||||||
(try
|
|
||||||
(handler (validate request parameters false) respond raise)
|
;; (def ^:private cors-middleware
|
||||||
(catch Exception e
|
;; {:name ::cors-middleware
|
||||||
(raise e)))))))))}))
|
;; :wrap #(wrap-cors %
|
||||||
|
;; :access-control-allow-origin [#".*"]
|
||||||
|
;; :access-control-allow-methods [:get :put :post :delete]
|
||||||
|
;; :access-control-allow-headers ["x-requested-with"
|
||||||
|
;; "content-type"
|
||||||
|
;; "authorization"])})
|
||||||
|
|
||||||
|
(def ^:private muuntaja-instance
|
||||||
|
(m/create (update-in m/default-options [:formats "application/transit+json"]
|
||||||
|
merge {:encoder-opts {:handlers t/+write-handlers+}
|
||||||
|
:decoder-opts {:handlers t/+read-handlers+}})))
|
||||||
|
(def router-options
|
||||||
|
{;;:reitit.middleware/transform dev/print-request-diffs
|
||||||
|
:data {:muuntaja muuntaja-instance
|
||||||
|
:middleware [session-middleware
|
||||||
|
parameters/parameters-middleware
|
||||||
|
normalize-params-middleware
|
||||||
|
;; content-negotiation
|
||||||
|
muuntaja/format-negotiate-middleware
|
||||||
|
;; encoding response body
|
||||||
|
muuntaja/format-response-middleware
|
||||||
|
;; exception handling
|
||||||
|
api-errors/exception-middleware
|
||||||
|
;; decoding request body
|
||||||
|
muuntaja/format-request-middleware
|
||||||
|
;; validation
|
||||||
|
parameters-validation-middleware
|
||||||
|
;; multipart
|
||||||
|
multipart/multipart-middleware]}})
|
||||||
|
|
||||||
|
(defn handler
|
||||||
|
[invar]
|
||||||
|
(let [metadata (meta invar)
|
||||||
|
hlrdata (-> metadata
|
||||||
|
(dissoc :arglist :line :column :file :ns)
|
||||||
|
(assoc :handler (transform-handler (var-get invar))
|
||||||
|
:fullname (symbol (str (:ns metadata)) (str (:name metadata)))))]
|
||||||
|
(cond-> hlrdata
|
||||||
|
(:doc metadata) (assoc :description (:doc metadata)))))
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
"Create page for a project"
|
"Create page for a project"
|
||||||
{:parameters {:body {:data [st/required]
|
{:parameters {:body {:data [st/required]
|
||||||
:metadata [st/required]
|
:metadata [st/required]
|
||||||
:project [st/required st/uuid-str]
|
:project [st/required st/uuid]
|
||||||
:name [st/required st/string]
|
:name [st/required st/string]
|
||||||
:id [st/uuid-str]}}}
|
:id [st/uuid]}}}
|
||||||
[{:keys [user parameters]}]
|
[{:keys [user parameters]}]
|
||||||
(let [data (get parameters :body)
|
(let [data (get parameters :body)
|
||||||
message (assoc data :user user :type :create-page)]
|
message (assoc data :user user :type :create-page)]
|
||||||
|
@ -42,10 +42,10 @@
|
||||||
{:parameters {:path {:id [st/required st/uuid-str]}
|
{:parameters {:path {:id [st/required st/uuid-str]}
|
||||||
:body {:data [st/required]
|
:body {:data [st/required]
|
||||||
:metadata [st/required]
|
:metadata [st/required]
|
||||||
:project [st/required st/uuid-str]
|
:project [st/required st/uuid]
|
||||||
:name [st/required st/string]
|
:name [st/required st/string]
|
||||||
:version [st/required st/integer]
|
:version [st/required st/integer]
|
||||||
:id [st/uuid-str]}}}
|
:id [st/uuid]}}}
|
||||||
[{:keys [user parameters]}]
|
[{:keys [user parameters]}]
|
||||||
(let [id (get-in parameters [:path :id])
|
(let [id (get-in parameters [:path :id])
|
||||||
data (get parameters :body)
|
data (get parameters :body)
|
||||||
|
@ -56,9 +56,9 @@
|
||||||
(defn update-metadata
|
(defn update-metadata
|
||||||
"Update page metadata"
|
"Update page metadata"
|
||||||
{:parameters {:path {:id [st/required st/uuid-str]}
|
{:parameters {:path {:id [st/required st/uuid-str]}
|
||||||
:body {:id [st/required st/uuid-str]
|
:body {:id [st/required st/uuid]
|
||||||
:metadata [st/required]
|
:metadata [st/required]
|
||||||
:project [st/required st/uuid-str]
|
:project [st/required st/uuid]
|
||||||
:name [st/required st/string]}}}
|
:name [st/required st/string]}}}
|
||||||
[{:keys [user parameters]}]
|
[{:keys [user parameters]}]
|
||||||
(let [id (get-in parameters [:path :id])
|
(let [id (get-in parameters [:path :id])
|
||||||
|
@ -87,3 +87,17 @@
|
||||||
message (assoc data :id id :type :list-page-history :user user)]
|
message (assoc data :id id :type :list-page-history :user user)]
|
||||||
(->> (sv/query message)
|
(->> (sv/query message)
|
||||||
(p/map #(http/ok %)))))
|
(p/map #(http/ok %)))))
|
||||||
|
|
||||||
|
(defn update-history
|
||||||
|
{:parameters {:path {:id [st/required st/uuid-str]
|
||||||
|
:hid [st/required st/uuid-str]}
|
||||||
|
:body {:label [st/required st/string]
|
||||||
|
::pinned [st/required st/boolean]}}}
|
||||||
|
[{:keys [user parameters]}]
|
||||||
|
(let [{:keys [id hid]} (get parameters :path)
|
||||||
|
message (assoc (get parameters :body)
|
||||||
|
:type :update-page-history
|
||||||
|
:id hid
|
||||||
|
:user user)]
|
||||||
|
(->> (sv/novelty message)
|
||||||
|
(p/map #(http/ok %)))))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue