Skip to content

Instantly share code, notes, and snippets.

@danielglauser
Last active March 24, 2016 16:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielglauser/cf6d1e8ddd162ee7dab8 to your computer and use it in GitHub Desktop.
Save danielglauser/cf6d1e8ddd162ee7dab8 to your computer and use it in GitHub Desktop.
(ns turbovote-admin-http-api.service
(:require [io.pedestal.http :as bootstrap]
[io.pedestal.http.route :as route]
[io.pedestal.http.route.definition :refer [defroutes]]
[io.pedestal.interceptor :refer [interceptor]]
[io.pedestal.impl.interceptor :refer [terminate]]
[ring.util.response :as ring-resp]
[turbovote.resource-config :refer [config]]
[pedestal-toolbox.params :refer :all]
[pedestal-toolbox.content-negotiation :refer :all]
[kehaar.core :as k]
[clojure.core.async :refer [go alt! timeout]]
[bifrost.core :as bifrost]
[bifrost.interceptors :as bifrost.i]
[clj-time.core :refer [minutes from-now]]
[buddy.auth.protocols :as proto]
[buddy.auth.backends.token :refer [jwe-backend]]
[buddy.sign.jwe :as jwe]
[turbovote-admin-http-api.channels :as channels]))
(def secret "my-secret-needs-to-be-32-charact")
(def encryption {:alg :a256kw :enc :a128gcm})
(def user-db #{{:username "ocho" :password "grande"
:company "TurboVote" :role :admin}})
(defn lookup-user [username password]
(first user-db))
(defn user->token-info [userid]
(select-keys (first user-db) [:username :company :role]))
(def ping
(interceptor
{:enter
(fn [ctx]
(assoc ctx :response (ring-resp/response "OK")))}))
(defn valid? [user]
true)
(defn make-token [minutes-to-live info]
(let [claims {:user info
:exp (-> minutes-to-live minutes from-now)}]
(jwe/encrypt claims secret encryption)))
(def login
(interceptor
{:enter
(fn [ctx]
(let [{:keys [username password]} ctx
valid-user (valid? (lookup-user username password))]
(if valid-user
(let [info (user->token-info username)
token (make-token 2 info)]
(assoc ctx :response {:status 200 :body {:token token}}))
(assoc ctx :response {:status 401
:body {:message "Wrong credentials"}}))))}))
(def auth-backend (jwe-backend {}))
(def check-auth
(interceptor
{:enter
(fn [{:keys [request] :as ctx}]
(prn "OHAI! check-auth:" request)
(let [req (try (some->> request
(proto/-parse auth-backend)
(proto/-authenticate auth-backend request))
(catch Exception ex
(println (.getMessage ex))
nil))]
(if req
(assoc ctx :request req)
(-> ctx
terminate
(assoc :response
{:status 401 :body {:message "Unauthorized"}})))))}))
(def profile
(interceptor
{:enter
(fn [{:keys [request] :as ctx}]
(assoc ctx :response
{:status 200 :body {:users user-db}}))}))
(defroutes routes
[[["/"
^:interceptors [(body-params)
(negotiate-response-content-type ["application/edn"
"application/transit+json"
"application/transit+msgpack"
"application/json"
"text/plain"])]
["/ping" {:get [:ping ping]}]
["/login" {:post [:login login]}]
["/users" ^:interceptors [check-auth] {:get profile}]]]])
(defn service []
{::env :prod
::bootstrap/router :linear-search
::bootstrap/routes routes
::bootstrap/resource-path "/public"
::bootstrap/allowed-origins (if (= :all (config [:server :allowed-origins]))
(constantly true)
(config [:server :allowed-origins]))
::bootstrap/host (config [:server :hostname])
::bootstrap/type :immutant
::bootstrap/port (config [:server :port])})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment