mirror of
https://github.com/penpot/penpot.git
synced 2025-03-16 01:31:22 -05:00
Merge pull request #2775 from penpot/niwinz-bugfixes-1
🐛 Several backend bugfixes
This commit is contained in:
commit
275eb993ce
15 changed files with 23 additions and 201 deletions
|
@ -106,9 +106,6 @@
|
||||||
(s/def ::file-change-snapshot-every ::us/integer)
|
(s/def ::file-change-snapshot-every ::us/integer)
|
||||||
(s/def ::file-change-snapshot-timeout ::dt/duration)
|
(s/def ::file-change-snapshot-timeout ::dt/duration)
|
||||||
|
|
||||||
(s/def ::setup-admin-email ::us/email)
|
|
||||||
(s/def ::setup-admin-password ::us/not-empty-string)
|
|
||||||
|
|
||||||
(s/def ::default-executor-parallelism ::us/integer)
|
(s/def ::default-executor-parallelism ::us/integer)
|
||||||
(s/def ::scheduled-executor-parallelism ::us/integer)
|
(s/def ::scheduled-executor-parallelism ::us/integer)
|
||||||
|
|
||||||
|
@ -314,9 +311,6 @@
|
||||||
::srepl-host
|
::srepl-host
|
||||||
::srepl-port
|
::srepl-port
|
||||||
|
|
||||||
::setup-admin-email
|
|
||||||
::setup-admin-password
|
|
||||||
|
|
||||||
::assets-storage-backend
|
::assets-storage-backend
|
||||||
::storage-assets-fs-directory
|
::storage-assets-fs-directory
|
||||||
::storage-assets-s3-bucket
|
::storage-assets-s3-bucket
|
||||||
|
@ -332,8 +326,7 @@
|
||||||
[:enable-backend-api-doc
|
[:enable-backend-api-doc
|
||||||
:enable-backend-worker
|
:enable-backend-worker
|
||||||
:enable-secure-session-cookies
|
:enable-secure-session-cookies
|
||||||
:enable-email-verification
|
:enable-email-verification])
|
||||||
:enable-quotes])
|
|
||||||
|
|
||||||
(defn- parse-flags
|
(defn- parse-flags
|
||||||
[config]
|
[config]
|
||||||
|
|
|
@ -91,9 +91,7 @@
|
||||||
(let [params (:path-params match)
|
(let [params (:path-params match)
|
||||||
result (:result match)
|
result (:result match)
|
||||||
handler (or (:handler result) not-found-handler)
|
handler (or (:handler result) not-found-handler)
|
||||||
request (-> request
|
request (assoc request :path-params params)]
|
||||||
(assoc :path-params params)
|
|
||||||
(update :params merge params))]
|
|
||||||
(handler request respond raise))
|
(handler request respond raise))
|
||||||
(not-found-handler request respond raise)))
|
(not-found-handler request respond raise)))
|
||||||
|
|
||||||
|
|
|
@ -408,9 +408,6 @@
|
||||||
{:port (cf/get :srepl-port)
|
{:port (cf/get :srepl-port)
|
||||||
:host (cf/get :srepl-host)}
|
:host (cf/get :srepl-host)}
|
||||||
|
|
||||||
:app.setup/initial-profile
|
|
||||||
{::db/pool (ig/ref ::db/pool)}
|
|
||||||
|
|
||||||
:app.setup/builtin-templates
|
:app.setup/builtin-templates
|
||||||
{::http.client/client (ig/ref ::http.client/client)}
|
{::http.client/client (ig/ref ::http.client/client)}
|
||||||
|
|
||||||
|
|
|
@ -299,9 +299,6 @@
|
||||||
{:name "0096-del-storage-pending-table"
|
{:name "0096-del-storage-pending-table"
|
||||||
:fn (mg/resource "app/migrations/sql/0096-del-storage-pending-table.sql")}
|
:fn (mg/resource "app/migrations/sql/0096-del-storage-pending-table.sql")}
|
||||||
|
|
||||||
{:name "0097-mod-profile-table"
|
|
||||||
:fn (mg/resource "app/migrations/sql/0097-mod-profile-table.sql")}
|
|
||||||
|
|
||||||
{:name "0098-add-quotes-table"
|
{:name "0098-add-quotes-table"
|
||||||
:fn (mg/resource "app/migrations/sql/0098-add-quotes-table.sql")}
|
:fn (mg/resource "app/migrations/sql/0098-add-quotes-table.sql")}
|
||||||
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
ALTER TABLE profile
|
|
||||||
ADD COLUMN is_admin boolean DEFAULT false;
|
|
|
@ -71,8 +71,8 @@
|
||||||
(defn- rpc-query-handler
|
(defn- rpc-query-handler
|
||||||
"Ring handler that dispatches query requests and convert between
|
"Ring handler that dispatches query requests and convert between
|
||||||
internal async flow into ring async flow."
|
internal async flow into ring async flow."
|
||||||
[methods {:keys [profile-id session-id params] :as request} respond raise]
|
[methods {:keys [profile-id session-id path-params params] :as request} respond raise]
|
||||||
(let [type (keyword (:type params))
|
(let [type (keyword (:type path-params))
|
||||||
data (-> params
|
data (-> params
|
||||||
(assoc ::request-at (dt/now))
|
(assoc ::request-at (dt/now))
|
||||||
(assoc ::http/request request))
|
(assoc ::http/request request))
|
||||||
|
@ -94,8 +94,8 @@
|
||||||
(defn- rpc-mutation-handler
|
(defn- rpc-mutation-handler
|
||||||
"Ring handler that dispatches mutation requests and convert between
|
"Ring handler that dispatches mutation requests and convert between
|
||||||
internal async flow into ring async flow."
|
internal async flow into ring async flow."
|
||||||
[methods {:keys [profile-id session-id params] :as request} respond raise]
|
[methods {:keys [profile-id session-id path-params params] :as request} respond raise]
|
||||||
(let [type (keyword (:type params))
|
(let [type (keyword (:type path-params))
|
||||||
data (-> params
|
data (-> params
|
||||||
(assoc ::request-at (dt/now))
|
(assoc ::request-at (dt/now))
|
||||||
(assoc ::http/request request))
|
(assoc ::http/request request))
|
||||||
|
@ -116,8 +116,8 @@
|
||||||
(defn- rpc-command-handler
|
(defn- rpc-command-handler
|
||||||
"Ring handler that dispatches cmd requests and convert between
|
"Ring handler that dispatches cmd requests and convert between
|
||||||
internal async flow into ring async flow."
|
internal async flow into ring async flow."
|
||||||
[methods {:keys [profile-id session-id params] :as request} respond raise]
|
[methods {:keys [profile-id session-id path-params params] :as request} respond raise]
|
||||||
(let [cmd (keyword (:type params))
|
(let [cmd (keyword (:type path-params))
|
||||||
etag (yrq/get-header request "if-none-match")
|
etag (yrq/get-header request "if-none-match")
|
||||||
|
|
||||||
data (-> params
|
data (-> params
|
||||||
|
@ -290,7 +290,6 @@
|
||||||
(let [cfg (assoc cfg ::type "command" ::metrics-id :rpc-command-timing)]
|
(let [cfg (assoc cfg ::type "command" ::metrics-id :rpc-command-timing)]
|
||||||
(->> (sv/scan-ns 'app.rpc.commands.binfile
|
(->> (sv/scan-ns 'app.rpc.commands.binfile
|
||||||
'app.rpc.commands.comments
|
'app.rpc.commands.comments
|
||||||
'app.rpc.commands.profile
|
|
||||||
'app.rpc.commands.management
|
'app.rpc.commands.management
|
||||||
'app.rpc.commands.verify-token
|
'app.rpc.commands.verify-token
|
||||||
'app.rpc.commands.search
|
'app.rpc.commands.search
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
;; ---- COMMAND: login with password
|
;; ---- COMMAND: login with password
|
||||||
|
|
||||||
(defn login-with-password
|
(defn login-with-password
|
||||||
[{:keys [::db/pool session] :as cfg} {:keys [email password scope] :as params}]
|
[{:keys [::db/pool session] :as cfg} {:keys [email password] :as params}]
|
||||||
|
|
||||||
(when-not (or (contains? cf/flags :login)
|
(when-not (or (contains? cf/flags :login)
|
||||||
(contains? cf/flags :login-with-password))
|
(contains? cf/flags :login-with-password))
|
||||||
|
@ -119,17 +119,8 @@
|
||||||
;; accept invitation with other email
|
;; accept invitation with other email
|
||||||
response (if (and (some? invitation) (= (:id profile) (:member-id invitation)))
|
response (if (and (some? invitation) (= (:id profile) (:member-id invitation)))
|
||||||
{:invitation-token (:invitation-token params)}
|
{:invitation-token (:invitation-token params)}
|
||||||
(update profile :is-admin (fn [admin?]
|
(assoc profile :is-admin (let [admins (cf/get :admins)]
|
||||||
(or admin?
|
(contains? admins (:email profile)))))]
|
||||||
(let [admins (cf/get :admins)]
|
|
||||||
(contains? admins (:email profile)))))))]
|
|
||||||
|
|
||||||
(when (and (nil? (:default-team-id profile))
|
|
||||||
(not= scope "admin"))
|
|
||||||
(ex/raise :type :restriction
|
|
||||||
:code :admin-only-profile
|
|
||||||
:hint "can't login with admin-only profile"))
|
|
||||||
|
|
||||||
(-> response
|
(-> response
|
||||||
(rph/with-transform (session/create-fn session (:id profile)))
|
(rph/with-transform (session/create-fn session (:id profile)))
|
||||||
(rph/with-meta {::audit/props (audit/profile->props profile)
|
(rph/with-meta {::audit/props (audit/profile->props profile)
|
||||||
|
|
|
@ -1,75 +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.commands.profile
|
|
||||||
(:require
|
|
||||||
[app.auth :as auth]
|
|
||||||
[app.common.exceptions :as ex]
|
|
||||||
[app.common.spec :as us]
|
|
||||||
[app.config :as cf]
|
|
||||||
[app.db :as db]
|
|
||||||
[app.rpc :as-alias rpc]
|
|
||||||
[app.rpc.climit :as-alias climit]
|
|
||||||
[app.rpc.doc :as-alias doc]
|
|
||||||
[app.util.services :as sv]
|
|
||||||
[clojure.spec.alpha :as s]))
|
|
||||||
|
|
||||||
;; --- MUTATION: Set profile password
|
|
||||||
|
|
||||||
(declare update-profile-password!)
|
|
||||||
|
|
||||||
(s/def ::profile-id ::us/uuid)
|
|
||||||
(s/def ::password ::us/not-empty-string)
|
|
||||||
|
|
||||||
(s/def ::get-derived-password
|
|
||||||
(s/keys :req [::rpc/profile-id]
|
|
||||||
:req-un [::password]))
|
|
||||||
|
|
||||||
(sv/defmethod ::get-derived-password
|
|
||||||
"Get derived password, only ADMINS allowed to call this RPC
|
|
||||||
methods. Designed for administration pannel integration."
|
|
||||||
{::climit/queue :auth
|
|
||||||
::climit/key-fn ::rpc/profile-id
|
|
||||||
::doc/added "1.18"}
|
|
||||||
[{:keys [::db/pool]} {:keys [::rpc/profile-id password]}]
|
|
||||||
(db/with-atomic [conn pool]
|
|
||||||
(let [admins (cf/get :admins)
|
|
||||||
profile (db/get-by-id conn :profile profile-id)]
|
|
||||||
|
|
||||||
(if (or (:is-admin profile)
|
|
||||||
(contains? admins (:email profile)))
|
|
||||||
{:password (auth/derive-password password)}
|
|
||||||
(ex/raise :type :authentication
|
|
||||||
:code :only-admins-allowed
|
|
||||||
:hint "only admins allowed to call this RPC method")))))
|
|
||||||
|
|
||||||
;; --- MUTATION: Check profile password
|
|
||||||
|
|
||||||
(s/def ::attempt ::us/not-empty-string)
|
|
||||||
(s/def ::check-profile-password
|
|
||||||
(s/keys :req [::rpc/profile-id]
|
|
||||||
:req-un [::profile-id ::password]))
|
|
||||||
|
|
||||||
(sv/defmethod ::check-profile-password
|
|
||||||
"Check profile password, only ADMINS allowed to call this RPC
|
|
||||||
methods. Designed for administration pannel integration."
|
|
||||||
{::climit/queue :auth
|
|
||||||
::climit/key-fn ::rpc/profile-id
|
|
||||||
::doc/added "1.18"}
|
|
||||||
[{:keys [::db/pool]} {:keys [profile-id password] :as params}]
|
|
||||||
(db/with-atomic [conn pool]
|
|
||||||
(let [admins (cf/get :admins)
|
|
||||||
profile (db/get-by-id pool :profile (::rpc/profile-id params))]
|
|
||||||
|
|
||||||
(if (or (:is-admin profile)
|
|
||||||
(contains? admins (:email profile)))
|
|
||||||
(let [profile (if (not= (::rpc/profile-id params) profile-id)
|
|
||||||
(db/get-by-id conn :profile profile-id)
|
|
||||||
profile)]
|
|
||||||
(auth/verify-password password (:password profile)))
|
|
||||||
(ex/raise :type :authentication
|
|
||||||
:code :only-admins-allowed
|
|
||||||
:hint "only admins allowed to call this RPC method")))))
|
|
|
@ -29,7 +29,6 @@
|
||||||
(s/def ::is-active ::us/boolean)
|
(s/def ::is-active ::us/boolean)
|
||||||
(s/def ::mtype
|
(s/def ::mtype
|
||||||
#{"application/json"
|
#{"application/json"
|
||||||
"application/x-www-form-urlencoded"
|
|
||||||
"application/transit+json"})
|
"application/transit+json"})
|
||||||
|
|
||||||
(s/def ::create-webhook
|
(s/def ::create-webhook
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
[app.db :as db]
|
[app.db :as db]
|
||||||
[app.main :as-alias main]
|
[app.main :as-alias main]
|
||||||
[app.setup.builtin-templates]
|
[app.setup.builtin-templates]
|
||||||
[app.setup.initial-user]
|
|
||||||
[app.setup.keys :as keys]
|
[app.setup.keys :as keys]
|
||||||
[buddy.core.codecs :as bc]
|
[buddy.core.codecs :as bc]
|
||||||
[buddy.core.nonce :as bn]
|
[buddy.core.nonce :as bn]
|
||||||
|
@ -69,5 +68,5 @@
|
||||||
(let [secret (or key (generate-random-key))]
|
(let [secret (or key (generate-random-key))]
|
||||||
(-> (retrieve-all conn)
|
(-> (retrieve-all conn)
|
||||||
(assoc :secret-key secret)
|
(assoc :secret-key secret)
|
||||||
(assoc :tokens-key (keys/derive secret :salt "tokens" :size 32))
|
(assoc :tokens-key (keys/derive secret :salt "tokens"))
|
||||||
(update :instance-id handle-instance-id conn (db/read-only? pool))))))
|
(update :instance-id handle-instance-id conn (db/read-only? pool))))))
|
||||||
|
|
|
@ -1,40 +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.setup.initial-user
|
|
||||||
"Initial data setup of instance."
|
|
||||||
(:require
|
|
||||||
[app.auth :as auth]
|
|
||||||
[app.common.logging :as l]
|
|
||||||
[app.config :as cf]
|
|
||||||
[app.db :as db]
|
|
||||||
[app.setup :as-alias setup]
|
|
||||||
[clojure.spec.alpha :as s]
|
|
||||||
[integrant.core :as ig]))
|
|
||||||
|
|
||||||
(def ^:private sql:insert-profile
|
|
||||||
"insert into profile (id, fullname, email, password, is_active, is_admin, created_at, modified_at)
|
|
||||||
values ('00000000-0000-0000-0000-000000000000', 'Admin', ?, ?, true, true, now(), now())
|
|
||||||
on conflict (id)
|
|
||||||
do update set email = ?, password = ?")
|
|
||||||
|
|
||||||
(defmethod ig/pre-init-spec ::setup/initial-profile [_]
|
|
||||||
(s/keys :req [::db/pool]))
|
|
||||||
|
|
||||||
(defmethod ig/init-key ::setup/initial-profile
|
|
||||||
[_ {:keys [::db/pool]}]
|
|
||||||
(let [email (cf/get :setup-admin-email)
|
|
||||||
password (cf/get :setup-admin-password)]
|
|
||||||
(when (and email password)
|
|
||||||
(db/with-atomic [conn pool]
|
|
||||||
(let [pwd (auth/derive-password password)]
|
|
||||||
(db/exec-one! conn [sql:insert-profile email pwd email pwd])
|
|
||||||
(l/info :hint "setting initial user (admin)"
|
|
||||||
:email email
|
|
||||||
:password "********"))))
|
|
||||||
nil))
|
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,10 @@
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
[buddy.core.kdf :as bk]))
|
[buddy.core.kdf :as bk]))
|
||||||
|
|
||||||
|
|
||||||
(defn derive
|
(defn derive
|
||||||
"Derive a key from secret-key"
|
"Derive a key from secret-key"
|
||||||
[secret-key & {:keys [salt size]}]
|
[secret-key & {:keys [salt size] :or {size 32}}]
|
||||||
(us/assert! ::us/not-empty-string secret-key)
|
(us/assert! ::us/not-empty-string secret-key)
|
||||||
(let [engine (bk/engine {:key secret-key
|
(let [engine (bk/engine {:key secret-key
|
||||||
:salt salt
|
:salt salt
|
||||||
|
|
|
@ -175,14 +175,15 @@
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(defn get-error-context
|
(defn get-error-context
|
||||||
[error]
|
[error]
|
||||||
(when-let [data (ex-data error)]
|
(merge
|
||||||
(merge
|
{:hint (ex-message error)}
|
||||||
{:hint (ex-message error)
|
(when-let [data (ex-data error)]
|
||||||
:spec-problems (some->> data ::s/problems (take 10) seq vec)
|
(merge
|
||||||
:spec-value (some->> data ::s/value)
|
{:spec-problems (some->> data ::s/problems (take 10) seq vec)
|
||||||
:data (some-> data (dissoc ::s/problems ::s/value ::s/spec))}
|
:spec-value (some->> data ::s/value)
|
||||||
(when-let [explain (ex/explain data)]
|
:data (some-> data (dissoc ::s/problems ::s/value ::s/spec))}
|
||||||
{:spec-explain explain})))))
|
(when-let [explain (ex/explain data)]
|
||||||
|
{:spec-explain explain}))))))
|
||||||
|
|
||||||
(defmacro log
|
(defmacro log
|
||||||
[& props]
|
[& props]
|
||||||
|
|
|
@ -137,15 +137,6 @@ services:
|
||||||
environment:
|
environment:
|
||||||
- PENPOT_FLAGS=enable-registration enable-login disable-email-verification enable-smtp
|
- PENPOT_FLAGS=enable-registration enable-login disable-email-verification enable-smtp
|
||||||
|
|
||||||
## Setup initial administration user, uncommit only if you are
|
|
||||||
## going to use the penpot-admin; Once uncommented, the special
|
|
||||||
## user will be created on application start. This user can only
|
|
||||||
## be used for access admin, you will not be able to login with
|
|
||||||
## it on penpot application.
|
|
||||||
|
|
||||||
# - PENPOT_SETUP_ADMIN_EMAIL=admin@example.com
|
|
||||||
# - PENPOT_SETUP_ADMIN_PASSWORD=password
|
|
||||||
|
|
||||||
## Public URI. If you are going to expose this instance to the
|
## Public URI. If you are going to expose this instance to the
|
||||||
## internet, or use it under different domain than 'localhost'
|
## internet, or use it under different domain than 'localhost'
|
||||||
## consider using traefik and set the
|
## consider using traefik and set the
|
||||||
|
@ -240,32 +231,6 @@ services:
|
||||||
networks:
|
networks:
|
||||||
- penpot
|
- penpot
|
||||||
|
|
||||||
## An optional admin application for pentpot. It allows manage
|
|
||||||
## users, teams and inspect some parts of the database. You can read
|
|
||||||
## more about it on: https://github.com/penpot/penpot-admin
|
|
||||||
##
|
|
||||||
## Status: EXPERIMENTAL
|
|
||||||
|
|
||||||
# penpot-admin:
|
|
||||||
# image: "penpotapp/admin:alpha"
|
|
||||||
# networks:
|
|
||||||
# - penpot
|
|
||||||
#
|
|
||||||
# depends_on:
|
|
||||||
# - penpot-postgres
|
|
||||||
# - penpot-backend
|
|
||||||
#
|
|
||||||
# environment:
|
|
||||||
# - PENPOT_PUBLIC_URI=http://localhost:9001
|
|
||||||
# - PENPOT_API_URI=http://penpot-frontend/
|
|
||||||
#
|
|
||||||
# - PENPOT_DATABASE_HOST=penpot-postgres
|
|
||||||
# - PENPOT_DATABASE_NAME=penpot
|
|
||||||
# - PENPOT_DATABASE_USERNAME=penpot
|
|
||||||
# - PENPOT_DATABASE_PASSWORD=penpot
|
|
||||||
# - PENPOT_REDIS_URI=redis://penpot-redis/0
|
|
||||||
# - PENPOT_DEBUG="false"
|
|
||||||
|
|
||||||
## A mailcatch service, used as temporal SMTP server. You can access
|
## A mailcatch service, used as temporal SMTP server. You can access
|
||||||
## via HTTP to the port 1080 for read all emails the penpot platform
|
## via HTTP to the port 1080 for read all emails the penpot platform
|
||||||
## has sent. Should be only used as a temporal solution meanwhile
|
## has sent. Should be only used as a temporal solution meanwhile
|
||||||
|
|
|
@ -626,7 +626,6 @@
|
||||||
|
|
||||||
(def valid-webhook-mtypes
|
(def valid-webhook-mtypes
|
||||||
[{:label "application/json" :value "application/json"}
|
[{:label "application/json" :value "application/json"}
|
||||||
{:label "application/x-www-form-urlencoded" :value "application/x-www-form-urlencoded"}
|
|
||||||
{:label "application/transit+json" :value "application/transit+json"}])
|
{:label "application/transit+json" :value "application/transit+json"}])
|
||||||
|
|
||||||
(defn- extract-status
|
(defn- extract-status
|
||||||
|
|
Loading…
Add table
Reference in a new issue