diff --git a/backend/src/uxbox/api.clj b/backend/src/uxbox/api.clj index a5a251a934..59e16d801c 100644 --- a/backend/src/uxbox/api.clj +++ b/backend/src/uxbox/api.clj @@ -6,16 +6,22 @@ (ns uxbox.api (:require [mount.core :refer [defstate]] - [uxbox.config :as cfg] + [muuntaja.core :as m] [ring.adapter.jetty :as jetty] [reitit.ring :as ring] - [uxbox.api.middleware :refer [handler router-options]] + [reitit.dev.pretty :as pretty] + [uxbox.config :as cfg] + [uxbox.api.middleware :refer [handler middleware authorization-middleware]] [uxbox.api.auth :as api-auth] [uxbox.api.pages :as api-pages] [uxbox.api.users :as api-users] [uxbox.api.icons :as api-icons] [uxbox.api.images :as api-images] - [uxbox.api.projects :as api-projects])) + [uxbox.api.kvstore :as api-kvstore] + [uxbox.api.projects :as api-projects] + [uxbox.api.svg :as api-svg] + [uxbox.util.transit :as t])) + ;; --- Top Level Handlers @@ -33,15 +39,40 @@ ;; --- Routes +(def ^:private muuntaja-instance + (m/create (update-in m/default-options [:formats "application/transit+json"] + merge {:encoder-opts {:handlers t/+write-handlers+} + :decoder-opts {:handlers t/+read-handlers+}}))) + +(def ^:private router-options + {;;:reitit.middleware/transform dev/print-request-diffs + :exception pretty/exception + :data {:muuntaja muuntaja-instance + :middleware middleware}}) + (def routes (ring/router [["/media/*" (ring/create-resource-handler {:root "public/media"})] ["/static/*" (ring/create-resource-handler {:root "public/static"})] - ["/auth/login" {:post (handler #'api-auth/login)}] + ["/auth" + ["/login" {:post (handler #'api-auth/login)}] + ["/register" {:post (handler #'api-auth/register)}] + ["/recovery/:token" {:get (handler #'api-auth/register)}] + ["/recovery" {:post (handler #'api-auth/request-recovery) + :get (handler #'api-auth/recover-password)}]] - ["/api" {:middleware [api-auth/authorization-middleware]} + ["/api" {:middleware [authorization-middleware]} ["/echo" (handler #'welcome-api)] + + ;; KVStore + ["/kvstore/:key" {:put (handler #'api-kvstore/upsert) + :get (handler #'api-kvstore/retrieve) + :delete (handler #'api-kvstore/delete)}] + + ["/svg/parse" {:post (handler #'api-svg/parse)}] + + ;; Projects ["/projects" {:get (handler #'api-projects/list) :post (handler #'api-projects/create)}] ["/projects/by-token/:token" {:get (handler #'api-projects/get-by-share-token)}] diff --git a/backend/src/uxbox/api/auth.clj b/backend/src/uxbox/api/auth.clj index 7ff9a0baec..b124e11cd5 100644 --- a/backend/src/uxbox/api/auth.clj +++ b/backend/src/uxbox/api/auth.clj @@ -6,6 +6,7 @@ (ns uxbox.api.auth (:require [clojure.spec.alpha :as s] + [promesa.core :as p] [struct.core :as st] [uxbox.services :as sv] [uxbox.util.http :as http] @@ -18,19 +19,47 @@ :password [st/required st/string] :scope [st/required st/string]}}} [ctx] - (let [data (get-in ctx [:parameters :body]) - user @(sv/novelty (assoc data :type :login))] - (-> (http/no-content) - (assoc :session {:user-id (get user :id)})))) + (let [data (get-in ctx [:parameters :body])] + (->> (sv/novelty (assoc data :type :login)) + (p/map (fn [{:keys [id] :as user}] + (-> (http/no-content) + (assoc :session {:user-id id}))))))) -(defn authorization-middleware - [handler] - (fn - ([request] - (if-let [identity (get-in request [:session :user-id])] - (handler (assoc request :identity identity :user identity)) - (http/forbidden nil))) - ([request respond raise] - (if-let [identity (get-in request [:session :user-id])] - (handler (assoc request :identity identity :user identity) respond raise) - (respond (http/forbidden nil)))))) +(defn register + {:parameters {:body {:username [st/required st/string] + :email [st/required st/email] + :password [st/required st/string] + :fullname [st/required st/string]}}} + [{:keys [parameters]}] + (let [data (get parameters :body) + message (assoc data :type :register-profile)] + (->> (sv/novelty message) + (p/map http/ok)))) + +(defn request-recovery + {:parameters {:body {:username [st/required st/string]}}} + [{:keys [parameters]}] + (let [data (get parameters :body) + message (assoc data :type :request-profile-password-recovery)] + (->> (sv/novelty message) + (p/map (constantly (http/no-content)))))) + +(defn recover-password + {:parameters {:body {:token [st/required st/string] + :password [st/required st/string]}}} + [{:keys [parameters]}] + (let [data (get parameters :body) + message (assoc data :type :recover-profile-password)] + (->> (sv/novelty message) + (p/map (constantly (http/no-content)))))) + +(defn validate-recovery-token + {:parameters {:path {:token [st/required st/string]}}} + [{:keys [parameters]}] + (let [message {:type :validate-profile-password-recovery-token + :token (get-in parameters [:path :token])}] + (->> (sv/query message) + (p/map (fn [v] + (if v + (http/no-content) + (http/not-found ""))))))) diff --git a/backend/src/uxbox/api/kvstore.clj b/backend/src/uxbox/api/kvstore.clj new file mode 100644 index 0000000000..dbaa575f40 --- /dev/null +++ b/backend/src/uxbox/api/kvstore.clj @@ -0,0 +1,53 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) 2019 Andrey Antukh + +(ns uxbox.api.kvstore + (:refer-clojure :exclude [update]) + (:require [struct.core :as st] + [promesa.core :as p] + [uxbox.services :as sv] + [uxbox.media :as media] + [uxbox.util.http :as http] + [uxbox.util.spec :as us] + [uxbox.util.uuid :as uuid])) + +(defn retrieve + {:parameters {:path {:key [st/required st/string]}}} + [{:keys [user parameters] }] + (let [key (get-in parameters [:path :key]) + message {:key key + :type :retrieve-kvstore + :user user}] + (->> (sv/query message) + (p/map http/ok)))) + +(defn upsert + {:parameters {:path {:key [st/required st/string]} + :body {:value [st/required] + :version [st/number]}}} + [{:keys [user parameters]}] + (let [value (get-in parameters [:body :value]) + key (get-in parameters [:path :key]) + version (get-in parameters [:body :version]) + message {:key key + :version version + :value value + :type :update-kvstore + :user user}] + (->> (sv/novelty message) + (p/map http/ok)))) + +(defn delete + {:parameters {:path {:key [st/required st/string]}}} + [{:keys [user parameters]}] + (let [key (get-in parameters [:path :key]) + message {:key key + :type :delete-kvstore + :user user}] + (->> (sv/novelty message) + (p/map (constantly (http/no-content)))))) + + diff --git a/backend/src/uxbox/api/svg.clj b/backend/src/uxbox/api/svg.clj new file mode 100644 index 0000000000..4a74219cf4 --- /dev/null +++ b/backend/src/uxbox/api/svg.clj @@ -0,0 +1,19 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) 2016 Andrey Antukh + +(ns uxbox.api.svg + (:require [promesa.core :as p] + [uxbox.util.spec :as us] + [uxbox.services :as sv] + [uxbox.util.http :as http] + [uxbox.util.uuid :as uuid])) + +(defn parse + [{:keys [body] :as req}] + (let [message {:data (slurp body) + :type :parse-svg}] + (->> (sv/query message) + (p/map http/ok))))