Minor improvements on profile initial data.

This commit is contained in:
Andrey Antukh 2021-01-29 17:18:53 +01:00
parent 510d3cfa33
commit e3891df243
5 changed files with 67 additions and 72 deletions

View file

@ -70,8 +70,8 @@
:ldap-auth-fullname-attribute "displayName" :ldap-auth-fullname-attribute "displayName"
:ldap-auth-avatar-attribute "jpegPhoto" :ldap-auth-avatar-attribute "jpegPhoto"
;; :initial-data-project-name "Penpot Onboarding" ;; :initial-data-file "resources/initial-data.json"
;; :initial-data-file "/internal/initial-data.json" ;; :initial-data-project-name "Penpot Oboarding"
}) })
(s/def ::http-server-port ::us/integer) (s/def ::http-server-port ::us/integer)
@ -140,7 +140,7 @@
(s/def ::telemetry-server-enabled ::us/boolean) (s/def ::telemetry-server-enabled ::us/boolean)
(s/def ::telemetry-server-port ::us/integer) (s/def ::telemetry-server-port ::us/integer)
(s/def ::initial-data-project-id ::us/uuid) (s/def ::initial-data-file ::us/string)
(s/def ::initial-data-project-name ::us/string) (s/def ::initial-data-project-name ::us/string)
(s/def ::config (s/def ::config
@ -197,7 +197,7 @@
::telemetry-server-enabled ::telemetry-server-enabled
::telemetry-server-port ::telemetry-server-port
::telemetry-uri ::telemetry-uri
::initial-data-project-id ::initial-data-file
::initial-data-project-name])) ::initial-data-project-name]))
(defn- env->config (defn- env->config

View file

@ -13,12 +13,10 @@
[app.config :as cfg] [app.config :as cfg]
[app.db :as db] [app.db :as db]
[app.rpc.mutations.projects :as projects] [app.rpc.mutations.projects :as projects]
[app.storage :as storage]
[app.util.transit :as tr] [app.util.transit :as tr]
[clojure.tools.logging :as log] [clojure.java.io :as io]
[cuerdas.core :as str]) [cuerdas.core :as str]
(:import java.io.FileOutputStream [datoteka.core :as fs]))
java.io.FileInputStream))
(def sql:file (def sql:file
"select * from file where project_id = ?") "select * from file where project_id = ?")
@ -35,18 +33,10 @@
from file_media_object from file_media_object
where file_id in (select id from file_ids)") where file_id in (select id from file_ids)")
(def sql:file-media-thumbnail
"with file_ids as (select id from file where project_id = ?),
media_ids as (select id from file_media_object where file_id in (select id from file_ids))
select *
from file_media_thumbnail
where media_object_id in (select id from media_ids)")
(defn change-ids (defn change-ids
"Given a collection and a map from ID to ID. Changes all the `keys` properties "Given a collection and a map from ID to ID. Changes all the `keys` properties
so they point to the new ID existing in `map-ids`" so they point to the new ID existing in `map-ids`"
[map-ids coll keys] [map-ids coll keys]
(let [generate-id (let [generate-id
(fn [map-ids {:keys [id]}] (fn [map-ids {:keys [id]}]
(assoc map-ids id (uuid/next))) (assoc map-ids id (uuid/next)))
@ -66,61 +56,57 @@
[new-map-ids (map (partial change-id new-map-ids) coll)])) [new-map-ids (map (partial change-id new-map-ids) coll)]))
(defn create-initial-data-dump (defn create-initial-data-dump
[conn project-id output-file] [conn project-id output-path]
(let [ ;; Retrieve data from templates (let [ ;; Retrieve data from templates
opath (fs/path output-path)
file (db/exec! conn [sql:file, project-id]) file (db/exec! conn [sql:file, project-id])
file-library-rel (db/exec! conn [sql:file-library-rel, project-id]) file-library-rel (db/exec! conn [sql:file-library-rel, project-id])
file-media-object (db/exec! conn [sql:file-media-object, project-id]) file-media-object (db/exec! conn [sql:file-media-object, project-id])
file-media-thumbnail (db/exec! conn [sql:file-media-thumbnail, project-id])
data {:file file data {:file file
:file-library-rel file-library-rel :file-library-rel file-library-rel
:file-media-object file-media-object :file-media-object file-media-object}]
:file-media-thumbnail file-media-thumbnail}] (with-open [output (io/output-stream opath)]
(tr/encode-stream data output)
nil)))
(with-open [output (FileOutputStream. output-file)] (defn read-initial-data
(tr/encode-stream data output)))) [path]
(when (fs/exists? path)
(with-open [input (io/input-stream (fs/path path))]
(tr/decode-stream input))))
(defn create-profile-initial-data (defn create-profile-initial-data
[conn storage profile] [conn profile]
(when-let [initial-data-path (:initial-data-file cfg/config)]
(let [initial-data-file (get cfg/config :initial-data-file) (when-let [{:keys [file file-library-rel file-media-object file-media-thumbnail]} (read-initial-data initial-data-path)]
initial-data (when initial-data-file (let [sample-project-name (:initial-data-project-name cfg/config "Penpot Onboarding")
(with-open [input (FileInputStream. initial-data-file)]
(tr/decode-stream input)))]
(when initial-data
(let [{:keys [file file-library-rel file-media-object file-media-thumbnail]} initial-data
sample-project-name (get cfg/config :initial-data-project-name "Penpot Onboarding")
proj (projects/create-project conn {:profile-id (:id profile) proj (projects/create-project conn {:profile-id (:id profile)
:team-id (:default-team-id profile) :team-id (:default-team-id profile)
:name sample-project-name}) :name sample-project-name})
_ (projects/create-project-profile conn {:project-id (:id proj)
:profile-id (:id profile)})
_ (projects/create-team-project-profile conn {:team-id (:default-team-id profile)
:project-id (:id proj)
:profile-id (:id profile)})
map-ids {} map-ids {}
;; Create new ID's and change the references ;; Create new ID's and change the references
[map-ids file] (change-ids map-ids file #{:id}) [map-ids file] (change-ids map-ids file #{:id})
[map-ids file-library-rel] (change-ids map-ids file-library-rel #{:file-id :library-file-id}) [map-ids file-library-rel] (change-ids map-ids file-library-rel #{:file-id :library-file-id})
[map-ids file-media-object] (change-ids map-ids file-media-object #{:id :file-id :media-id :thumbnail-id}) [map-ids file-media-object] (change-ids map-ids file-media-object #{:id :file-id :media-id :thumbnail-id})
[map-ids file-media-thumbnail] (change-ids map-ids file-media-thumbnail #{:id :media-object-id}) [map-ids file-media-thumbnail] (change-ids map-ids file-media-thumbnail #{:id :media-object-id})
file (->> file (map (fn [data] (assoc data :project-id (:id proj))))) file (map #(assoc % :project-id (:id proj)) file)
file-profile-rel (->> file (map (fn [data] file-profile-rel (map #(array-map :file-id (:id %)
(hash-map :file-id (:id data) :profile-id (:id profile)
:profile-id (:id profile) :is-owner true
:is-owner true :is-admin true
:is-admin true :can-edit true)
:can-edit true))))] file)]
(projects/create-project-profile conn {:project-id (:id proj)
:profile-id (:id profile)})
(projects/create-team-project-profile conn {:team-id (:default-team-id profile)
:project-id (:id proj)
:profile-id (:id profile)})
;; Re-insert into the database ;; Re-insert into the database
(db/insert-multi! conn :file file) (db/insert-multi! conn :file file)

View file

@ -14,6 +14,7 @@
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.config :as cfg] [app.config :as cfg]
[app.db :as db] [app.db :as db]
[app.db.profile-initial-data :refer [create-profile-initial-data]]
[app.rpc.mutations.profile :as profile] [app.rpc.mutations.profile :as profile]
[app.tasks :as tasks] [app.tasks :as tasks]
[app.util.services :as sv] [app.util.services :as sv]
@ -27,7 +28,7 @@
[{:keys [pool] :as cfg} _] [{:keys [pool] :as cfg} _]
(let [id (uuid/next) (let [id (uuid/next)
sem (System/currentTimeMillis) sem (System/currentTimeMillis)
email (str "demo-" sem ".demo@nodomain.com") email (str "demo-" sem ".demo@example.com")
fullname (str "Demo User " sem) fullname (str "Demo User " sem)
password (-> (bn/random-bytes 16) password (-> (bn/random-bytes 16)
(bc/bytes->b64u) (bc/bytes->b64u)
@ -36,7 +37,8 @@
:email email :email email
:fullname fullname :fullname fullname
:demo? true :demo? true
:password password}] :password password
:props {:onboarding-viewed true}}]
(when-not (:allow-demo-users cfg/config) (when-not (:allow-demo-users cfg/config)
(ex/raise :type :validation (ex/raise :type :validation
@ -45,11 +47,13 @@
(db/with-atomic [conn pool] (db/with-atomic [conn pool]
(->> (#'profile/create-profile conn params) (->> (#'profile/create-profile conn params)
(#'profile/create-profile-relations conn)) (#'profile/create-profile-relations conn)
(create-profile-initial-data conn))
;; Schedule deletion of the demo profile ;; Schedule deletion of the demo profile
(tasks/submit! conn {:name "delete-profile" (tasks/submit! conn {:name "delete-profile"
:delay cfg/default-deletion-delay :delay cfg/default-deletion-delay
:props {:profile-id id}}) :props {:profile-id id}})
{:email email {:email email
:password password}))) :password password})))

View file

@ -55,7 +55,7 @@
:opt-un [::token])) :opt-un [::token]))
(sv/defmethod ::register-profile {:auth false :rlimit :password} (sv/defmethod ::register-profile {:auth false :rlimit :password}
[{:keys [pool tokens session storage] :as cfg} {:keys [token] :as params}] [{:keys [pool tokens session] :as cfg} {:keys [token] :as params}]
(when-not (:registration-enabled cfg/config) (when-not (:registration-enabled cfg/config)
(ex/raise :type :restriction (ex/raise :type :restriction
:code :registration-disabled)) :code :registration-disabled))
@ -69,7 +69,7 @@
(check-profile-existence! conn params) (check-profile-existence! conn params)
(let [profile (->> (create-profile conn params) (let [profile (->> (create-profile conn params)
(create-profile-relations conn))] (create-profile-relations conn))]
(create-profile-initial-data conn storage profile) (create-profile-initial-data conn profile)
(if token (if token
;; If token comes in params, this is because the user comes ;; If token comes in params, this is because the user comes
@ -160,18 +160,21 @@
(defn- create-profile (defn- create-profile
"Create the profile entry on the database with limited input "Create the profile entry on the database with limited input
filling all the other fields with defaults." filling all the other fields with defaults."
[conn {:keys [id fullname email password demo?] :as params}] [conn {:keys [id fullname email password demo? props] :as params}]
(let [id (or id (uuid/next)) (let [id (or id (uuid/next))
demo? (if (boolean? demo?) demo? false) demo? (if (boolean? demo?) demo? false)
active? (if demo? true false) active? (if demo? true false)
props (db/tjson (or props {}))
password (derive-password password)] password (derive-password password)]
(db/insert! conn :profile (-> (db/insert! conn :profile
{:id id {:id id
:fullname fullname :fullname fullname
:email (str/lower email) :email (str/lower email)
:password password :password password
:is-active active? :props props
:is-demo demo?}))) :is-active active?
:is-demo demo?})
(update :props db/decode-transit-pgobject))))
(defn- create-profile-relations (defn- create-profile-relations
[conn profile] [conn profile]

View file

@ -44,15 +44,17 @@
(update :data pmg/migrate-data))))) (update :data pmg/migrate-data)))))
;; Examples ;; Examples:
;; (def backup (update-file #uuid "1586e1f0-3e02-11eb-b1d2-556a2f641513" identity)) ;; (def backup (update-file #uuid "1586e1f0-3e02-11eb-b1d2-556a2f641513" identity))
;; (def x (update-file #uuid "1586e1f0-3e02-11eb-b1d2-556a2f641513" (fn [{:keys [data] :as file}] (update-in data [:pages-index #uuid "878278c0-3ef0-11eb-9d67-8551e7624f43" :objects] dissoc nil)))) ;; (def x (update-file
;; #uuid "1586e1f0-3e02-11eb-b1d2-556a2f641513"
;; (fn [{:keys [data] :as file}]
;; (update-in data [:pages-index #uuid "878278c0-3ef0-11eb-9d67-8551e7624f43" :objects] dissoc nil))))
(def default-project-id #uuid "5761a890-3b81-11eb-9e7d-556a2f641513")
(defn initial-data-dump (defn initial-data-dump
([system file] ([system file] (initial-data-dump system default-project-id file))
(let [default-project-id #uuid "5761a890-3b81-11eb-9e7d-556a2f641513"] ([system project-id path]
(initial-data-dump system default-project-id file)))
([system project-id file]
(db/with-atomic [conn (:app.db/pool system)] (db/with-atomic [conn (:app.db/pool system)]
(pid/create-initial-data-dump conn file)))) (pid/create-initial-data-dump conn project-id path))))