0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-09 21:41:23 -05:00

🔥 Remove deprecated queries and mutations

This commit is contained in:
Andrey Antukh 2023-04-24 20:18:14 +02:00
parent 36953eef1a
commit c0ccbaebaf
23 changed files with 105 additions and 978 deletions

View file

@ -1,6 +1,5 @@
<li class="rpc-item">
<div class="rpc-row-info">
{# <div class="type">{{item.type}}</div> #}
<div class="module">{{item.module}}:</div>
<div class="name">{{item.name}}</div>
<div class="tags">

View file

@ -23,23 +23,9 @@
</header>
<section class="rpc-doc-content">
<h2>RPC COMMAND METHODS:</h2>
<h2>RPC METHODS:</h2>
<ul class="rpc-items">
{% for item in command-methods %}
{% include "app/templates/api-doc-entry.tmpl" with item=item %}
{% endfor %}
</ul>
<h2>RPC QUERY METHODS:</h2>
<ul class="rpc-items">
{% for item in query-methods %}
{% include "app/templates/api-doc-entry.tmpl" with item=item %}
{% endfor %}
</ul>
<h2>RPC MUTATION METHODS:</h2>
<ul class="rpc-items">
{% for item in mutation-methods %}
{% for item in methods %}
{% include "app/templates/api-doc-entry.tmpl" with item=item %}
{% endfor %}
</ul>

View file

@ -66,46 +66,7 @@
(handle-response-transformation request mdata)
(handle-before-comple-hook mdata)))))
(defn- rpc-query-handler
"Ring handler that dispatches query requests and convert between
internal async flow into ring async flow."
[methods {:keys [params path-params] :as request}]
(let [type (keyword (:type path-params))
profile-id (or (::session/profile-id request)
(::actoken/profile-id request))
data (-> params
(assoc ::request-at (dt/now))
(assoc ::http/request request))
data (if profile-id
(-> data
(assoc :profile-id profile-id)
(assoc ::profile-id profile-id))
(dissoc data :profile-id ::profile-id))
method (get methods type default-handler)
response (method data)]
(handle-response request response)))
(defn- rpc-mutation-handler
"Ring handler that dispatches mutation requests and convert between
internal async flow into ring async flow."
[methods {:keys [params path-params] :as request}]
(let [type (keyword (:type path-params))
profile-id (or (::session/profile-id request)
(::actoken/profile-id request))
data (-> params
(assoc ::request-at (dt/now))
(assoc ::http/request request))
data (if profile-id
(-> data
(assoc :profile-id profile-id)
(assoc ::profile-id profile-id))
(dissoc data :profile-id))
method (get methods type default-handler)
response (method data)]
(handle-response request response)))
(defn- rpc-command-handler
(defn- rpc-handler
"Ring handler that dispatches cmd requests and convert between
internal async flow into ring async flow."
[methods {:keys [params path-params] :as request}]
@ -209,29 +170,6 @@
[cfg [vfn mdata]]
[(keyword (::sv/name mdata)) [mdata (wrap cfg vfn mdata)]])
(defn- resolve-query-methods
[cfg]
(let [cfg (assoc cfg ::type "query" ::metrics-id :rpc-query-timing)]
(->> (sv/scan-ns
'app.rpc.queries.projects
'app.rpc.queries.profile
'app.rpc.queries.viewer
'app.rpc.queries.fonts)
(map (partial process-method cfg))
(into {}))))
(defn- resolve-mutation-methods
[cfg]
(let [cfg (assoc cfg ::type "mutation" ::metrics-id :rpc-mutation-timing)]
(->> (sv/scan-ns
'app.rpc.mutations.media
'app.rpc.mutations.profile
'app.rpc.mutations.projects
'app.rpc.mutations.fonts
'app.rpc.mutations.share-link)
(map (partial process-method cfg))
(into {}))))
(defn- resolve-command-methods
[cfg]
(let [cfg (assoc cfg ::type "command" ::metrics-id :rpc-command-timing)]
@ -279,23 +217,10 @@
(defmethod ig/init-key ::methods
[_ cfg]
(let [cfg (d/without-nils cfg)]
{:mutations (resolve-mutation-methods cfg)
:queries (resolve-query-methods cfg)
:commands (resolve-command-methods cfg)}))
(s/def ::mutations
(s/map-of keyword? (s/tuple map? fn?)))
(s/def ::queries
(s/map-of keyword? (s/tuple map? fn?)))
(s/def ::commands
(s/map-of keyword? (s/tuple map? fn?)))
(resolve-command-methods cfg)))
(s/def ::methods
(s/keys :req-un [::mutations
::queries
::commands]))
(s/map-of keyword? (s/tuple map? fn?)))
(s/def ::routes vector?)
@ -308,14 +233,7 @@
(defmethod ig/init-key ::routes
[_ {:keys [::methods] :as cfg}]
(let [methods (-> methods
(update :commands update-vals peek)
(update :queries update-vals peek)
(update :mutations update-vals peek))]
(let [methods (update-vals methods peek)]
[["/rpc" {:middleware [[session/authz cfg]
[actoken/authz cfg]]}
["/command/:type" {:handler (partial rpc-command-handler (:commands methods))}]
["/query/:type" {:handler (partial rpc-query-handler (:queries methods))}]
["/mutation/:type" {:handler (partial rpc-mutation-handler (:mutations methods))
:allowed-methods #{:post}}]]]))
["/command/:type" {:handler (partial rpc-handler methods)}]]]))

View file

@ -30,9 +30,8 @@
(defn- prepare-context
[methods]
(letfn [(gen-doc [type [{:keys [::sv/name] :as mdata} _f]]
{:type (d/name type)
:name (d/name name)
(letfn [(gen-doc [[{:keys [::sv/name] :as mdata} _f]]
{:name (d/name name)
:module (-> (:ns mdata) (str/split ".") last)
:auth (:auth mdata true)
:webhook (::webhooks/event? mdata false)
@ -43,22 +42,10 @@
:spec (get-spec-str (::sv/spec mdata))})]
{:version (:main cf/version)
:command-methods
(->> (:commands methods)
:methods
(->> methods
(map val)
(map (partial gen-doc :command))
(sort-by (juxt :module :name)))
:query-methods
(->> (:queries methods)
(map val)
(map (partial gen-doc :query))
(sort-by (juxt :module :name)))
:mutation-methods
(->> (:mutations methods)
(map val)
(map (partial gen-doc :query))
(map gen-doc)
(sort-by (juxt :module :name)))}))
(defn- handler

View file

@ -1,116 +0,0 @@
;; 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) KALEIDOS INC
(ns app.rpc.mutations.fonts
(:require
[app.common.spec :as us]
[app.db :as db]
[app.loggers.audit :as-alias audit]
[app.loggers.webhooks :as-alias webhooks]
[app.media :as media]
[app.rpc.commands.fonts :as fonts]
[app.rpc.commands.teams :as teams]
[app.rpc.doc :as-alias doc]
[app.rpc.helpers :as rph]
[app.rpc.quotes :as quotes]
[app.storage :as sto]
[app.util.services :as sv]
[app.util.time :as dt]
[clojure.spec.alpha :as s]))
(declare create-font-variant)
(def valid-weight #{100 200 300 400 500 600 700 800 900 950})
(def valid-style #{"normal" "italic"})
(s/def ::id ::us/uuid)
(s/def ::profile-id ::us/uuid)
(s/def ::team-id ::us/uuid)
(s/def ::name ::us/not-empty-string)
(s/def ::weight valid-weight)
(s/def ::style valid-style)
(s/def ::font-id ::us/uuid)
(s/def ::data (s/map-of ::us/string any?))
(s/def ::create-font-variant
(s/keys :req-un [::profile-id ::team-id ::data
::font-id ::font-family ::font-weight ::font-style]))
(declare create-font-variant)
(sv/defmethod ::create-font-variant
{::doc/added "1.3"
::doc/deprecated "1.18"
::webhooks/event? true}
[{:keys [pool] :as cfg} {:keys [team-id profile-id] :as params}]
(let [cfg (update cfg ::sto/storage media/configure-assets-storage)]
(teams/check-edition-permissions! pool profile-id team-id)
(quotes/check-quote! pool {::quotes/id ::quotes/font-variants-per-team
::quotes/profile-id profile-id
::quotes/team-id team-id})
(fonts/create-font-variant cfg params)))
;; --- UPDATE FONT FAMILY
(s/def ::update-font
(s/keys :req-un [::profile-id ::team-id ::id ::name]))
(sv/defmethod ::update-font
{::doc/added "1.3"
::doc/deprecated "1.18"
::webhooks/event? true}
[{:keys [pool] :as cfg} {:keys [team-id profile-id id name] :as params}]
(db/with-atomic [conn pool]
(teams/check-edition-permissions! conn profile-id team-id)
(rph/with-meta
(db/update! conn :team-font-variant
{:font-family name}
{:font-id id
:team-id team-id})
{::audit/replace-props {:id id
:name name
:team-id team-id
:profile-id profile-id}})))
;; --- DELETE FONT
(s/def ::delete-font
(s/keys :req-un [::profile-id ::team-id ::id]))
(sv/defmethod ::delete-font
{::doc/added "1.3"
::doc/deprecated "1.18"
::webhooks/event? true}
[{:keys [pool] :as cfg} {:keys [id team-id profile-id] :as params}]
(db/with-atomic [conn pool]
(teams/check-edition-permissions! conn profile-id team-id)
(let [font (db/update! conn :team-font-variant
{:deleted-at (dt/now)}
{:font-id id :team-id team-id})]
(rph/with-meta (rph/wrap)
{::audit/props {:id id
:team-id team-id
:name (:font-family font)
:profile-id profile-id}}))))
;; --- DELETE FONT VARIANT
(s/def ::delete-font-variant
(s/keys :req-un [::profile-id ::team-id ::id]))
(sv/defmethod ::delete-font-variant
{::doc/added "1.3"
::doc/deprecated "1.18"
::webhooks/event? true}
[{:keys [pool] :as cfg} {:keys [id team-id profile-id] :as params}]
(db/with-atomic [conn pool]
(teams/check-edition-permissions! conn profile-id team-id)
(let [variant (db/update! conn :team-font-variant
{:deleted-at (dt/now)}
{:id id :team-id team-id})]
(rph/with-meta (rph/wrap)
{::audit/props {:font-family (:font-family variant)
:font-id (:font-id variant)}}))))

View file

@ -1,55 +0,0 @@
;; 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) KALEIDOS INC
(ns app.rpc.mutations.media
(:require
[app.db :as db]
[app.media :as media]
[app.rpc.commands.files :as files]
[app.rpc.commands.media :as cmd.media]
[app.rpc.doc :as-alias doc]
[app.storage :as-alias sto]
[app.util.services :as sv]
[clojure.spec.alpha :as s]))
;; --- Create File Media object (upload)
(s/def ::upload-file-media-object ::cmd.media/upload-file-media-object)
(sv/defmethod ::upload-file-media-object
{::doc/added "1.2"
::doc/deprecated "1.18"}
[{:keys [pool] :as cfg} {:keys [profile-id file-id content] :as params}]
(let [cfg (update cfg ::sto/storage media/configure-assets-storage)]
(files/check-edition-permissions! pool profile-id file-id)
(media/validate-media-type! content)
(cmd.media/validate-content-size! content)
(cmd.media/create-file-media-object cfg params)))
;; --- Create File Media Object (from URL)
(s/def ::create-file-media-object-from-url ::cmd.media/create-file-media-object-from-url)
(sv/defmethod ::create-file-media-object-from-url
{::doc/added "1.3"
::doc/deprecated "1.18"}
[{:keys [pool] :as cfg} {:keys [profile-id file-id] :as params}]
(let [cfg (update cfg ::sto/storage media/configure-assets-storage)]
(files/check-edition-permissions! pool profile-id file-id)
(#'cmd.media/create-file-media-object-from-url cfg params)))
;; --- Clone File Media object (Upload and create from url)
(s/def ::clone-file-media-object ::cmd.media/clone-file-media-object)
(sv/defmethod ::clone-file-media-object
{::doc/added "1.2"
::doc/deprecated "1.18"}
[{:keys [pool] :as cfg} {:keys [profile-id file-id] :as params}]
(db/with-atomic [conn pool]
(files/check-edition-permissions! conn profile-id file-id)
(-> (assoc cfg :conn conn)
(cmd.media/clone-file-media-object params))))

View file

@ -1,192 +0,0 @@
;; 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) KALEIDOS INC
(ns app.rpc.mutations.profile
(:require
[app.common.data :as d]
[app.common.exceptions :as ex]
[app.common.spec :as us]
[app.config :as cf]
[app.db :as db]
[app.http.session :as session]
[app.loggers.audit :as audit]
[app.media :as media]
[app.rpc.commands.profile :as profile]
[app.rpc.doc :as-alias doc]
[app.rpc.helpers :as rph]
[app.storage :as sto]
[app.util.services :as sv]
[app.util.time :as dt]
[clojure.spec.alpha :as s]
[cuerdas.core :as str]))
;; --- Helpers & Specs
(s/def ::email ::us/email)
(s/def ::fullname ::us/not-empty-string)
(s/def ::lang ::us/string)
(s/def ::path ::us/string)
(s/def ::profile-id ::us/uuid)
(s/def ::password ::us/not-empty-string)
(s/def ::old-password (s/nilable ::us/string))
(s/def ::theme ::us/string)
;; --- MUTATION: Update Profile (own)
(s/def ::update-profile
(s/keys :req-un [::fullname ::profile-id]
:opt-un [::lang ::theme]))
(sv/defmethod ::update-profile
{::doc/added "1.0"
::doc/deprecated "1.18"}
[{:keys [::db/pool] :as cfg} {:keys [profile-id fullname lang theme] :as params}]
(db/with-atomic [conn pool]
;; NOTE: we need to retrieve the profile independently if we use
;; it or not for explicit locking and avoid concurrent updates of
;; the same row/object.
(let [profile (-> (db/get-by-id conn :profile profile-id ::db/for-update? true)
(profile/decode-row))
;; Update the profile map with direct params
profile (-> profile
(assoc :fullname fullname)
(assoc :lang lang)
(assoc :theme theme))
]
(db/update! conn :profile
{:fullname fullname
:lang lang
:theme theme
:props (db/tjson (:props profile))}
{:id profile-id})
(-> profile
(profile/strip-private-attrs)
(d/without-nils)
(rph/with-meta {::audit/props (audit/profile->props profile)})))))
;; --- MUTATION: Update Password
(s/def ::update-profile-password
(s/keys :req-un [::profile-id ::password ::old-password]))
(sv/defmethod ::update-profile-password
{::doc/added "1.0"
::doc/deprecated "1.18"}
[{:keys [::db/pool] :as cfg} {:keys [password] :as params}]
(db/with-atomic [conn pool]
(let [cfg (assoc cfg ::db/conn conn)
profile (#'profile/validate-password! cfg params)
session-id (::session/id params)]
(when (= (str/lower (:email profile))
(str/lower (:password params)))
(ex/raise :type :validation
:code :email-as-password
:hint "you can't use your email as password"))
(profile/update-profile-password! cfg (assoc profile :password password))
(#'profile/invalidate-profile-session! cfg (:id profile) session-id)
nil)))
;; --- MUTATION: Update Photo
(s/def ::file ::media/upload)
(s/def ::update-profile-photo
(s/keys :req-un [::profile-id ::file]))
(sv/defmethod ::update-profile-photo
{::doc/added "1.0"
::doc/deprecated "1.18"}
[cfg {:keys [file] :as params}]
;; Validate incoming mime type
(media/validate-media-type! file #{"image/jpeg" "image/png" "image/webp"})
(let [cfg (update cfg ::sto/storage media/configure-assets-storage)]
(profile/update-profile-photo cfg params)))
;; --- MUTATION: Request Email Change
(s/def ::request-email-change
(s/keys :req-un [::email]))
(sv/defmethod ::request-email-change
{::doc/added "1.0"
::doc/deprecated "1.18"}
[{:keys [::db/pool] :as cfg} {:keys [profile-id email] :as params}]
(db/with-atomic [conn pool]
(let [profile (db/get-by-id conn :profile profile-id)
cfg (assoc cfg ::profile/conn conn)
params (assoc params
:profile profile
:email (str/lower email))]
(if (contains? cf/flags :smtp)
(#'profile/request-email-change! cfg params)
(#'profile/change-email-immediately! cfg params)))))
;; --- MUTATION: Update Profile Props
(s/def ::props map?)
(s/def ::update-profile-props
(s/keys :req-un [::profile-id ::props]))
(sv/defmethod ::update-profile-props
{::doc/added "1.0"
::doc/deprecated "1.18"}
[{:keys [::db/pool] :as cfg} {:keys [profile-id props]}]
(db/with-atomic [conn pool]
(let [profile (profile/get-profile conn profile-id ::db/for-update? true)
props (reduce-kv (fn [props k v]
;; We don't accept namespaced keys
(if (simple-ident? k)
(if (nil? v)
(dissoc props k)
(assoc props k v))
props))
(:props profile)
props)]
(db/update! conn :profile
{:props (db/tjson props)}
{:id profile-id})
(profile/filter-props props))))
;; --- MUTATION: Delete Profile
(s/def ::delete-profile
(s/keys :req-un [::profile-id]))
(sv/defmethod ::delete-profile
{::doc/added "1.0"
::doc/deprecated "1.18"}
[{:keys [::db/pool] :as cfg} {:keys [profile-id] :as params}]
(db/with-atomic [conn pool]
(let [teams (#'profile/get-owned-teams-with-participants conn profile-id)
deleted-at (dt/now)]
;; If we found owned teams with participants, we don't allow
;; delete profile until the user properly transfer ownership or
;; explicitly removes all participants from the team
(when (some pos? (map :participants teams))
(ex/raise :type :validation
:code :owner-teams-with-people
:hint "The user need to transfer ownership of owned teams."
:context {:teams (mapv :id teams)}))
(doseq [{:keys [id]} teams]
(db/update! conn :team
{:deleted-at deleted-at}
{:id id}))
(db/update! conn :profile
{:deleted-at deleted-at}
{:id profile-id})
(rph/with-transform {} (session/delete-fn cfg)))))

View file

@ -1,130 +0,0 @@
;; 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) KALEIDOS INC
(ns app.rpc.mutations.projects
(:require
[app.common.spec :as us]
[app.db :as db]
[app.loggers.audit :as-alias audit]
[app.loggers.webhooks :as-alias webhooks]
[app.rpc.commands.projects :as projects]
[app.rpc.commands.teams :as teams]
[app.rpc.doc :as-alias doc]
[app.rpc.helpers :as rph]
[app.rpc.quotes :as quotes]
[app.util.services :as sv]
[app.util.time :as dt]
[clojure.spec.alpha :as s]))
;; --- Helpers & Specs
(s/def ::id ::us/uuid)
(s/def ::name ::us/string)
(s/def ::profile-id ::us/uuid)
;; --- Mutation: Create Project
(s/def ::team-id ::us/uuid)
(s/def ::create-project
(s/keys :req-un [::profile-id ::team-id ::name]
:opt-un [::id]))
(sv/defmethod ::create-project
{::doc/added "1.0"
::doc/deprecated "1.18"
::webhooks/event? true}
[{:keys [pool] :as cfg} {:keys [profile-id team-id] :as params}]
(db/with-atomic [conn pool]
(teams/check-edition-permissions! conn profile-id team-id)
(quotes/check-quote! conn {::quotes/id ::quotes/projects-per-team
::quotes/profile-id profile-id
::quotes/team-id team-id})
(let [project (teams/create-project conn params)]
(teams/create-project-role conn profile-id (:id project) :owner)
(db/insert! conn :team-project-profile-rel
{:project-id (:id project)
:profile-id profile-id
:team-id team-id
:is-pinned true})
(assoc project :is-pinned true))))
;; --- Mutation: Toggle Project Pin
(def ^:private
sql:update-project-pin
"insert into team_project_profile_rel (team_id, project_id, profile_id, is_pinned)
values (?, ?, ?, ?)
on conflict (team_id, project_id, profile_id)
do update set is_pinned=?")
(s/def ::is-pinned ::us/boolean)
(s/def ::project-id ::us/uuid)
(s/def ::update-project-pin
(s/keys :req-un [::profile-id ::id ::team-id ::is-pinned]))
(sv/defmethod ::update-project-pin
{::doc/added "1.0"
::doc/deprecated "1.18"
::webhooks/batch-timeout (dt/duration "5s")
::webhooks/batch-key :id
::webhooks/event? true}
[{:keys [pool] :as cfg} {:keys [id profile-id team-id is-pinned] :as params}]
(db/with-atomic [conn pool]
(projects/check-edition-permissions! conn profile-id id)
(db/exec-one! conn [sql:update-project-pin team-id id profile-id is-pinned is-pinned])
nil))
;; --- Mutation: Rename Project
(declare rename-project)
(s/def ::rename-project
(s/keys :req-un [::profile-id ::name ::id]))
(sv/defmethod ::rename-project
{::doc/added "1.0"
::doc/deprecated "1.18"
::webhooks/event? true}
[{:keys [pool] :as cfg} {:keys [id profile-id name] :as params}]
(db/with-atomic [conn pool]
(projects/check-edition-permissions! conn profile-id id)
(let [project (db/get-by-id conn :project id)]
(db/update! conn :project
{:name name}
{:id id})
(rph/with-meta (rph/wrap)
{::audit/props {:team-id (:team-id project)
:prev-name (:name project)}}))))
;; --- Mutation: Delete Project
(s/def ::delete-project
(s/keys :req-un [::id ::profile-id]))
;; TODO: right now, we just don't allow delete default projects, in a
;; future we need to ensure raise a correct exception signaling that
;; this is not allowed.
(sv/defmethod ::delete-project
{::doc/added "1.0"
::doc/deprecated "1.18"
::webhooks/event? true}
[{:keys [pool] :as cfg} {:keys [id profile-id] :as params}]
(db/with-atomic [conn pool]
(projects/check-edition-permissions! conn profile-id id)
(let [project (db/update! conn :project
{:deleted-at (dt/now)}
{:id id :is-default false})]
(rph/with-meta (rph/wrap)
{::audit/props {:team-id (:team-id project)
:name (:name project)
:created-at (:created-at project)
:modified-at (:modified-at project)}}))))

View file

@ -1,71 +0,0 @@
;; 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) KALEIDOS INC
(ns app.rpc.mutations.share-link
"Share link related rpc mutation methods."
(:require
[app.common.spec :as us]
[app.common.uuid :as uuid]
[app.db :as db]
[app.rpc.commands.files :as files]
[app.rpc.doc :as-alias doc]
[app.util.services :as sv]
[clojure.spec.alpha :as s]))
;; --- Helpers & Specs
(s/def ::id ::us/uuid)
(s/def ::profile-id ::us/uuid)
(s/def ::file-id ::us/uuid)
(s/def ::who-comment ::us/string)
(s/def ::who-inspect ::us/string)
(s/def ::pages (s/every ::us/uuid :kind set?))
;; --- Mutation: Create Share Link
(declare create-share-link)
(s/def ::create-share-link
(s/keys :req-un [::profile-id ::file-id ::who-comment ::who-inspect ::pages]))
(sv/defmethod ::create-share-link
"Creates a share-link object.
Share links are resources that allows external users access to specific
pages of a file with specific permissions (who-comment and who-inspect)."
{::doc/added "1.5"
::doc/deprecated "1.18"}
[{:keys [::db/pool] :as cfg} {:keys [profile-id file-id] :as params}]
(db/with-atomic [conn pool]
(files/check-edition-permissions! conn profile-id file-id)
(create-share-link conn params)))
(defn create-share-link
[conn {:keys [profile-id file-id pages who-comment who-inspect]}]
(let [pages (db/create-array conn "uuid" pages)
slink (db/insert! conn :share-link
{:id (uuid/next)
:file-id file-id
:who-comment who-comment
:who-inspect who-inspect
:pages pages
:owner-id profile-id})]
(update slink :pages db/decode-pgarray #{})))
;; --- Mutation: Delete Share Link
(s/def ::delete-share-link
(s/keys :req-un [::profile-id ::id]))
(sv/defmethod ::delete-share-link
{::doc/added "1.5"
::doc/deprecated "1.18"}
[{:keys [::db/pool] :as cfg} {:keys [profile-id id] :as params}]
(db/with-atomic [conn pool]
(let [slink (db/get-by-id conn :share-link id)]
(files/check-edition-permissions! conn profile-id (:file-id slink))
(db/delete! conn :share-link {:id id})
nil)))

View file

@ -1,59 +0,0 @@
;; 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) KALEIDOS INC
(ns app.rpc.queries.fonts
(:require
[app.common.spec :as us]
[app.db :as db]
[app.rpc.commands.files :as files]
[app.rpc.commands.projects :as projects]
[app.rpc.commands.teams :as teams]
[app.rpc.doc :as-alias doc]
[app.util.services :as sv]
[clojure.spec.alpha :as s]))
;; --- Query: Font Variants
(s/def ::team-id ::us/uuid)
(s/def ::file-id ::us/uuid)
(s/def ::project-id ::us/uuid)
(s/def ::font-variants
(s/and
(s/keys :req-un [::profile-id]
:opt-un [::team-id
::file-id
::project-id])
(fn [o]
(or (contains? o :team-id)
(contains? o :file-id)
(contains? o :project-id)))))
(sv/defmethod ::font-variants
{::doc/added "1.7"}
[{:keys [pool] :as cfg} {:keys [profile-id team-id file-id project-id] :as params}]
(with-open [conn (db/open pool)]
(cond
(uuid? team-id)
(do
(teams/check-read-permissions! conn profile-id team-id)
(db/query conn :team-font-variant
{:team-id team-id
:deleted-at nil}))
(uuid? project-id)
(let [project (db/get-by-id conn :project project-id {:columns [:id :team-id]})]
(projects/check-read-permissions! conn profile-id project-id)
(db/query conn :team-font-variant
{:team-id (:team-id project)
:deleted-at nil}))
(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]})]
(files/check-read-permissions! conn profile-id file-id)
(db/query conn :team-font-variant
{:team-id (:team-id project)
:deleted-at nil})))))

View file

@ -1,32 +0,0 @@
;; 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) KALEIDOS INC
(ns app.rpc.queries.profile
(:require
[app.common.uuid :as uuid]
[app.db :as db]
[app.rpc :as-alias rpc]
[app.rpc.commands.profile :as profile]
[app.rpc.doc :as-alias doc]
[app.util.services :as sv]
[clojure.spec.alpha :as s]))
(s/def ::profile ::profile/get-profile)
(sv/defmethod ::profile
{::rpc/auth false
::doc/added "1.0"
::doc/deprecated "1.18"}
[{:keys [::db/pool] :as cfg} {:keys [profile-id]}]
;; We need to return the anonymous profile object in two cases, when
;; no profile-id is in session, and when db call raises not found. In all other
;; cases we need to reraise the exception.
(try
(-> (profile/get-profile pool profile-id)
(profile/strip-private-attrs)
(update :props profile/filter-props))
(catch Throwable _
{:id uuid/zero :fullname "Anonymous User"})))

View file

@ -1,59 +0,0 @@
;; 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) KALEIDOS INC
(ns app.rpc.queries.projects
(:require
[app.common.spec :as us]
[app.db :as db]
[app.rpc.commands.projects :as projects]
[app.rpc.commands.teams :as teams]
[app.rpc.doc :as-alias doc]
[app.util.services :as sv]
[clojure.spec.alpha :as s]))
;; --- Query: Projects
(s/def ::team-id ::us/uuid)
(s/def ::profile-id ::us/uuid)
(s/def ::projects
(s/keys :req-un [::profile-id ::team-id]))
(sv/defmethod ::projects
{::doc/added "1.0"
::doc/deprecated "1.18"}
[{:keys [pool]} {:keys [profile-id team-id]}]
(with-open [conn (db/open pool)]
(teams/check-read-permissions! conn profile-id team-id)
(projects/get-projects conn profile-id team-id)))
;; --- Query: All projects
(s/def ::profile-id ::us/uuid)
(s/def ::all-projects
(s/keys :req-un [::profile-id]))
(sv/defmethod ::all-projects
{::doc/added "1.0"
::doc/deprecated "1.18"}
[{:keys [pool]} {:keys [profile-id]}]
(with-open [conn (db/open pool)]
(projects/get-all-projects conn profile-id)))
;; --- Query: Project
(s/def ::id ::us/uuid)
(s/def ::project
(s/keys :req-un [::profile-id ::id]))
(sv/defmethod ::project
{::doc/added "1.0"
::doc/deprecated "1.18"}
[{:keys [pool]} {:keys [profile-id id]}]
(with-open [conn (db/open pool)]
(let [project (db/get-by-id conn :project id)]
(projects/check-read-permissions! conn profile-id id)
project)))

View file

@ -1,32 +0,0 @@
;; 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) KALEIDOS INC
(ns app.rpc.queries.viewer
(:require
[app.common.spec :as us]
[app.db :as db]
[app.rpc :as-alias rpc]
[app.rpc.commands.viewer :as viewer]
[app.rpc.doc :as-alias doc]
[app.util.services :as sv]
[clojure.spec.alpha :as s]))
(s/def ::components-v2 ::us/boolean)
(s/def ::view-only-bundle
(s/and ::viewer/get-view-only-bundle
(s/keys :opt-un [::components-v2])))
(sv/defmethod ::view-only-bundle
{::rpc/auth false
::doc/added "1.3"
::doc/deprecated "1.18"}
[{:keys [pool] :as cfg} {:keys [features components-v2] :as params}]
(with-open [conn (db/open pool)]
(let [;; BACKWARD COMPATIBILTY with the components-v2 parameter
features (cond-> (or features #{})
components-v2 (conj "components/v2"))
params (assoc params :features features)]
(viewer/get-view-only-bundle conn params))))

View file

@ -23,7 +23,6 @@
[app.db.sql :as sql]
[app.main :refer [system]]
[app.rpc.commands.files :as files]
[app.rpc.queries.profile :as prof]
[app.util.blob :as blob]
[app.util.objects-map :as omap]
[app.util.pointer-map :as pmap]

View file

@ -29,7 +29,6 @@
[app.rpc.commands.files-update :as files.update]
[app.rpc.commands.teams :as teams]
[app.rpc.helpers :as rph]
[app.rpc.mutations.profile :as profile]
[app.util.blob :as blob]
[app.util.services :as sv]
[app.util.time :as dt]
@ -231,7 +230,7 @@
([pool i {:keys [profile-id project-id] :as params}]
(us/assert uuid? profile-id)
(us/assert uuid? project-id)
(dm/with-open [conn (db/open pool)]
(db/with-atomic [conn (db/open pool)]
(files.create/create-file conn
(merge {:id (mk-uuid "file" i)
:name (str "file" i)
@ -367,7 +366,7 @@
(defn command!
[{:keys [::type] :as data}]
(let [[mdata method-fn] (get-in *system* [:app.rpc/methods :commands type])]
(let [[mdata method-fn] (get-in *system* [:app.rpc/methods type])]
(when-not method-fn
(ex/raise :type :assertion
:code :rpc-method-not-found
@ -378,23 +377,6 @@
(dissoc ::type)
(assoc :app.rpc/request-at (dt/now)))))))
(defn mutation!
[{:keys [::type profile-id] :as data}]
(let [[mdata method-fn] (get-in *system* [:app.rpc/methods :mutations type])]
(try-on! (method-fn (-> data
(dissoc ::type)
(assoc ::rpc/profile-id profile-id)
(d/without-nils))))))
(defn query!
[{:keys [::type profile-id] :as data}]
(let [[mdata method-fn] (get-in *system* [:app.rpc/methods :queries type])]
(try-on! (method-fn (-> data
(dissoc ::type)
(assoc ::rpc/profile-id profile-id)
(d/without-nils))))))
(defn run-task!
([name]
(run-task! name {}))

View file

@ -23,7 +23,7 @@
res (th/run-task! :process-webhook-event
{:props
{:app.loggers.webhooks/event
{:type "mutation"
{:type "command"
:name "create-project"
:props {:team-id (:default-team-id prof)}}}})]
@ -37,7 +37,7 @@
res (th/run-task! :process-webhook-event
{:props
{:app.loggers.webhooks/event
{:type "mutation"
{:type "command"
:name "create-project"
:props {:team-id (:default-team-id prof)}}}})]
@ -48,7 +48,7 @@
(with-mocks [http-mock {:target 'app.http.client/req! :return {:status 200}}]
(let [prof (th/create-profile* 1 {:is-active true})
whk (th/create-webhook* {:team-id (:default-team-id prof)})
evt {:type "mutation"
evt {:type "command"
:name "create-project"
:props {:team-id (:default-team-id prof)}}
res (th/run-task! :run-webhook
@ -73,7 +73,7 @@
(with-mocks [http-mock {:target 'app.http.client/req! :return {:status 400}}]
(let [prof (th/create-profile* 1 {:is-active true})
whk (th/create-webhook* {:team-id (:default-team-id prof)})
evt {:type "mutation"
evt {:type "command"
:name "create-project"
:props {:team-id (:default-team-id prof)}}
res (th/run-task! :run-webhook

View file

@ -129,12 +129,12 @@
:mtype "image/jpeg"
:size 312043}
params {::th/type :upload-file-media-object
:profile-id profile-id
::rpc/profile-id profile-id
:file-id file-id
:is-local true
:name "testfile"
:content mfile}
out (th/mutation! params)]
out (th/command! params)]
;; (th/print-result! out)
(t/is (nil? (:error out)))

View file

@ -26,11 +26,11 @@
:is-shared false})
url "https://raw.githubusercontent.com/uxbox/uxbox/develop/sample_media/images/unsplash/anna-pelzer.jpg"
params {::th/type :create-file-media-object-from-url
:profile-id (:id prof)
::rpc/profile-id (:id prof)
:file-id (:id file)
:is-local true
:url url}
out (th/mutation! params)]
out (th/command! params)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
@ -66,12 +66,12 @@
:size 312043}
params {::th/type :upload-file-media-object
:profile-id (:id prof)
::rpc/profile-id (:id prof)
:file-id (:id file)
:is-local true
:name "testfile"
:content mfile}
out (th/mutation! params)]
out (th/command! params)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
@ -105,7 +105,7 @@
:size 312043}
params {::th/type :upload-file-media-object
:profile-id (:id prof)
::rpc/profile-id (:id prof)
:file-id (:id file)
:is-local true
:name "testfile"
@ -113,7 +113,7 @@
:id (uuid/next)}]
;; First try
(let [{:keys [result error] :as out} (th/mutation! params)]
(let [{:keys [result error] :as out} (th/command! params)]
;; (th/print-result! out)
(t/is (nil? error))
(t/is (= (:id params) (:id result)))
@ -125,7 +125,7 @@
(t/is (uuid? (:thumbnail-id result))))
;; Second try
(let [{:keys [result error] :as out} (th/mutation! params)]
(let [{:keys [result error] :as out} (th/command! params)]
;; (th/print-result! out)
(t/is (nil? error))
(t/is (= (:id params) (:id result)))

View file

@ -24,11 +24,11 @@
;; create project
(let [data {::th/type :create-project
::rpc/profile-id (:id profile)
:id project-id
:profile-id (:id profile)
:team-id (:id team)
:name "test project"}
out (th/mutation! data)]
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
@ -36,10 +36,10 @@
(t/is (= (:name data) (:name result)))))
;; query the list of projects of a team
(let [data {::th/type :projects
:team-id (:id team)
:profile-id (:id profile)}
out (th/query! data)]
(let [data {::th/type :get-projects
::rpc/profile-id (:id profile)
:team-id (:id team)}
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
@ -49,9 +49,9 @@
(t/is (= "test project" (get-in result [0 :name])))))
;; query all projects of a user
(let [data {::th/type :all-projects
:profile-id (:id profile)}
out (th/query! data)]
(let [data {::th/type :get-all-projects
::rpc/profile-id (:id profile)}
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
@ -68,19 +68,19 @@
;; rename project
(let [data {::th/type :rename-project
::rpc/profile-id (:id profile)
:id project-id
:name "renamed project"
:profile-id (:id profile)}
out (th/mutation! data)]
:name "renamed project"}
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(t/is (nil? (:result out))))
;; retrieve project
(let [data {::th/type :project
:id project-id
:profile-id (:id profile)}
out (th/query! data)]
(let [data {::th/type :get-project
::rpc/profile-id (:id profile)
:id project-id}
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]
@ -88,19 +88,19 @@
;; delete project
(let [data {::th/type :delete-project
:id project-id
:profile-id (:id profile)}
out (th/mutation! data)]
::rpc/profile-id (:id profile)
:id project-id}
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(t/is (nil? (:result out))))
;; query a list of projects after delete
(let [data {::th/type :projects
:team-id (:id team)
:profile-id (:id profile)}
out (th/query! data)]
(let [data {::th/type :get-projects
::rpc/profile-id (:id profile)
:team-id (:id team)}
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]
@ -112,10 +112,10 @@
profile2 (th/create-profile* 2)
data {::th/type :create-project
:profile-id (:id profile2)
::rpc/profile-id (:id profile2)
:team-id (:default-team-id profile1)
:name "test project"}
out (th/mutation! data)
out (th/command! data)
error (:error out)]
;; (th/print-result! out)
@ -128,10 +128,10 @@
project (th/create-project* 1 {:team-id (:default-team-id profile1)
:profile-id (:id profile1)})
data {::th/type :rename-project
::rpc/profile-id (:id profile2)
:id (:id project)
:profile-id (:id profile2)
:name "foobar"}
out (th/mutation! data)
out (th/command! data)
error (:error out)]
;; (th/print-result! out)
@ -144,9 +144,9 @@
project (th/create-project* 1 {:team-id (:default-team-id profile1)
:profile-id (:id profile1)})
data {::th/type :delete-project
:id (:id project)
:profile-id (:id profile2)}
out (th/mutation! data)
::rpc/profile-id (:id profile2)
:id (:id project)}
out (th/command! data)
error (:error out)]
;; (th/print-result! out)
@ -159,12 +159,12 @@
project (th/create-project* 1 {:team-id (:default-team-id profile1)
:profile-id (:id profile1)})
data {::th/type :update-project-pin
::rpc/profile-id (:id profile2)
:id (:id project)
:team-id (:default-team-id profile1)
:profile-id (:id profile2)
:is-pinned true}
out (th/mutation! data)
out (th/command! data)
error (:error out)]
;; (th/print-result! out)
@ -184,10 +184,10 @@
(t/is (= 0 (:processed result))))
;; query the list of projects
(let [data {::th/type :projects
:team-id (:default-team-id profile1)
:profile-id (:id profile1)}
out (th/query! data)]
(let [data {::th/type :get-projects
::rpc/profile-id (:id profile1)
:team-id (:default-team-id profile1)}
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]
@ -195,16 +195,16 @@
;; Request project to be deleted
(let [params {::th/type :delete-project
:id (:id project)
:profile-id (:id profile1)}
out (th/mutation! params)]
::rpc/profile-id (:id profile1)
:id (:id project)}
out (th/command! params)]
(t/is (nil? (:error out))))
;; query the list of projects after soft deletion
(let [data {::th/type :projects
:team-id (:default-team-id profile1)
:profile-id (:id profile1)}
out (th/query! data)]
(let [data {::th/type :get-projects
::rpc/profile-id (:id profile1)
:team-id (:default-team-id profile1)}
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]

View file

@ -70,12 +70,12 @@
profile-2 (th/create-profile* 2)
team-id (:default-team-id profile-1)
data {::th/type :create-project
:profile-id (:id profile-1)
::rpc/profile-id (:id profile-1)
:team-id team-id}
check-ok! (fn [name]
(let [data (assoc data :name (str "project" name))
out (th/mutation! data)]
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(t/is (some? (:result out)))))
@ -83,7 +83,7 @@
check-ko! (fn [name]
;; create second project
(let [data (assoc data :name (str "project" name))
out (th/mutation! data)]
out (th/command! data)]
;; (th/print-result! out)
(t/is (not (th/success? out)))
(let [error (:error out)]

View file

@ -321,10 +321,10 @@
(t/is (= 0 (:processed result))))
;; query the list of projects after hard deletion
(let [data {::th/type :projects
:profile-id (:id profile1)
(let [data {::th/type :get-projects
::rpc/profile-id (:id profile1)
:team-id (:id team)}
out (th/query! data)]
out (th/command! data)]
;; (th/print-result! out)
(t/is (not (th/success? out)))
(let [edata (-> out :error ex-data)]
@ -335,10 +335,10 @@
(t/is (= 1 (:processed result))))
;; query the list of projects of a after hard deletion
(let [data {::th/type :projects
:profile-id (:id profile1)
(let [data {::th/type :get-projects
::rpc/profile-id (:id profile1)
:team-id (:id team)}
out (th/query! data)]
out (th/command! data)]
;; (th/print-result! out)
(t/is (not (th/success? out)))

View file

@ -9,6 +9,7 @@
[backend-tests.helpers :as th]
[app.common.uuid :as uuid]
[app.db :as db]
[app.rpc :as-alias rpc]
[clojure.test :as t]
[datoteka.core :as fs]))
@ -27,13 +28,13 @@
share-id (atom nil)]
(t/testing "authenticated with page-id"
(let [data {::th/type :view-only-bundle
:profile-id (:id prof)
(let [data {::th/type :get-view-only-bundle
::rpc/profile-id (:id prof)
:file-id (:id file)
:page-id (get-in file [:data :pages 0])
:components-v2 true}
out (th/query! data)]
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
@ -47,12 +48,12 @@
(t/testing "generate share token"
(let [data {::th/type :create-share-link
:profile-id (:id prof)
::rpc/profile-id (:id prof)
:file-id (:id file)
:pages #{(get-in file [:data :pages 0])}
:who-comment "team"
:who-inspect "all"}
out (th/mutation! data)]
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
@ -61,12 +62,12 @@
(reset! share-id (:id result)))))
(t/testing "not authenticated with page-id"
(let [data {::th/type :view-only-bundle
:profile-id (:id prof2)
(let [data {::th/type :get-view-only-bundle
::rpc/profile-id (:id prof2)
:file-id (:id file)
:page-id (get-in file [:data :pages 0])
:components-v2 true}
out (th/query! data)]
out (th/command! data)]
;; (th/print-result! out)
(let [error (:error out)
@ -76,13 +77,13 @@
(t/is (= (:code error-data) :object-not-found)))))
(t/testing "authenticated with token & profile"
(let [data {::th/type :view-only-bundle
:profile-id (:id prof2)
(let [data {::th/type :get-view-only-bundle
::rpc/profile-id (:id prof2)
:share-id @share-id
:file-id (:id file)
:page-id (get-in file [:data :pages 0])
:components-v2 true}
out (th/query! data)]
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
@ -92,12 +93,12 @@
(t/is (contains? result :project)))))
(t/testing "authenticated with token"
(let [data {::th/type :view-only-bundle
(let [data {::th/type :get-view-only-bundle
:share-id @share-id
:file-id (:id file)
:page-id (get-in file [:data :pages 0])
:components-v2 true}
out (th/query! data)]
out (th/command! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))

View file

@ -6,12 +6,13 @@
(ns backend-tests.storage-test
(:require
[backend-tests.helpers :as th]
[app.common.exceptions :as ex]
[app.common.uuid :as uuid]
[app.db :as db]
[app.rpc :as-alias rpc]
[app.storage :as sto]
[app.util.time :as dt]
[backend-tests.helpers :as th]
[clojure.test :as t]
[cuerdas.core :as str]
[datoteka.core :as fs]
@ -134,14 +135,14 @@
:size 312043}
params {::th/type :upload-file-media-object
:profile-id (:id prof)
::rpc/profile-id (:id prof)
:file-id (:id file)
:is-local true
:name "testfile"
:content mfile}
out1 (th/mutation! params)
out2 (th/mutation! params)]
out1 (th/command! params)
out2 (th/command! params)]
(t/is (nil? (:error out1)))
(t/is (nil? (:error out2)))
@ -209,14 +210,14 @@
:size 312043}
params1 {::th/type :upload-file-media-object
:profile-id (:id prof)
::rpc/profile-id (:id prof)
:file-id (:id file)
:is-local true
:name "testfile"
:content mfile}
params2 {::th/type :create-font-variant
:profile-id (:id prof)
::rpc/profile-id (:id prof)
:team-id team-id
:font-id font-id
:font-family "somefont"
@ -224,8 +225,8 @@
:font-style "normal"
:data {"font/ttf" ttfdata}}
out1 (th/mutation! params1)
out2 (th/mutation! params2)]
out1 (th/command! params1)
out2 (th/command! params2)]
;; (th/print-result! out)
@ -275,14 +276,14 @@
:size 312043}
params {::th/type :upload-file-media-object
:profile-id (:id prof)
::rpc/profile-id (:id prof)
:file-id (:id file)
:is-local true
:name "testfile"
:content mfile}
out1 (th/mutation! params)
out2 (th/mutation! params)]
out1 (th/command! params)
out2 (th/command! params)]
(t/is (nil? (:error out1)))
(t/is (nil? (:error out2)))