0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-10 08:50:57 -05:00

Merge remote-tracking branch 'origin/staging' into develop

This commit is contained in:
Andrey Antukh 2022-02-23 12:00:50 +01:00
commit b183dc3e62
3 changed files with 82 additions and 66 deletions

View file

@ -14,48 +14,56 @@
[app.db :as db] [app.db :as db]
[app.emails :as eml] [app.emails :as eml]
[app.rpc.queries.profile :as profile] [app.rpc.queries.profile :as profile]
[app.worker :as wrk]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[integrant.core :as ig])) [integrant.core :as ig]
[promesa.core :as p]
[promesa.exec :as px]))
(declare send-feedback) (declare ^:private send-feedback)
(declare ^:private handler)
(defmethod ig/pre-init-spec ::handler [_] (defmethod ig/pre-init-spec ::handler [_]
(s/keys :req-un [::db/pool])) (s/keys :req-un [::db/pool ::wrk/executor]))
(defmethod ig/init-key ::handler (defmethod ig/init-key ::handler
[_ {:keys [pool] :as scfg}] [_ {:keys [executor] :as cfg}]
(let [ftoken (cf/get :feedback-token ::no-token) (let [ftoken (cf/get :feedback-token ::no-token)
enabled (contains? cf/flags :user-feedback)] enabled? (contains? cf/flags :user-feedback)]
(fn [{:keys [profile-id] :as request}] (if enabled?
(let [token (get-in request [:headers "x-feedback-token"]) (fn [request respond raise]
params (d/merge (:params request) (-> (px/submit! executor #(handler cfg request))
(:body-params request))] (p/then' respond)
(p/catch raise)))
(fn [_ _ raise]
(raise (ex/error :type :validation
:code :feedback-disabled
:hint "feedback module is disabled"))))))
(when-not enabled (defn- handler
(ex/raise :type :validation [{:keys [pool] :as cfg} {:keys [profile-id] :as request}]
:code :feedback-disabled (let [ftoken (cf/get :feedback-token ::no-token)
:hint "feedback module is disabled")) token (get-in request [:headers "x-feedback-token"])
params (d/merge (:params request)
(:body-params request))]
(cond
(uuid? profile-id)
(let [profile (profile/retrieve-profile-data pool profile-id)
params (assoc params :from (:email profile))]
(send-feedback pool profile params))
(cond (= token ftoken)
(uuid? profile-id) (send-feedback cfg nil params))
(let [profile (profile/retrieve-profile-data pool profile-id)
params (assoc params :from (:email profile))]
(when-not (:is-muted profile)
(send-feedback pool profile params)))
(= token ftoken) {:status 204 :body ""}))
(send-feedback scfg nil params))
{:status 204 :body ""}))))
(s/def ::content ::us/string) (s/def ::content ::us/string)
(s/def ::from ::us/email) (s/def ::from ::us/email)
(s/def ::subject ::us/string) (s/def ::subject ::us/string)
(s/def ::feedback (s/def ::feedback
(s/keys :req-un [::from ::subject ::content])) (s/keys :req-un [::from ::subject ::content]))
(defn send-feedback (defn- send-feedback
[pool profile params] [pool profile params]
(let [params (us/conform ::feedback params) (let [params (us/conform ::feedback params)
destination (cf/get :feedback-destination)] destination (cf/get :feedback-destination)]

View file

@ -22,6 +22,8 @@
[clojure.core.async :as a] [clojure.core.async :as a]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[cuerdas.core :as str] [cuerdas.core :as str]
[promesa.core :as p]
[promesa.exec :as px]
[integrant.core :as ig] [integrant.core :as ig]
[lambdaisland.uri :as u] [lambdaisland.uri :as u]
[promesa.exec :as px])) [promesa.exec :as px]))
@ -79,53 +81,58 @@
(s/keys :req-un [::type ::name ::props ::timestamp ::profile-id] (s/keys :req-un [::type ::name ::props ::timestamp ::profile-id]
:opt-un [::context])) :opt-un [::context]))
(s/def ::frontend-events (s/every ::event)) (s/def ::frontend-events (s/every ::frontend-event))
(defmethod ig/init-key ::http-handler (defmethod ig/init-key ::http-handler
[_ {:keys [executor pool] :as cfg}] [_ {:keys [executor pool] :as cfg}]
(if (db/read-only? pool) (if (or (db/read-only? pool) (not (contains? cf/flags :audit-log)))
(do (do
(l/warn :hint "audit log http handler disabled, db is read-only") (l/warn :hint "audit log http handler disabled or db is read-only")
(constantly {:status 204 :body ""})) (fn [_ respond _]
(fn [{:keys [params profile-id] :as request}] (respond {:status 204 :body ""})))
(when (contains? cf/flags :audit-log)
(let [events (->> (:events params)
(remove #(not= profile-id (:profile-id %)))
(us/conform ::frontend-events))
ip-addr (parse-client-ip request)
cfg (-> cfg
(assoc :source "frontend")
(assoc :events events)
(assoc :ip-addr ip-addr))]
(px/run! executor #(persist-http-events cfg))))
{:status 204 :body ""}))) (letfn [(handler [{:keys [params profile-id] :as request}]
(let [events (->> (:events params)
(remove #(not= profile-id (:profile-id %)))
(us/conform ::frontend-events))
ip-addr (parse-client-ip request)
cfg (-> cfg
(assoc :source "frontend")
(assoc :events events)
(assoc :ip-addr ip-addr))]
(persist-http-events cfg)))
(handle-error [cause]
(let [xdata (ex-data cause)]
(if (= :spec-validation (:code xdata))
(l/error ::l/raw (str "spec validation on persist-events:\n" (us/pretty-explain xdata)))
(l/error :hint "error on persist-events" :cause cause))))]
(fn [request respond raise]
;; Fire and forget, log error in case of errro
(-> (px/submit! executor #(handler request))
(p/catch handle-error))
(respond {:status 204 :body ""})))))
(defn- persist-http-events (defn- persist-http-events
[{:keys [pool events ip-addr source] :as cfg}] [{:keys [pool events ip-addr source] :as cfg}]
(try (let [columns [:id :name :source :type :tracked-at :profile-id :ip-addr :props :context]
(let [columns [:id :name :source :type :tracked-at :profile-id :ip-addr :props :context] prepare-xf (map (fn [event]
prepare-xf (map (fn [event] [(uuid/next)
[(uuid/next) (:name event)
(:name event) source
source (:type event)
(:type event) (:timestamp event)
(:timestamp event) (:profile-id event)
(:profile-id event) (db/inet ip-addr)
(db/inet ip-addr) (db/tjson (:props event))
(db/tjson (:props event)) (db/tjson (d/without-nils (:context event)))]))]
(db/tjson (d/without-nils (:context event)))])) (when (seq events)
events (us/conform ::events events)] (->> (into [] prepare-xf events)
(when (seq events) (db/insert-multi! pool :audit-log columns)))))
(->> (into [] prepare-xf events)
(db/insert-multi! pool :audit-log columns))))
(catch Throwable e
(let [xdata (ex-data e)]
(if (= :spec-validation (:code xdata))
(l/error ::l/raw (str "spec validation on persist-events:\n"
(:explain xdata)))
(l/error :hint "error on persist-events"
:cause e))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Collector ;; Collector

View file

@ -135,7 +135,8 @@
:signature-max-age (dt/duration {:hours 24 :minutes 5})} :signature-max-age (dt/duration {:hours 24 :minutes 5})}
:app.http.feedback/handler :app.http.feedback/handler
{:pool (ig/ref :app.db/pool)} {:pool (ig/ref :app.db/pool)
:executor (ig/ref [::default :app.worker/executor])}
:app.http.oauth/handler :app.http.oauth/handler
{:rpc (ig/ref :app.rpc/rpc) {:rpc (ig/ref :app.rpc/rpc)
@ -280,7 +281,7 @@
:app.loggers.audit/http-handler :app.loggers.audit/http-handler
{:pool (ig/ref :app.db/pool) {:pool (ig/ref :app.db/pool)
:executor (ig/ref [::default :app.worker/executor])} :executor (ig/ref [::worker :app.worker/executor])}
:app.loggers.audit/collector :app.loggers.audit/collector
{:pool (ig/ref :app.db/pool) {:pool (ig/ref :app.db/pool)