Skip to content

Commit

Permalink
Migrated to pedestal and pedestal-route
Browse files Browse the repository at this point in the history
  • Loading branch information
tonsky committed May 3, 2019
1 parent acdf672 commit 1414774
Show file tree
Hide file tree
Showing 10 changed files with 358 additions and 299 deletions.
29 changes: 15 additions & 14 deletions deps.edn
Original file line number Original file line Diff line number Diff line change
@@ -1,16 +1,18 @@
{:deps {:deps
{org.clojure/clojure {:mvn/version "1.10.1-beta2"} {org.clojure/clojure {:mvn/version "1.10.1-beta2"}
com.stuartsierra/component {:mvn/version "0.4.0"} com.stuartsierra/component {:mvn/version "0.4.0"}
org.clojure/data.xml {:mvn/version "0.2.0-alpha6"} ring/ring-core {:mvn/version "1.6.3"}
ring/ring-core {:mvn/version "1.6.3"} org.immutant/web {:mvn/version "2.1.10"}
org.immutant/web {:mvn/version "2.1.10"} io.pedestal/pedestal.service {:mvn/version "0.5.5" :exclusions [cheshire/cheshire]}
compojure {:mvn/version "1.6.1"} io.pedestal/pedestal.route {:mvn/version "0.5.5"}
rum {:mvn/version "0.11.3"} io.pedestal/pedestal.immutant {:mvn/version "0.5.5" :exclusions [javax.servlet/javax.servlet-api]}
com.cognitect/transit-clj {:mvn/version "0.8.313"} rum {:mvn/version "0.11.3"}
clj-http {:mvn/version "3.9.1"} com.cognitect/transit-clj {:mvn/version "0.8.313"}
cheshire {:mvn/version "5.8.1"} ; for clj-http :as :json org.clojure/data.xml {:mvn/version "0.2.0-alpha6"}
cljs-drag-n-drop {:mvn/version "0.1.0"} clj-http {:mvn/version "3.9.1"}
com.cognitect/transit-cljs {:mvn/version "0.8.256"}} cheshire {:mvn/version "5.8.1"} ; for clj-http :as :json
cljs-drag-n-drop {:mvn/version "0.1.0"}
com.cognitect/transit-cljs {:mvn/version "0.8.256"}}
:paths ["src" "resources"] :paths ["src" "resources"]
:aliases :aliases
{:dev {:jvm-opts ["-ea" "--add-opens" "java.base/sun.nio.ch=ALL-UNNAMED"] {:dev {:jvm-opts ["-ea" "--add-opens" "java.base/sun.nio.ch=ALL-UNNAMED"]
Expand All @@ -21,5 +23,4 @@
:uberjar {:extra-paths ["target/uberjar"]} :uberjar {:extra-paths ["target/uberjar"]}
:package {:extra-paths ["package"] :package {:extra-paths ["package"]
:extra-deps {org.clojure/clojurescript {:mvn/version "1.10.520"} :extra-deps {org.clojure/clojurescript {:mvn/version "1.10.520"}
uberdeps {:mvn/version "0.1.0"}}} uberdeps {:mvn/version "0.1.0"}}}}}
}}
6 changes: 0 additions & 6 deletions dev.cljs.edn

This file was deleted.

28 changes: 18 additions & 10 deletions dev/grumpy/figwheel.clj
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,18 +4,26 @@
[cljs.stacktrace] [cljs.stacktrace]
[figwheel.main.api :as fig])) [figwheel.main.api :as fig]))


(defrecord Figwheel [opts]
(defrecord Figwheel []
component/Lifecycle component/Lifecycle
(start [this] (start [this]
(println "[Figwheel] Starting figwheel build" (:build opts)) (println "[Figwheel] Starting figwheel build")
(fig/start {:mode :serve (fig/start
:rebel-readline false {:mode :serve
:cljs-devtools false :rebel-readline false
:helpful-classpaths false :cljs-devtools false
:open-url false} :helpful-classpaths false
(:build opts)) :open-url false}
{:id "dev"
:config {:watch-dirs ["src"]
:css-dirs ["resources/static"]}
:options {:main 'grumpy.editor
:output-to "target/resources/static/editor.js"
:output-dir "target/resources/static/editor"
:asset-path "/static/editor"}})
this) this)
(stop [this] (stop [this]
(println "[Figwheel] Stopping figwheel build" (:build opts)) (println "[Figwheel] Stopping figwheel build")
(fig/stop (:build opts)) (fig/stop "dev")
this)) this))
2 changes: 1 addition & 1 deletion dev/user.clj
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@




(reset! *figwheel (reset! *figwheel
(component/start (figwheel/map->Figwheel {:opts {:build "dev"}}))) (component/start (figwheel/->Figwheel)))




