0
Fork 0
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:
Alejandro 2023-01-13 14:33:46 +01:00 committed by GitHub
commit 275eb993ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 23 additions and 201 deletions

View file

@ -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]

View file

@ -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)))

View file

@ -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)}

View file

@ -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")}

View file

@ -1,2 +0,0 @@
ALTER TABLE profile
ADD COLUMN is_admin boolean DEFAULT false;

View file

@ -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

View file

@ -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)

View file

@ -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")))))

View file

@ -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

View file

@ -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))))))

View file

@ -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))

View file

@ -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

View file

@ -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]

View file

@ -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

View file

@ -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