init
						commit
						96e48825d2
					
				| @ -0,0 +1,10 @@ | ||||
| /target | ||||
| /lib | ||||
| /classes | ||||
| /checkouts | ||||
| pom.xml | ||||
| pom.xml.asc | ||||
| *.jar | ||||
| *.class | ||||
| /.lein-* | ||||
| /.nrepl-port | ||||
| @ -0,0 +1,8 @@ | ||||
| version: '2' | ||||
| 
 | ||||
| services: | ||||
|   db: | ||||
|     image: neo4j | ||||
|     ports: | ||||
|       - 7474:7474 | ||||
|       - 7687:7687 | ||||
| @ -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"]]}}) | ||||
| @ -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; | ||||
| } | ||||
| @ -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))))) | ||||
| @ -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)) | ||||
| @ -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))])) | ||||
| @ -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))) | ||||
| @ -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"]]]])) | ||||
| @ -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))))) | ||||
					Loading…
					
					
				
		Reference in New Issue
	
	 Josha von Gizycki
						Josha von Gizycki