(reset) (reset)
Expand Down
2 changes: 1 addition & 1 deletion resources/static/authors.css
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ body.dragover { background-color: #F0FCF0; }
.autosave-clean { border: 1px solid #ccc; background: #ccc; } .autosave-clean { border: 1px solid #ccc; background: #ccc; }
.autosave-dirty { border: 1px solid #aaa; background: #fff; } .autosave-dirty { border: 1px solid #aaa; background: #fff; }
.autosave-saving { border: 1px solid #aaa; background: #eee; } .autosave-saving { border: 1px solid #aaa; background: #eee; }
.autosave-error { border: 1px solid #aaa; background: #c33; } .autosave-error { border: 1px solid #c33; background: #c33; }


.edit-post_picture { min-height: 60px; position: relative; } .edit-post_picture { min-height: 60px; position: relative; }
.edit-post_picture-empty { background-image: url("/static/upload.svg"); background-color: #999; background-repeat: no-repeat; background-position: center center; opacity: 0.2; } .edit-post_picture-empty { background-image: url("/static/upload.svg"); background-color: #999; background-repeat: no-repeat; background-position: center center; opacity: 0.2; }
Expand Down
224 changes: 122 additions & 102 deletions src/grumpy/auth.clj
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
(:require (:require
[rum.core :as rum] [rum.core :as rum]
[clojure.set :as set] [clojure.set :as set]
[grumpy.core :as grumpy] [clojure.string :as str]
[clojure.java.io :as io] [clojure.java.io :as io]
[compojure.core :as compojure]
[clojure.java.shell :as shell] [clojure.java.shell :as shell]
[io.pedestal.http.route :as route]
[ring.middleware.session :as session] [ring.middleware.session :as session]
[ring.middleware.session.cookie :as session.cookie]) [io.pedestal.interceptor :as interceptor]
[io.pedestal.http.body-params :as body-params]
[ring.middleware.session.cookie :as session.cookie]
[io.pedestal.http.ring-middlewares :as middlewares]
[grumpy.core :as grumpy]
[grumpy.routes :as routes])
(:import (:import
[java.security SecureRandom])) [java.security SecureRandom]))


Expand Down Expand Up @@ -67,45 +72,54 @@
(:value token))))) (:value token)))))




(defn- expire-session [handler] (def expire-session
(fn [req] {:name ::expire-session
(let [created (:created (:session req))] :enter
(if (and (some? created) (fn [ctx]
(> (grumpy/age created) session-ttl-ms)) (let [created (-> ctx :request :session :created)]
(handler (dissoc req :session)) (if (and (some? created)
(handler req))))) (> (grumpy/age created) session-ttl-ms))

(update ctx :request dissoc :session)

ctx)))})
(defn force-user [handler]
(fn [req]
(if-some [u grumpy/forced-user] (def force-user
(some-> req {:name ::force-user
(assoc-in [:session :user] u) :enter
(handler) (fn [ctx]
(assoc :cookies { "grumpy_user" { :value u }} (if-some [u grumpy/forced-user]
:session { :user u (assoc-in ctx [:request :session :user] u)
:created (grumpy/now) })) ctx))
(handler req)))) :leave
(fn [ctx]
(if-some [u grumpy/forced-user]
(update ctx :response assoc :cookies {"grumpy_user" {:value u}}
:session {:user u
:created (grumpy/now)})
ctx))})




(defn wrap-session [handler] (def session
(-> handler (middlewares/session
(expire-session) {:store (session.cookie/cookie-store {:key cookie-secret})
(force-user) :cookie-name "grumpy_session"
(session/wrap-session :cookie-attrs {:http-only true
{ :store (session.cookie/cookie-store { :key cookie-secret }) :secure (not grumpy/dev?)}}))
:cookie-name "grumpy_session"
:cookie-attrs { :http-only true
:secure (not grumpy/dev?) }}))) (def populate-session [session force-user expire-session])




(defn user [req] (defn user [req]
(get-in req [:session :user])) (get-in req [:session :user]))




(defn check-session [req] (def require-user
(when (nil? (user req)) {:name ::require-user
(grumpy/redirect "/forbidden" { :redirect-url (:uri req) }))) :enter (fn [{req :request :as ctx}]
(if (nil? (user req))
(assoc ctx :response (grumpy/redirect "/forbidden" {:redirect-url (:uri req)}))
ctx))})




