commit 96e48825d2a16696258e59bc62fa30f17887355f Author: Josha von Gizycki Date: Mon Mar 19 20:23:04 2018 +0100 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..22d6a48 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +/target +/lib +/classes +/checkouts +pom.xml +pom.xml.asc +*.jar +*.class +/.lein-* +/.nrepl-port diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b276deb --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,8 @@ +version: '2' + +services: + db: + image: neo4j + ports: + - 7474:7474 + - 7687:7687 diff --git a/project.clj b/project.clj new file mode 100644 index 0000000..617b6bb --- /dev/null +++ b/project.clj @@ -0,0 +1,14 @@ +(defproject wanijo "0.1.0-SNAPSHOT" + :description "FIXME: write description" + :url "http://example.com/FIXME" + :min-lein-version "2.0.0" + :dependencies [[org.clojure/clojure "1.8.0"] + [compojure "1.5.1"] + [ring/ring-defaults "0.2.1"] + [clojurewerkz/neocons "3.2.0"] + [hiccup "1.0.5"]] + :plugins [[lein-ring "0.9.7"]] + :ring {:handler wanijo.handler/app} + :profiles + {:dev {:dependencies [[javax.servlet/servlet-api "2.5"] + [ring/ring-mock "0.3.0"]]}}) diff --git a/resources/public/css/app.css b/resources/public/css/app.css new file mode 100644 index 0000000..58e2f76 --- /dev/null +++ b/resources/public/css/app.css @@ -0,0 +1,59 @@ +body { + font-family: sans-serif; +} + +.grid { + display: grid; + grid-template-columns: 20% 70% 10%; + grid-template-areas: + "header header header" + "nav main sidebar" + "footer footer footer"; + margin: auto; + max-width: 70%; + border-top: 1px solid #ccc; +} + +nav { + grid-area: nav; +} + +main { + grid-area: main; +} + +aside { + grid-area: sidebar; +} + +header, footer, main, nav, aside { + border-bottom: 1px solid #ccc; + padding: .5rem 1rem .2rem 1rem; +} + +header { + grid-area: header; +} + +footer { + grid-area: footer; +} + +.form-group { + display: flex; + margin-bottom: 1rem; +} + +.form-group label { + width: 30%; +} + +.form-group input, +.form-group select { + width: 70%; + padding: .1rem; +} + +.form-group input[type=submit] { + width: auto; +} diff --git a/src/wanijo/auth/handler.clj b/src/wanijo/auth/handler.clj new file mode 100644 index 0000000..c72a783 --- /dev/null +++ b/src/wanijo/auth/handler.clj @@ -0,0 +1,11 @@ +(ns wanijo.auth.handler + (:require [ring.util.response :as rur])) + +(defn login-check [req] + (let [{{:keys [uname pw]} :params} req] + (if (and (= uname "admin") + (= pw "pw")) + (-> (rur/redirect "/") + (assoc-in [:session :ident] uname)) + (-> (rur/redirect "/login") + (assoc :flash :invalid-credentials))))) diff --git a/src/wanijo/auth/routes.clj b/src/wanijo/auth/routes.clj new file mode 100644 index 0000000..ad7d7b9 --- /dev/null +++ b/src/wanijo/auth/routes.clj @@ -0,0 +1,8 @@ +(ns wanijo.auth.routes + (:require [compojure.core :refer [POST GET defroutes]] + [wanijo.auth.view :as auth-view] + [wanijo.auth.handler :as auth-handler])) + +(defroutes auth-routes + (GET "/login" [] auth-view/login) + (POST "/login-check" [] auth-handler/login-check)) diff --git a/src/wanijo/auth/view.clj b/src/wanijo/auth/view.clj new file mode 100644 index 0000000..b0fd145 --- /dev/null +++ b/src/wanijo/auth/view.clj @@ -0,0 +1,22 @@ +(ns wanijo.auth.view + (:require [hiccup.form :as hf] + [wanijo.view :refer [layout]] + [ring.util.anti-forgery :refer [anti-forgery-field]])) + +(defn login [req] + (layout + :authed? false + :content [[:h1 "Login"] + (hf/form-to + [:post "/login-check"] + [:dif.form-group + (:flash req)] + [:div.form-group + (hf/label "uname" "Username") + [:input#uname {:name "uname"}]] + [:div.form-group + (hf/label "pw" "Password") + (hf/password-field {:id "pw"} "pw")] + [:div.form-group + (hf/submit-button "Login")] + (anti-forgery-field))])) diff --git a/src/wanijo/handler.clj b/src/wanijo/handler.clj new file mode 100644 index 0000000..d607b23 --- /dev/null +++ b/src/wanijo/handler.clj @@ -0,0 +1,34 @@ +(ns wanijo.handler + (:require [compojure.core :refer :all] + [compojure.route :as route] + [ring.middleware.defaults :refer [wrap-defaults site-defaults]] + [ring.util.response :as rur] + [hiccup.page :as hp] + [wanijo.auth.routes :refer [auth-routes]] + [wanijo.view :refer [layout]])) + +(defn- home [_] + (layout :title "home")) + +(defroutes app-routes + (routes auth-routes) + (GET "/" [] home) + (route/not-found "Not Found")) + +(defn- wrap-login-redirect [handler] + (fn [req] + (let [ident (get-in req [:session :ident]) + uri (:uri req)] + (println ident (:session req)) + (if (and (nil? ident) + (not (or (clojure.string/ends-with? uri ".css") + (clojure.string/ends-with? uri ".js") + (= uri "/login-check") + (= uri "/login")))) + (rur/redirect "/login") + (handler req))))) + +(def app + (-> app-routes + wrap-login-redirect + (wrap-defaults site-defaults))) diff --git a/src/wanijo/view.clj b/src/wanijo/view.clj new file mode 100644 index 0000000..dbc1b73 --- /dev/null +++ b/src/wanijo/view.clj @@ -0,0 +1,23 @@ +(ns wanijo.view + (:require [hiccup.page :refer [html5]])) + +(defn layout + [& {:keys [authed? content title] + :or {authed? true + content [] + title "wan ijo"}}] + (html5 + [:head + [:meta {:charset "utf-8"}] + [:title title] + [:link {:rel "stylesheet" + :href "/css/app.css"}]] + [:body + [:section.grid + [:header + [:h1 "wan ijo"]] + [:nav (when authed? "nav")] + (vec (concat [:main] content)) + [:aside (when authed? "aside")] + [:footer + [:small "stuff with objects"]]]])) diff --git a/test/wanijo/handler_test.clj b/test/wanijo/handler_test.clj new file mode 100644 index 0000000..fc1560c --- /dev/null +++ b/test/wanijo/handler_test.clj @@ -0,0 +1,14 @@ +(ns wanijo.handler-test + (:require [clojure.test :refer :all] + [ring.mock.request :as mock] + [wanijo.handler :refer :all])) + +(deftest test-app + (testing "main route" + (let [response (app (mock/request :get "/"))] + (is (= (:status response) 200)) + (is (= (:body response) "Hello World")))) + + (testing "not-found route" + (let [response (app (mock/request :get "/invalid"))] + (is (= (:status response) 404)))))