2017-02-16 22:31:16 +01:00
|
|
|
(ns yenu.middleware
|
2017-04-25 22:53:34 +02:00
|
|
|
(:require [clojure.tools.logging :as log]
|
2017-02-16 22:31:16 +01:00
|
|
|
[ring.middleware.anti-forgery :refer [wrap-anti-forgery]]
|
|
|
|
[ring.middleware.webjars :refer [wrap-webjars]]
|
|
|
|
[ring.middleware.format :refer [wrap-restful-format]]
|
|
|
|
[ring.middleware.flash :refer [wrap-flash]]
|
2017-04-03 21:21:48 +02:00
|
|
|
[ring.middleware.cookies :refer [wrap-cookies]]
|
2017-03-29 14:39:03 +02:00
|
|
|
[ring.middleware.defaults :refer [site-defaults wrap-defaults]]
|
2017-04-25 22:53:34 +02:00
|
|
|
[ring.util.response :refer [redirect]]
|
|
|
|
[immutant.web.middleware :refer [wrap-session]]
|
|
|
|
|
|
|
|
[yenu.env :refer [defaults]]
|
|
|
|
[yenu.config :refer [env]]
|
|
|
|
[yenu.layout :refer [*app-context* *identity* error-page]]
|
|
|
|
|
|
|
|
[buddy.auth :refer [authenticated?]]
|
2017-03-29 14:39:03 +02:00
|
|
|
[buddy.auth.middleware :refer [wrap-authentication wrap-authorization]]
|
|
|
|
[buddy.auth.backends.session :refer [session-backend]]
|
2017-04-25 22:53:34 +02:00
|
|
|
[buddy.auth.accessrules :refer [wrap-access-rules success error restrict]]
|
|
|
|
|
|
|
|
[digest :as digest])
|
2017-02-16 22:31:16 +01:00
|
|
|
(:import [javax.servlet ServletContext]))
|
|
|
|
|
|
|
|
(defn wrap-context [handler]
|
|
|
|
(fn [request]
|
|
|
|
(binding [*app-context*
|
|
|
|
(if-let [context (:servlet-context request)]
|
|
|
|
;; If we're not inside a servlet environment
|
|
|
|
;; (for example when using mock requests), then
|
|
|
|
;; .getContextPath might not exist
|
|
|
|
(try (.getContextPath ^ServletContext context)
|
|
|
|
(catch IllegalArgumentException _ context))
|
|
|
|
;; if the context is not specified in the request
|
|
|
|
;; we check if one has been specified in the environment
|
|
|
|
;; instead
|
|
|
|
(:app-context env))]
|
|
|
|
(handler request))))
|
|
|
|
|
|
|
|
(defn wrap-internal-error [handler]
|
|
|
|
(fn [req]
|
|
|
|
(try
|
|
|
|
(handler req)
|
|
|
|
(catch Throwable t
|
|
|
|
(log/error t)
|
|
|
|
(error-page {:status 500
|
|
|
|
:title "Something very bad has happened!"
|
|
|
|
:message "We've dispatched a team of highly trained gnomes to take care of the problem."})))))
|
|
|
|
|
|
|
|
(defn wrap-csrf [handler]
|
|
|
|
(wrap-anti-forgery
|
2017-03-29 14:39:03 +02:00
|
|
|
handler
|
|
|
|
{:error-response
|
|
|
|
(error-page
|
|
|
|
{:status 403
|
|
|
|
:title "Invalid anti-forgery token"})}))
|
|
|
|
|
|
|
|
(defn wrap-identity [handler]
|
|
|
|
(fn [request]
|
|
|
|
(binding [*identity* (get-in request [:session :identity])]
|
|
|
|
(handler request))))
|
2017-02-16 22:31:16 +01:00
|
|
|
|
|
|
|
(defn wrap-formats [handler]
|
|
|
|
(let [wrapped (wrap-restful-format
|
2017-03-29 14:39:03 +02:00
|
|
|
handler
|
|
|
|
{:formats [:json-kw :transit-json :transit-msgpack]})]
|
2017-02-16 22:31:16 +01:00
|
|
|
(fn [request]
|
|
|
|
;; disable wrap-formats for websockets
|
|
|
|
;; since they're not compatible with this middleware
|
|
|
|
((if (:websocket? request) handler wrapped) request))))
|
|
|
|
|
2017-03-29 14:39:03 +02:00
|
|
|
(defn on-error [request response]
|
2017-04-25 22:53:34 +02:00
|
|
|
(redirect (format "/login?next=%s" (:uri request))))
|
2017-03-29 14:39:03 +02:00
|
|
|
|
|
|
|
(defn creator-access [request]
|
|
|
|
(let [identity (:identity request)]
|
|
|
|
(if (= identity :creator)
|
|
|
|
true
|
|
|
|
(error "Not a creator."))))
|
|
|
|
|
2017-04-23 22:33:28 +02:00
|
|
|
(defn external-access-with-pw [request]
|
|
|
|
(if (= (get (:query-params request) "password") (digest/md5 (:user-password env)))
|
|
|
|
true
|
|
|
|
(error "Wrong password.")))
|
|
|
|
|
2017-03-29 14:39:03 +02:00
|
|
|
(def rules
|
2017-04-23 22:33:28 +02:00
|
|
|
[{:uris ["/feed"]
|
|
|
|
:handler external-access-with-pw}
|
|
|
|
{:uris ["/upload" "/statistics" "/comments"]
|
2017-03-29 14:39:03 +02:00
|
|
|
:handler creator-access}
|
|
|
|
{:pattern #"^/.*"
|
|
|
|
:handler authenticated?}])
|
|
|
|
|
2017-04-03 21:21:48 +02:00
|
|
|
(defn wrap-auth [handler]
|
2017-04-25 22:53:34 +02:00
|
|
|
(-> handler
|
|
|
|
(wrap-access-rules {:rules rules :on-error on-error})
|
|
|
|
(wrap-authentication session-backend)
|
|
|
|
(wrap-authorization session-backend)))
|
2017-04-03 21:21:48 +02:00
|
|
|
|
2017-02-16 22:31:16 +01:00
|
|
|
(defn wrap-base [handler]
|
|
|
|
(-> ((:middleware defaults) handler)
|
|
|
|
wrap-webjars
|
|
|
|
wrap-flash
|
2017-04-18 21:38:09 +02:00
|
|
|
(wrap-session {:timeout (* 60 60 24 7)
|
|
|
|
:cookie-attrs {:http-only true}})
|
2017-04-03 21:21:48 +02:00
|
|
|
wrap-cookies
|
2017-02-16 22:31:16 +01:00
|
|
|
(wrap-defaults
|
2017-03-29 14:39:03 +02:00
|
|
|
(-> site-defaults
|
|
|
|
(assoc-in [:security :anti-forgery] false)
|
|
|
|
(dissoc :session)))
|
2017-02-16 22:31:16 +01:00
|
|
|
wrap-context
|
|
|
|
wrap-internal-error))
|