(rum/defc email-sent-page [message] (rum/defc email-sent-page [message]
Expand All @@ -116,72 +130,78 @@




(rum/defc forbidden-page [redirect-url email] (rum/defc forbidden-page [redirect-url email]
(grumpy/page { :title "Log in" (grumpy/page {:title "Log in"
:styles ["authors.css"] } :styles ["authors.css"]}
[:form.forbidden [:form.forbidden
{ :action "/send-email" {:action "/send-email"
:method "post" } :method "post" }
[:.form_row [:.form_row
[:input { :type "text" [:input {:type "text"
:name "email" :name "email"
:placeholder "E-mail" :placeholder "E-mail"
:autofocus true :autofocus true
:value email }] :value email}]
[:input { :type "hidden" :name "redirect-url" :value redirect-url }]] [:input {:type "hidden" :name "redirect-url" :value redirect-url}]]
[:.form_row [:.form_row
[:button "Send email"]]])) [:button "Send email"]]]))




(compojure/defroutes routes (defn handle-forbidden [{:keys [query-params cookies]}]
(compojure/GET "/forbidden" [:as req] (let [user (get-in cookies ["grumpy_user" :value])
(let [redirect-url (get (:params req) "redirect-url") email (:email (grumpy/author-by :user user))]
user (get-in (:cookies req) ["grumpy_user" :value]) (grumpy/html-response (forbidden-page (:redirect-url query-params) email))))
email (:email (grumpy/author-by :user user))]
(grumpy/html-response (forbidden-page redirect-url email))))

(defn handle-send-email [{:keys [form-params] :as req}]
(compojure/GET "/authenticate" [:as req] ;; ?email=...&token=...&redirect-url=... (let [email (:email form-params)
(let [email (get (:params req) "email") user (:user (grumpy/author-by :email email))]
user (:user (grumpy/author-by :email email)) (cond
token (get (:params req) "token") (nil? (grumpy/author-by :email email))
redirect-url (get (:params req) "redirect-url")] (grumpy/redirect "/email-sent" {:message (str "You aren't the author, " email)})
(if (= token (get-token email))
(do (some? (get-token email))
(swap! *tokens dissoc email) (grumpy/redirect "/email-sent" {:message (str "Emailed link is still valid, " user)})
(assoc
(grumpy/redirect redirect-url) :else
:cookies { "grumpy_user" { :value user }} (let [token (gen-token)
:session { :user user redirect-url (:redirect-url form-params)
:created (grumpy/now) })) link (grumpy/url (str grumpy/hostname "/authenticate")
{ :status 403 {:email email
:body "403 Bad token" }))) :token token

:redirect-url redirect-url})]
(compojure/GET "/logout" [:as req] (swap! *tokens assoc email { :value token :created (grumpy/now) })
(assoc (send-email!
(grumpy/redirect "/") {:to email
:session nil)) :subject (str "Log into Grumpy " (grumpy/format-date (grumpy/now)))

:body (str "<html><div style='text-align: center;'><a href=\"" link "\" style='display: inline-block; font-size: 16px; padding: 0.5em 1.75em; background: #c3c; color: white; text-decoration: none; border-radius: 4px;'>Login now!</a></div></html>")})
(compojure/POST "/send-email" [:as req] (grumpy/redirect "/email-sent" {:message (str "Check your email, " user)})))))
(let [params (:params req)
email (get params "email")
user (:user (grumpy/author-by :email email))] (defn handle-email-sent [{:keys [query-params]}]
(cond (grumpy/html-response (email-sent-page (:message query-params))))
(nil? (grumpy/author-by :email email))
(grumpy/redirect "/email-sent" { :message (str "You aren't the author, " email) })
(some? (get-token email)) (defn handle-authenticate [{:keys [query-params]}] ;; ?email=...&token=...&redirect-url=...
(grumpy/redirect "/email-sent" { :message (str "Emailed link is still valid, " user) }) (let [email (:email query-params)
:else user (:user (grumpy/author-by :email email))
(let [token (gen-token) redirect-url (if (str/blank? (:redirect-url query-params))
redirect-url (get params "redirect-url") "/"
link (grumpy/url (str grumpy/hostname "/authenticate") (:redirect-url query-params))]
{ :email email (if (= (:token query-params) (get-token email))
:token token (do
:redirect-url redirect-url })] (swap! *tokens dissoc email)
(swap! *tokens assoc email { :value token :created (grumpy/now) }) (assoc (grumpy/redirect redirect-url)
(send-email! :cookies {"grumpy_user" {:value user}}
{ :to email :session {:user user
:subject (str "Log into Grumpy " (grumpy/format-date (grumpy/now))) :created (grumpy/now)}))
:body (str "<html><div style='text-align: center;'><a href=\"" link "\" style='display: inline-block; font-size: 16px; padding: 0.5em 1.75em; background: #c3c; color: white; text-decoration: none; border-radius: 4px;'>Login now!</a></div></html>") }) {:status 403
(grumpy/redirect "/email-sent" { :message (str "Check your email, " user) }))))) :body "403 Bad token"})))


(compojure/GET "/email-sent" [:as req]
(grumpy/html-response (email-sent-page (get-in req [:params "message"]))))) (def routes
(routes/expand
[:get "/forbidden" populate-session route/query-params `handle-forbidden]
[:post "/send-email" populate-session (body-params/body-params) `handle-send-email]
[:get "/email-sent" populate-session route/query-params `handle-email-sent]
[:get "/authenticate" populate-session route/query-params `handle-authenticate]
[:get "/logout" populate-session (fn [_] (assoc (grumpy/redirect "/") :session nil))]))
Loading

0 comments on commit 1414774

Please sign in to comment.