Integrate objects-map and introduce file feature flags

This commit is contained in:
Andrey Antukh 2022-10-06 18:47:16 +02:00 committed by Andrés Moya
parent 69f084e1df
commit 951b3eb4fe
21 changed files with 406 additions and 264 deletions

View file

@ -227,29 +227,34 @@
(d/index-by :object-id :data))))))
(defn retrieve-file
[{:keys [pool] :as cfg} id components-v2]
[{:keys [pool] :as cfg} id features]
(let [file (->> (db/get-by-id pool :file id)
(decode-row)
(pmg/migrate-file))]
(if components-v2
(if (contains? features "components/v2")
(update file :data ctf/migrate-to-components-v2)
(if (get-in file [:data :options :components-v2])
(if (dm/get-in file [:data :options :components-v2])
(ex/raise :type :restriction
:code :feature-disabled
:hint "tried to open a components-v2 file with feature disabled")
:hint "tried to open a components/v2 file with feature disabled")
file))))
(s/def ::features ::us/set-of-strings)
(s/def ::file
(s/keys :req-un [::profile-id ::id]
:opt-un [::components-v2]))
:opt-un [::features ::components-v2]))
(sv/defmethod ::file
"Retrieve a file by its ID. Only authenticated users."
[{:keys [pool] :as cfg} {:keys [profile-id id components-v2] :as params}]
(let [perms (get-permissions pool profile-id id)]
[{:keys [pool] :as cfg} {:keys [profile-id id features components-v2] :as params}]
(let [perms (get-permissions pool profile-id id)
;; BACKWARD COMPATIBILTY with the components-v2 parameter
features (cond-> (or features #{})
components-v2 (conj features "components/v2"))]
(check-read-permissions! perms)
(let [file (retrieve-file cfg id components-v2)
(let [file (retrieve-file cfg id features)
thumbs (retrieve-object-thumbnails cfg id)]
(-> file
(assoc :thumbnails thumbs)
@ -278,7 +283,7 @@
(s/def ::page
(s/and
(s/keys :req-un [::profile-id ::file-id]
:opt-un [::page-id ::object-id ::components-v2])
:opt-un [::page-id ::object-id ::features ::components-v2])
(fn [obj]
(if (contains? obj :object-id)
(contains? obj :page-id)
@ -294,11 +299,15 @@
mandatory.
Mainly used for rendering purposes."
[{:keys [pool] :as cfg} {:keys [profile-id file-id page-id object-id components-v2] :as props}]
[{:keys [pool] :as cfg} {:keys [profile-id file-id page-id object-id features components-v2] :as props}]
(check-read-permissions! pool profile-id file-id)
(let [file (retrieve-file cfg file-id components-v2)
page-id (or page-id (-> file :data :pages first))
page (get-in file [:data :pages-index page-id])]
(let [;; BACKWARD COMPATIBILTY with the components-v2 parameter
features (cond-> (or features #{})
components-v2 (conj features "components/v2"))
file (retrieve-file cfg file-id features)
page-id (or page-id (-> file :data :pages first))
page (dm/get-in file [:data :pages-index page-id])]
(cond-> (prune-thumbnails page)
(uuid? object-id)
@ -384,14 +393,17 @@
(s/def ::file-data-for-thumbnail
(s/keys :req-un [::profile-id ::file-id]
:opt-un [::components-v2]))
:opt-un [::components-v2 ::features]))
(sv/defmethod ::file-data-for-thumbnail
"Retrieves the data for generate the thumbnail of the file. Used
mainly for render thumbnails on dashboard."
[{:keys [pool] :as cfg} {:keys [profile-id file-id components-v2] :as props}]
[{:keys [pool] :as cfg} {:keys [profile-id file-id features components-v2] :as props}]
(check-read-permissions! pool profile-id file-id)
(let [file (retrieve-file cfg file-id components-v2)]
(let [;; BACKWARD COMPATIBILTY with the components-v2 parameter
features (cond-> (or features #{})
components-v2 (conj features "components/v2"))
file (retrieve-file cfg file-id features)]
{:file-id file-id
:revn (:revn file)
:page (get-file-thumbnail-data cfg file)}))
@ -567,8 +579,9 @@
;; --- Helpers
(defn decode-row
[{:keys [data changes] :as row}]
[{:keys [data changes features] :as row}]
(when row
(cond-> row
changes (assoc :changes (blob/decode changes))
data (assoc :data (blob/decode data)))))
features (assoc :features (db/decode-pgarray features))
changes (assoc :changes (blob/decode changes))
data (assoc :data (blob/decode data)))))

View file

@ -23,8 +23,8 @@
(db/get-by-id pool :project id {:columns [:id :name :team-id]}))
(defn- retrieve-bundle
[{:keys [pool] :as cfg} file-id profile-id components-v2]
(p/let [file (files/retrieve-file cfg file-id components-v2)
[{:keys [pool] :as cfg} file-id profile-id features]
(p/let [file (files/retrieve-file cfg file-id features)
project (retrieve-project pool (:project-id file))
libs (files/retrieve-file-libraries cfg false file-id)
users (comments/get-file-comments-users pool file-id profile-id)
@ -45,40 +45,49 @@
(s/def ::file-id ::us/uuid)
(s/def ::profile-id ::us/uuid)
(s/def ::share-id ::us/uuid)
(s/def ::features ::us/set-of-strings)
;; TODO: deprecated, should be removed when version >= 1.18
(s/def ::components-v2 ::us/boolean)
(s/def ::view-only-bundle
(s/keys :req-un [::file-id] :opt-un [::profile-id ::share-id ::components-v2]))
(s/keys :req-un [::file-id]
:opt-un [::profile-id ::share-id ::features ::components-v2]))
(sv/defmethod ::view-only-bundle {:auth false}
[{:keys [pool] :as cfg} {:keys [profile-id file-id share-id components-v2] :as params}]
(p/let [slink (slnk/retrieve-share-link pool file-id share-id)
[{:keys [pool] :as cfg} {:keys [profile-id file-id share-id features components-v2] :as params}]
(p/let [;; BACKWARD COMPATIBILTY with the components-v2 parameter
features (cond-> (or features #{})
components-v2 (conj features "components/v2"))
slink (slnk/retrieve-share-link pool file-id share-id)
perms (files/get-permissions pool profile-id file-id share-id)
thumbs (files/retrieve-object-thumbnails cfg file-id)
bundle (p/-> (retrieve-bundle cfg file-id profile-id components-v2)
bundle (p/-> (retrieve-bundle cfg file-id profile-id features)
(assoc :permissions perms)
(assoc-in [:file :thumbnails] thumbs))]
;; When we have neither profile nor share, we just return a not
;; found response to the user.
(when (and (not profile-id)
(not slink))
(ex/raise :type :not-found
:code :object-not-found))
(do
(when (and (not profile-id)
(not slink))
(ex/raise :type :not-found
:code :object-not-found))
;; When we have only profile, we need to check read permissions
;; on file.
(when (and profile-id (not slink))
(files/check-read-permissions! pool profile-id file-id))
;; When we have only profile, we need to check read permissions
;; on file.
(when (and profile-id (not slink))
(files/check-read-permissions! pool profile-id file-id))
(cond-> bundle
(some? slink)
(assoc :share slink)
(cond-> bundle
(some? slink)
(assoc :share slink)
(and (some? slink)
(and (some? slink)
(not (contains? (:flags slink) "view-all-pages")))
(update-in [:file :data] (fn [data]
(let [allowed-pages (:pages slink)]
(-> data
(update :pages (fn [pages] (filterv #(contains? allowed-pages %) pages)))
(update :pages-index (fn [index] (select-keys index allowed-pages))))))))))
(update-in [:file :data] (fn [data]
(let [allowed-pages (:pages slink)]
(-> data
(update :pages (fn [pages] (filterv #(contains? allowed-pages %) pages)))
(update :pages-index (fn [index] (select-keys index allowed-pages)))))))))))