diff options
author | Aspen Smith <grfn@gws.fyi> | 2024-02-12T03·00-0500 |
---|---|---|
committer | clbot <clbot@tvl.fyi> | 2024-02-14T19·37+0000 |
commit | 82ecd61f5c699cf3af6c4eadf47a1c52b1d696c6 (patch) | |
tree | 429c5e078528000591742ec3211bc768ae913a78 /users/aspen/bbbg/src/bbbg/web.clj | |
parent | 0ba476a4266015f278f18d74094299de74a5a111 (diff) |
chore(users): grfn -> aspen r/7511
Change-Id: I6c6847fac56f0a9a1a2209792e00a3aec5e672b9 Reviewed-on: https://cl.tvl.fyi/c/depot/+/10809 Autosubmit: aspen <root@gws.fyi> Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI Reviewed-by: lukegb <lukegb@tvl.fyi>
Diffstat (limited to 'users/aspen/bbbg/src/bbbg/web.clj')
-rw-r--r-- | users/aspen/bbbg/src/bbbg/web.clj | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/users/aspen/bbbg/src/bbbg/web.clj b/users/aspen/bbbg/src/bbbg/web.clj new file mode 100644 index 000000000000..f9755577a570 --- /dev/null +++ b/users/aspen/bbbg/src/bbbg/web.clj @@ -0,0 +1,140 @@ +(ns bbbg.web + (:require + [bbbg.discord.auth :as discord.auth :refer [wrap-discord-auth]] + [bbbg.handlers.attendee-checks :as attendee-checks] + [bbbg.handlers.attendees :as attendees] + [bbbg.handlers.core :refer [wrap-current-uri wrap-dynamic-auth]] + [bbbg.handlers.events :as events] + [bbbg.handlers.home :as home] + [bbbg.handlers.signup-form :as signup-form] + [bbbg.styles :refer [stylesheet]] + [bbbg.util.core :as u] + [bbbg.views.flash :refer [wrap-page-flash]] + [cambium.core :as log] + clj-time.coerce + [clojure.java.io :as io] + [clojure.spec.alpha :as s] + [com.stuartsierra.component :as component] + [compojure.core :refer [GET routes]] + [config.core :refer [env]] + [org.httpkit.server :as http-kit] + [ring.logger :refer [wrap-with-logger]] + [ring.middleware.flash :refer [wrap-flash]] + [ring.middleware.keyword-params :refer [wrap-keyword-params]] + [ring.middleware.multipart-params :refer [wrap-multipart-params]] + [ring.middleware.params :refer [wrap-params]] + [ring.middleware.resource :refer [wrap-resource]] + [ring.middleware.session :refer [wrap-session]] + [ring.middleware.session.cookie :refer [cookie-store]] + [ring.util.response :refer [content-type response]]) + (:import + java.util.Base64)) + +(s/def ::port pos-int?) + +(s/def ::cookie-secret + (s/and bytes? #(= 16 (count %)))) + +(s/def ::config + (s/merge + (s/keys :req [::port] + :opt [::cookie-secret + ::base-url]) + ::discord.auth/config)) + +(s/fdef make-server + :args (s/cat :config ::config)) + + +(defn- string->cookie-secret [raw] + (s/assert + ::cookie-secret + (when raw + (.decode (Base64/getDecoder) + (.getBytes raw "UTF-8"))))) + +(defn env->config [] + (s/assert + ::config + (u/remove-nils + (merge + {::port (:port env 8888) + ::cookie-secret (some-> env :cookie-secret string->cookie-secret) + ::base-url (:base-url env)} + (discord.auth/env->config))))) + +(defn dev-config [] + (s/assert + ::config + (merge + {::port 8888 + ::cookie-secret (into-array Byte/TYPE (repeat 16 0))} + (discord.auth/dev-config)))) + +;;; + +(defn app-routes [env] + (routes + (GET "/main.css" [] + (-> (response + (str + "\n/* begin base.css */\n" + (slurp (io/resource "base.css")) + "\n/* end base.css */\n" + stylesheet)) + (content-type "text/css"))) + + (attendees/attendees-routes env) + (attendee-checks/attendee-checks-routes env) + (signup-form/signup-form-routes env) + (events/events-routes env) + (home/home-routes env))) + +(defn middleware [app env] + (-> app + (wrap-resource "public") + (wrap-with-logger + {:log-fn + (fn [{:keys [level throwable message]}] + (log/log level {} throwable message))}) + wrap-current-uri + wrap-dynamic-auth + (wrap-discord-auth env) + wrap-keyword-params + wrap-multipart-params + wrap-params + wrap-page-flash + wrap-flash + (wrap-session {:store (cookie-store + {:key (:cookie-secret env) + :readers {'clj-time/date-time + clj-time.coerce/from-string}}) + :cookie-attrs {:same-site :lax}}))) + +(defn handler [env] + (-> (app-routes env) + (middleware env))) + +(defrecord WebServer [port cookie-secret db] + component/Lifecycle + (start [this] + (assoc this + ::shutdown-fn + (http-kit/run-server + (fn [r] ((handler this) r)) + {:port port}))) + (stop [this] + (if-let [shutdown-fn (::shutdown-fn this)] + (do (shutdown-fn :timeout 100) + (dissoc this ::shutdown-fn)) + this))) + +(defn make-server [{::keys [port cookie-secret] + :as env}] + (component/using + (map->WebServer + (merge + {:port port + :cookie-secret cookie-secret} + env)) + [:db])) |