mirror of
https://github.com/penpot/penpot.git
synced 2025-05-13 10:26:38 +02:00
✨ Minor improvements on profile initial data.
This commit is contained in:
parent
510d3cfa33
commit
e3891df243
5 changed files with 67 additions and 72 deletions
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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})))
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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))))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue