From 8cb2f27de8246d23423605ec1ba4176bd63eee68 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 22 Dec 2025 18:21:45 +0100 Subject: [PATCH] :recycle: Move file permissions to binfile common ns --- backend/src/app/binfile/common.clj | 75 +++++++++++++++++++++ backend/src/app/rpc/commands/files.clj | 88 +++---------------------- backend/src/app/rpc/commands/fonts.clj | 3 +- backend/src/app/rpc/commands/viewer.clj | 2 +- 4 files changed, 86 insertions(+), 82 deletions(-) diff --git a/backend/src/app/binfile/common.clj b/backend/src/app/binfile/common.clj index cf8508caa0..f57b8775df 100644 --- a/backend/src/app/binfile/common.clj +++ b/backend/src/app/binfile/common.clj @@ -331,6 +331,81 @@ (set/difference cfeat/backend-only-features)) #{})))) +(defn check-file-exists + [cfg id & {:keys [include-deleted?] + :or {include-deleted? false} + :as options}] + (db/get-with-sql cfg [sql:get-minimal-file id] + {:db/remove-deleted (not include-deleted?)})) + +(def ^:private sql:file-permissions + "select fpr.is_owner, + fpr.is_admin, + fpr.can_edit + from file_profile_rel as fpr + inner join file as f on (f.id = fpr.file_id) + where fpr.file_id = ? + and fpr.profile_id = ? + union all + select tpr.is_owner, + tpr.is_admin, + tpr.can_edit + from team_profile_rel as tpr + inner join project as p on (p.team_id = tpr.team_id) + inner join file as f on (p.id = f.project_id) + where f.id = ? + and tpr.profile_id = ? + union all + select ppr.is_owner, + ppr.is_admin, + ppr.can_edit + from project_profile_rel as ppr + inner join file as f on (f.project_id = ppr.project_id) + where f.id = ? + and ppr.profile_id = ?") + +(defn- get-file-permissions* + [conn profile-id file-id] + (when (and profile-id file-id) + (db/exec! conn [sql:file-permissions + file-id profile-id + file-id profile-id + file-id profile-id]))) + +(defn get-file-permissions + ([conn profile-id file-id] + (let [rows (get-file-permissions* conn profile-id file-id) + is-owner (boolean (some :is-owner rows)) + is-admin (boolean (some :is-admin rows)) + can-edit (boolean (some :can-edit rows))] + (when (seq rows) + {:type :membership + :is-owner is-owner + :is-admin (or is-owner is-admin) + :can-edit (or is-owner is-admin can-edit) + :can-read true + :is-logged (some? profile-id)}))) + + ([conn profile-id file-id share-id] + (let [perms (get-file-permissions conn profile-id file-id) + ldata (some-> (db/get* conn :share-link {:id share-id :file-id file-id}) + (dissoc :flags) + (update :pages db/decode-pgarray #{}))] + + ;; NOTE: in a future when share-link becomes more powerful and + ;; will allow us specify which parts of the app is available, we + ;; will probably need to tweak this function in order to expose + ;; this flags to the frontend. + (cond + (some? perms) perms + (some? ldata) {:type :share-link + :can-read true + :pages (:pages ldata) + :is-logged (some? profile-id) + :who-comment (:who-comment ldata) + :who-inspect (:who-inspect ldata)})))) + + (defn get-project [cfg project-id] (db/get cfg :project {:id project-id})) diff --git a/backend/src/app/rpc/commands/files.clj b/backend/src/app/rpc/commands/files.clj index de7a027e96..da21dd9616 100644 --- a/backend/src/app/rpc/commands/files.clj +++ b/backend/src/app/rpc/commands/files.clj @@ -79,85 +79,14 @@ ;; --- FILE PERMISSIONS - -(def ^:private sql:file-permissions - "select fpr.is_owner, - fpr.is_admin, - fpr.can_edit - from file_profile_rel as fpr - inner join file as f on (f.id = fpr.file_id) - where fpr.file_id = ? - and fpr.profile_id = ? - and f.deleted_at is null - union all - select tpr.is_owner, - tpr.is_admin, - tpr.can_edit - from team_profile_rel as tpr - inner join project as p on (p.team_id = tpr.team_id) - inner join file as f on (p.id = f.project_id) - where f.id = ? - and tpr.profile_id = ? - and f.deleted_at is null - union all - select ppr.is_owner, - ppr.is_admin, - ppr.can_edit - from project_profile_rel as ppr - inner join file as f on (f.project_id = ppr.project_id) - where f.id = ? - and ppr.profile_id = ? - and f.deleted_at is null") - -(defn get-file-permissions - [conn profile-id file-id] - (when (and profile-id file-id) - (db/exec! conn [sql:file-permissions - file-id profile-id - file-id profile-id - file-id profile-id]))) - -(defn get-permissions - ([conn profile-id file-id] - (let [rows (get-file-permissions conn profile-id file-id) - is-owner (boolean (some :is-owner rows)) - is-admin (boolean (some :is-admin rows)) - can-edit (boolean (some :can-edit rows))] - (when (seq rows) - {:type :membership - :is-owner is-owner - :is-admin (or is-owner is-admin) - :can-edit (or is-owner is-admin can-edit) - :can-read true - :is-logged (some? profile-id)}))) - - ([conn profile-id file-id share-id] - (let [perms (get-permissions conn profile-id file-id) - ldata (some-> (db/get* conn :share-link {:id share-id :file-id file-id}) - (dissoc :flags) - (update :pages db/decode-pgarray #{}))] - - ;; NOTE: in a future when share-link becomes more powerful and - ;; will allow us specify which parts of the app is available, we - ;; will probably need to tweak this function in order to expose - ;; this flags to the frontend. - (cond - (some? perms) perms - (some? ldata) {:type :share-link - :can-read true - :pages (:pages ldata) - :is-logged (some? profile-id) - :who-comment (:who-comment ldata) - :who-inspect (:who-inspect ldata)})))) - (def has-edit-permissions? - (perms/make-edition-predicate-fn get-permissions)) + (perms/make-edition-predicate-fn bfc/get-file-permissions)) (def has-read-permissions? - (perms/make-read-predicate-fn get-permissions)) + (perms/make-read-predicate-fn bfc/get-file-permissions)) (def has-comment-permissions? - (perms/make-comment-predicate-fn get-permissions)) + (perms/make-comment-predicate-fn bfc/get-file-permissions)) (def check-edition-permissions! (perms/make-check-fn has-edit-permissions?)) @@ -170,7 +99,7 @@ (defn check-comment-permissions! [conn profile-id file-id share-id] - (let [perms (get-permissions conn profile-id file-id share-id) + (let [perms (bfc/get-file-permissions conn profile-id file-id share-id) can-read (has-read-permissions? perms) can-comment (has-comment-permissions? perms)] (when-not (or can-read can-comment) @@ -222,7 +151,7 @@ (defn- get-minimal-file-with-perms [cfg {:keys [:id ::rpc/profile-id]}] (let [mfile (get-minimal-file cfg id) - perms (get-permissions cfg profile-id id)] + perms (bfc/get-file-permissions cfg profile-id id)] (assoc mfile :permissions perms))) (defn get-file-etag @@ -248,7 +177,7 @@ ;; will be already prefetched and we just reuse them instead ;; of making an additional database queries. (let [perms (or (:permissions (::cond/object params)) - (get-permissions conn profile-id id))] + (bfc/get-file-permissions conn profile-id id))] (check-read-permissions! perms) (let [team (teams/get-team conn @@ -311,7 +240,7 @@ ::sm/result schema:file-fragment} [cfg {:keys [::rpc/profile-id file-id fragment-id share-id]}] (db/run! cfg (fn [cfg] - (let [perms (get-permissions cfg profile-id file-id share-id)] + (let [perms (bfc/get-file-permissions cfg profile-id file-id share-id)] (check-read-permissions! perms) (-> (get-file-fragment cfg file-id fragment-id) (rph/with-http-cache long-cache-duration)))))) @@ -456,8 +385,7 @@ :code :params-validation :hint "page-id is required when object-id is provided")) - (let [perms (get-permissions conn profile-id file-id share-id) - + (let [perms (bfc/get-file-permissions conn profile-id file-id share-id) file (bfc/get-file cfg file-id :read-only? true) proj (db/get conn :project {:id (:project-id file)}) diff --git a/backend/src/app/rpc/commands/fonts.clj b/backend/src/app/rpc/commands/fonts.clj index 535d868f95..05454d6698 100644 --- a/backend/src/app/rpc/commands/fonts.clj +++ b/backend/src/app/rpc/commands/fonts.clj @@ -6,6 +6,7 @@ (ns app.rpc.commands.fonts (:require + [app.binfile.common :as bfc] [app.common.data.macros :as dm] [app.common.exceptions :as ex] [app.common.schema :as sm] @@ -66,7 +67,7 @@ (uuid? file-id) (let [file (db/get-by-id conn :file file-id {:columns [:id :project-id]}) project (db/get-by-id conn :project (:project-id file) {:columns [:id :team-id]}) - perms (files/get-permissions conn profile-id file-id share-id)] + perms (bfc/get-file-permissions conn profile-id file-id share-id)] (files/check-read-permissions! perms) (db/query conn :team-font-variant {:team-id (:team-id project) diff --git a/backend/src/app/rpc/commands/viewer.clj b/backend/src/app/rpc/commands/viewer.clj index 49d901979f..d2b191aeb4 100644 --- a/backend/src/app/rpc/commands/viewer.clj +++ b/backend/src/app/rpc/commands/viewer.clj @@ -120,7 +120,7 @@ [system {:keys [::rpc/profile-id file-id share-id] :as params}] (db/run! system (fn [{:keys [::db/conn] :as system}] - (let [perms (files/get-permissions conn profile-id file-id share-id) + (let [perms (bfc/get-file-permissions conn profile-id file-id share-id) params (-> params (assoc ::perms perms) (assoc :profile-id profile-id))]