Skip to content

Instantly share code, notes, and snippets.

@ricardojmendez
Forked from Deraen/00_notes.md
Created August 23, 2016 21:09
Show Gist options
  • Save ricardojmendez/2fa26562d85df60f71476cc8d574439d to your computer and use it in GitHub Desktop.
Save ricardojmendez/2fa26562d85df60f71476cc8d574439d to your computer and use it in GitHub Desktop.
Compojure-api and Buddy
  • (:identity req) is auth backend independent way to access user data
  • login and logout implementation depends on auth backend
  • :current-user doesn't imply that authentication is required, route should also have :auth-rules if authentication is required
(ns backend.access
(:require [buddy.auth :refer [authenticated?]]))
(defn authenticated [req]
(authenticated? req))
(defn admin [req]
(and (authenticated? req)
(#{:admin} (:role (:identity req)))))
(ns backend.handler
(:require [backend.session :refer [wrap-app-session]]
[ring.util.http-response :refer [ok]]
[compojure.api.sweet :refer :all]
[backend.access :as access]
backend.restructure))
(defapi app'
{:swagger {:ui "/api-docs"
:spec "/swagger.json"}}
(POST "/login" []
(assoc-in (ok) [:session :identity] {:_id 1, :username "juho"}))
(POST "/logout" []
(assoc-in (ok) [:session :identity] nil))
(GET "/foo" []
:auth-rules access/authenticated
; :auth-rules {:or [access/authenticated access/other-predicate]}
; :auth-rules {:and [access/authenticated access/other-predicate]}
:current-user user
(ok user))
(def app
(-> app'
wrap-app-session))
(ns backend.restructure
(:require [compojure.api.meta :refer [restructure-param]]
[backend.session :refer [wrap-rule]]
[backend.access :as access]))
(defmethod restructure-param :auth-rules
[_ rule acc]
(update-in acc [:middlewares] conj [wrap-rule rule]))
(defmethod restructure-param :current-user
[_ binding acc]
(update-in acc [:letks] into [binding `(:identity ~'+compojure-api-request+)]))
(ns backend.session
(:require [ring.util.http-response :refer [unauthorized forbidden]]
[ring.middleware.session :refer [wrap-session]]
[buddy.auth :refer [authenticated? throw-unauthorized]]
[buddy.auth.backends.session :refer [session-backend]]
[buddy.auth.accessrules :refer [wrap-access-rules]]
[buddy.auth.middleware :refer [wrap-authentication wrap-authorization]]))
; FIXME: From config
(def cookie-name "backend-session")
(def auth-backend
; By default responds with 401 or 403 if unauthorized
(session-backend))
(defn wrap-app-session [handler]
(-> handler
(wrap-authorization auth-backend)
(wrap-authentication auth-backend)
(wrap-session {:cookie-name cookie-name})))
(defn access-error [req val]
(unauthorized val))
(defn wrap-rule [handler rule]
(-> handler
(wrap-access-rules {:rules [{:pattern #".*"
:handler rule}]
:on-error access-error})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment