diff --git a/project.clj b/project.clj index 89f3beb..86181f2 100644 --- a/project.clj +++ b/project.clj @@ -8,7 +8,8 @@ [gorillalabs/neo4j-clj "1.1.0"] [hiccup "1.0.5"] [buddy/buddy-hashers "1.3.0" - :exclusions [commons-codec]]] + :exclusions [commons-codec]] + [clj-time "0.14.4"]] :plugins [[lein-ring "0.9.7"]] :ring {:handler wanijo.handler/app} :profiles {:dev {:dependencies diff --git a/src/wanijo/attribute/domain.clj b/src/wanijo/attribute/domain.clj new file mode 100644 index 0000000..af06d62 --- /dev/null +++ b/src/wanijo/attribute/domain.clj @@ -0,0 +1,17 @@ +(ns wanijo.attribute.domain + (:require [clojure.spec.alpha :as spec] + [wanijo.framework.neo4j :as neo4j])) + +(neo4j/defquery + findy-by-schema + "MATCH (a:attribute)-->(s:schema) + WHERE s.uuid = {uuid} + RETURN a + ORDER BY a.name") + +(defn find-by-schema! [schema-uuid] + (->> + (neo4j/exec-query! + findy-by-schema + {:uuid schema-uuid}) + (map :a))) diff --git a/src/wanijo/framework/auth.clj b/src/wanijo/framework/auth.clj index abd587f..a70d679 100644 --- a/src/wanijo/framework/auth.clj +++ b/src/wanijo/framework/auth.clj @@ -19,7 +19,7 @@ (-> (redirect "/login") (assoc :flash :invalid-credentials))))) -(defn login [req] +(defn login! [req] (view/layout! :content [[:h1 "Kama ken"] @@ -37,7 +37,7 @@ (anti-forgery-field))])) (defroutes routes - (GET "/login" [] login) + (GET "/login" [] login!) (POST "/login-check" [] login-check!) (GET "/logout" [] (-> (redirect "/login") (assoc :session nil)))) diff --git a/src/wanijo/framework/neo4j.clj b/src/wanijo/framework/neo4j.clj index bfcbe49..6c62caa 100644 --- a/src/wanijo/framework/neo4j.clj +++ b/src/wanijo/framework/neo4j.clj @@ -1,6 +1,8 @@ (ns wanijo.framework.neo4j (:require [neo4j-clj.core :as db] - [wanijo.framework.devmode :as devmode]) + [wanijo.framework.devmode :as devmode] + [clj-time.format :as time-format] + [clj-time.local :as time-local]) (:import (java.util UUID))) (def conn @@ -23,10 +25,15 @@ (filter #(> (count %) 0)) (clojure.string/join \newline))) -(defn exec-query [qry params] +(defn exec-query! [qry params] (with-open [session (db/get-session @conn)] (devmode/send-to-bar (str (butiful-query qry) "
---Params---
" params)) (qry session params))) + +(defn now-str [] + (time-format/unparse + (time-format/formatters :basic-date-time) + (time-local/local-now))) diff --git a/src/wanijo/framework/repl.clj b/src/wanijo/framework/repl.clj index e441f49..cf9461f 100644 --- a/src/wanijo/framework/repl.clj +++ b/src/wanijo/framework/repl.clj @@ -11,7 +11,7 @@ SET n.uuid = {uuid}") (defn create-user! [ident pw] - (neo4j/exec-query + (neo4j/exec-query! create-user {:ident ident :pw (hashers/derive pw) diff --git a/src/wanijo/framework/time.clj b/src/wanijo/framework/time.clj new file mode 100644 index 0000000..b9f0fa8 --- /dev/null +++ b/src/wanijo/framework/time.clj @@ -0,0 +1,2 @@ +(ns wanijo.framework.time + (:require [clj-time.core :as t])) diff --git a/src/wanijo/framework/view.clj b/src/wanijo/framework/view.clj index d7eb809..c17d6a0 100644 --- a/src/wanijo/framework/view.clj +++ b/src/wanijo/framework/view.clj @@ -36,7 +36,7 @@ (when authed? [:section.header-content (btnlink "/schema" "Jaki ijo" "header-content__link") - (btnlink "/logout" "Lape" "header-content__link")])] + (btnlink "/logout" "Lape!" "header-content__link")])] [:nav (when authed? "nav")] (vec (concat [:main] content)) [:aside (when authed? "aside")] diff --git a/src/wanijo/schema/domain.clj b/src/wanijo/schema/domain.clj index b442b0d..332c468 100644 --- a/src/wanijo/schema/domain.clj +++ b/src/wanijo/schema/domain.clj @@ -6,10 +6,8 @@ (spec/and string? not-empty)) (spec/def ::created-at - (spec/or :int (spec/and int? - #(> % 20000101000000)) - :str (spec/and string? - #(re-matches #"\d{4}\d{2}\d{2}\d{2}\d{2}\d{2}" %)))) + (spec/and string? + #(re-matches #"\d{4}\d{2}\d{2}T\d{2}\d{2}\d{2}\.\d{3}Z" %))) (neo4j/defquery all-created-by @@ -19,10 +17,11 @@ ORDER BY s.name") (defn all-created-by! [user-uuid] - (map :s - (neo4j/exec-query - all-created-by - {:uuid user-uuid}))) + (->> + (neo4j/exec-query! + all-created-by + {:uuid user-uuid}) + (map :s))) (neo4j/defquery create-new @@ -31,28 +30,63 @@ CREATE (s:schema)-[:created_by]->(u) SET s.name = {name} SET s.uuid = {s_uuid} + SET s.created_at = {created_at} RETURN s") (defn create-new! [name user-uuid] (->> - (neo4j/exec-query + (neo4j/exec-query! create-new {:u_uuid user-uuid :name name - :s_uuid (neo4j/uuid)}) + :s_uuid (neo4j/uuid) + :created_at (neo4j/now-str)}) first :uuid)) (neo4j/defquery - find-by-id! + find-by-uuid "MATCH (s:schema) WHERE s.uuid = {uuid} RETURN s") (defn find-by-uuid! [uuid] (->> - (neo4j/exec-query - find-by-id! + (neo4j/exec-query! + find-by-uuid {:uuid uuid}) first :s)) + +(neo4j/defquery + schema-creator + "MATCH (s:schema)-->(u:user) + WHERE s.uuid = {uuid} + RETURN u.uuid as uuid") + +(defn find-schema-creator! [uuid] + (->> + (neo4j/exec-query! + schema-creator + {:uuid uuid}) + first + :uuid)) + +(defn can-user-modify? [schema-uuid user-uuid] + (let [creator (find-schema-creator! schema-uuid)] + (= creator user-uuid))) + +(neo4j/defquery + delete + "MATCH (s:schema) + WHERE s.uuid = {uuid} + OPTIONAL MATCH (s)--(a:attribute) + DELETE a + WITH s + MATCH (s)-[c]-() + DELETE c, s") + +(defn delete! [uuid] + (neo4j/exec-query! + delete + {:uuid uuid})) diff --git a/src/wanijo/schema/routes.clj b/src/wanijo/schema/routes.clj index 20fd9c6..decb183 100644 --- a/src/wanijo/schema/routes.clj +++ b/src/wanijo/schema/routes.clj @@ -1,10 +1,11 @@ (ns wanijo.schema.routes - (:require [compojure.core :refer [defroutes GET POST]] + (:require [compojure.core :refer [defroutes GET POST DELETE]] [ring.util.response :as resp] [wanijo.framework.view :as view] [wanijo.framework.form :as form] [wanijo.schema.domain :as domain] - [wanijo.schema.view :as view-schema])) + [wanijo.schema.view :as view-schema] + [wanijo.attribute.domain :as attr-domain])) (defn new! [req] (if (form/valid? view-schema/new-form req) @@ -16,12 +17,20 @@ (view-schema/overview! req))) (defn show-schema! [uuid session] - (println uuid session) (view-schema/show-schema! (domain/find-by-uuid! uuid) + (attr-domain/find-by-schema! uuid) session)) +(defn delete-schema! [uuid session] + (if (domain/can-user-modify? uuid (:uuid session)) + (do + (domain/delete! uuid) + (resp/redirect "/schema")) + {:status 403})) + (defroutes routes (GET "/schema" [] view-schema/overview!) (GET "/schema/:uuid" [uuid :as req] (show-schema! uuid (:session req))) - (POST "/schema/new" [] new!)) + (POST "/schema/new" [] new!) + (DELETE "/schema/:uuid/delete" [uuid :as req] (delete-schema! uuid (:session req)))) diff --git a/src/wanijo/schema/view.clj b/src/wanijo/schema/view.clj index 3a518c2..cacb046 100644 --- a/src/wanijo/schema/view.clj +++ b/src/wanijo/schema/view.clj @@ -8,7 +8,7 @@ (def new-form {:fields {:schema-name {:label "Nimi" :required true - :spec :wanijo.domain.schema/name}}}) + :spec ::domain/name}}}) (defn overview! [req] (let [session (:session req) @@ -37,8 +37,19 @@ (hform/submit-button "Pali") (anti-forgery-field))]))) -(defn show-schema! [schema session] +(defn show-schema! [schema attrs session] (view/layout! :session session :content - [[:h1 "Jaki ijo " (:name schema)]])) + [[:h1 "Jaki ijo " (:name schema)] + (hform/form-to + [:post "/schema/edit"]) + [:h2 "Lili wan e jaki ijo"] + [:ul + (for [attr attrs] + [:li (:name attr)])] + [:h2 "Mute pali"] + (hform/form-to + [:delete (str "/schema/" (:uuid schema) "/delete")] + (anti-forgery-field) + (hform/submit-button "Pakala!"))])) diff --git a/src/wanijo/user/domain.clj b/src/wanijo/user/domain.clj index ac8c543..0572fdd 100644 --- a/src/wanijo/user/domain.clj +++ b/src/wanijo/user/domain.clj @@ -9,7 +9,7 @@ (defn find! [ident] (->> - (neo4j/exec-query + (neo4j/exec-query! find-user {:ident ident}) first