From ec04bb4160547aca6be8f05bb0b67e3fa42e67e2 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 2 Apr 2020 17:04:00 +0200 Subject: [PATCH] :tada: Add backend code for viewer page. --- .../resources/migrations/0003.projects.sql | 2 - backend/src/uxbox/services/init.clj | 2 +- backend/src/uxbox/services/queries/files.clj | 20 ++++-- .../src/uxbox/services/queries/projects.clj | 40 ++++++----- .../uxbox/services/queries/recent_files.clj | 6 +- backend/src/uxbox/services/queries/view.clj | 67 +++++++++++++++++++ 6 files changed, 109 insertions(+), 28 deletions(-) create mode 100644 backend/src/uxbox/services/queries/view.clj diff --git a/backend/resources/migrations/0003.projects.sql b/backend/resources/migrations/0003.projects.sql index 29bfa24e5..3b3516b1f 100644 --- a/backend/resources/migrations/0003.projects.sql +++ b/backend/resources/migrations/0003.projects.sql @@ -14,8 +14,6 @@ CREATE TABLE project ( CREATE INDEX project__team_id__idx ON project(team_id); - - CREATE TABLE project_profile_rel ( profile_id uuid NOT NULL REFERENCES profile(id) ON DELETE CASCADE, project_id uuid NOT NULL REFERENCES project(id) ON DELETE CASCADE, diff --git a/backend/src/uxbox/services/init.clj b/backend/src/uxbox/services/init.clj index 02e60dd56..3a46deed7 100644 --- a/backend/src/uxbox/services/init.clj +++ b/backend/src/uxbox/services/init.clj @@ -22,7 +22,7 @@ (require 'uxbox.services.queries.pages) (require 'uxbox.services.queries.profile) (require 'uxbox.services.queries.recent-files) - ;; (require 'uxbox.services.queries.user-attrs) + (require 'uxbox.services.queries.view) ) (defn- load-mutation-services diff --git a/backend/src/uxbox/services/queries/files.clj b/backend/src/uxbox/services/queries/files.clj index 3b50e9429..6e28c4dca 100644 --- a/backend/src/uxbox/services/queries/files.clj +++ b/backend/src/uxbox/services/queries/files.clj @@ -192,6 +192,16 @@ inner join file as f on (p.id = f.project_id) where f.id = $1") +(defn retrieve-file + [conn id] + (-> (db/query-one conn [sql:file id]) + (p/then' su/raise-not-found-if-nil) + (p/then' decode-row))) + +(defn retrieve-file-users + [conn id] + (db/query conn [sql:file-users id])) + (s/def ::file-with-users (s/keys :req-un [::profile-id ::id])) @@ -199,10 +209,8 @@ [{:keys [profile-id id] :as params}] (db/with-atomic [conn db/pool] (check-edition-permissions! conn profile-id id) - (p/let [file (-> (db/query-one conn [sql:file id]) - (p/then' su/raise-not-found-if-nil) - (p/then' decode-row)) - users (db/query conn [sql:file-users id])] + (p/let [file (retrieve-file conn id) + users (retrieve-file-users conn id)] (assoc file :users users)))) (s/def ::file @@ -212,9 +220,7 @@ [{:keys [profile-id id] :as params}] (db/with-atomic [conn db/pool] (check-edition-permissions! conn profile-id id) - (-> (db/query-one conn [sql:file id]) - (p/then' su/raise-not-found-if-nil) - (p/then' decode-row)))) + (retrieve-file conn id))) ;; --- Query: Project Files diff --git a/backend/src/uxbox/services/queries/projects.clj b/backend/src/uxbox/services/queries/projects.clj index 45d495b4c..cfe5eb7d9 100644 --- a/backend/src/uxbox/services/queries/projects.clj +++ b/backend/src/uxbox/services/queries/projects.clj @@ -16,13 +16,20 @@ (declare decode-row) +;; TODO: this module should be refactored for to separate the +;; permissions checks from the main queries in the same way as pages +;; and files. This refactor will make this functions more "reusable" +;; and will prevent duplicating queries on `queries.view` ns as +;; example. + ;; --- Query: Projects (def ^:private sql:projects "with projects as ( select p.*, - (select count(*) from file as f - where f.project_id = p.id and deleted_at is null) as file_count + (select count(*) from file as f + where f.project_id = p.id + and deleted_at is null) as file_count from project as p inner join team_profile_rel as tpr on (tpr.team_id = p.team_id) where tpr.profile_id = $1 @@ -32,8 +39,9 @@ tpr.can_edit = true) union select p.*, - (select count(*) from file as f - where f.project_id = p.id and deleted_at is null) + (select count(*) from file as f + where f.project_id = p.id + and deleted_at is null) from project as p inner join project_profile_rel as ppr on (ppr.project_id = p.id) where ppr.profile_id = $1 @@ -49,11 +57,11 @@ (def ^:private sql:project-by-id "select p.* - from project as p - inner join project_profile_rel as ppr on (ppr.project_id = p.id) - where ppr.profile_id = $1 - and p.id = $2 - and p.deleted_at is null + from project as p + inner join project_profile_rel as ppr on (ppr.project_id = p.id) + where ppr.profile_id = $1 + and p.id = $2 + and p.deleted_at is null and (ppr.is_admin = true or ppr.is_owner = true or ppr.can_edit = true)") @@ -68,16 +76,18 @@ (s/def ::project-by-id (s/keys :req-un [::profile-id ::project-id])) -(defn projects-by-team [profile-id team-id] - (db/query db/pool [sql:projects profile-id team-id])) +(defn retrieve-projects + [conn profile-id team-id] + (db/query conn [sql:projects profile-id team-id])) -(defn project-by-id [profile-id project-id] - (db/query-one db/pool [sql:project-by-id profile-id project-id])) +(defn retrieve-project + [conn profile-id id] + (db/query-one conn [sql:project-by-id profile-id id])) (sq/defquery ::projects-by-team [{:keys [profile-id team-id]}] - (projects-by-team profile-id team-id)) + (retrieve-projects db/pool profile-id team-id)) (sq/defquery ::project-by-id [{:keys [profile-id project-id]}] - (project-by-id profile-id project-id)) + (retrieve-project db/pool profile-id project-id)) diff --git a/backend/src/uxbox/services/queries/recent_files.clj b/backend/src/uxbox/services/queries/recent_files.clj index 9e3338cf5..b99b83128 100644 --- a/backend/src/uxbox/services/queries/recent_files.clj +++ b/backend/src/uxbox/services/queries/recent_files.clj @@ -14,8 +14,8 @@ [uxbox.db :as db] [uxbox.common.spec :as us] [uxbox.services.queries :as sq] - [uxbox.services.queries.projects :refer [ projects-by-team ]] - [uxbox.services.queries.files :refer [ decode-row ]])) + [uxbox.services.queries.projects :refer [retrieve-projects]] + [uxbox.services.queries.files :refer [decode-row]])) (def ^:private sql:project-files-recent "select distinct @@ -51,7 +51,7 @@ (sq/defquery ::recent-files [{:keys [profile-id team-id]}] - (-> (projects-by-team profile-id team-id) + (-> (retrieve-projects db/pool profile-id team-id) ;; Retrieve for each proyect the 5 more recent files (p/then #(p/all (map (partial recent-by-project profile-id) %))) ;; Change the structure so it's a map with project-id as keys diff --git a/backend/src/uxbox/services/queries/view.clj b/backend/src/uxbox/services/queries/view.clj new file mode 100644 index 000000000..ee6c0f608 --- /dev/null +++ b/backend/src/uxbox/services/queries/view.clj @@ -0,0 +1,67 @@ +;; 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/. +;; +;; This Source Code Form is "Incompatible With Secondary Licenses", as +;; defined by the Mozilla Public License, v. 2.0. +;; +;; Copyright (c) 2020 UXBOX Labs SL + +(ns uxbox.services.queries.view + (:require + [clojure.spec.alpha :as s] + [promesa.core :as p] + [promesa.exec :as px] + [uxbox.common.exceptions :as ex] + [uxbox.common.spec :as us] + [uxbox.db :as db] + [uxbox.media :as media] + [uxbox.images :as images] + [uxbox.services.queries.pages :as pages] + [uxbox.services.queries.files :as files] + [uxbox.services.queries :as sq] + [uxbox.services.util :as su] + [uxbox.util.blob :as blob] + [uxbox.util.data :as data] + [uxbox.util.uuid :as uuid] + [vertx.core :as vc])) + +;; --- Helpers & Specs + +(s/def ::id ::us/uuid) +(s/def ::page-id ::us/uuid) + +;; --- Query: Viewer Bundle + +(def ^:private + sql:project + "select p.id, p.name + from project as p + where p.id = $1 + and p.deleted_at is null") + +(defn- retrieve-project + [conn id] + (db/query-one conn [sql:project id])) + +(s/def ::viewer-bundle-by-page-id + (s/keys :req-un [::profile-id ::page-id])) + +(sq/defquery ::viewer-bundle-by-page-id + [{:keys [profile-id page-id]}] + (db/with-atomic [conn db/pool] + (p/let [page (pages/retrieve-page conn page-id) + file (files/retrieve-file conn (:file-id page)) + users (files/retrieve-file-users conn (:file-id page)) + images (files/retrieve-file-images conn page) + project (retrieve-project conn (:project-id file))] + (files/check-edition-permissions! conn profile-id (:file-id page)) + {:page page + :file file + :users users + :images images + :project project}))) + +;; TODO: bundle by share link + +