mirror of
https://github.com/penpot/penpot.git
synced 2026-07-23 06:28:14 +00:00
♻️ Refactor nitrate audit method and tests
Keep the audit refactor lint-clean after rebasing onto develop. AI-assisted-by: gpt-5
This commit is contained in:
parent
9f029de578
commit
9cb039070f
@ -154,7 +154,7 @@
|
||||
;; COLLECTOR API
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(declare ^:private prepare-context-from-request)
|
||||
(declare prepare-context-from-request)
|
||||
|
||||
;; Defines a service that collects the audit/activity log using
|
||||
;; internal database. Later this audit log can be transferred to
|
||||
@ -183,7 +183,7 @@
|
||||
(def valid-event?
|
||||
(sm/validator schema:event))
|
||||
|
||||
(defn- prepare-context-from-request
|
||||
(defn prepare-context-from-request
|
||||
"Prepare backend event context from request"
|
||||
[request]
|
||||
(let [client-event-origin (get-client-event-origin request)
|
||||
@ -412,7 +412,7 @@
|
||||
(update :ip-addr d/nilv "0.0.0.0")
|
||||
(update :props d/nilv {})
|
||||
(update :context d/nilv {})
|
||||
(assoc :source "backend")
|
||||
(update :source d/nilv "backend")
|
||||
(d/without-nils))]
|
||||
(submit* cfg event)))
|
||||
|
||||
@ -429,7 +429,7 @@
|
||||
(update :profile-id d/nilv uuid/zero)
|
||||
(update :props d/nilv {})
|
||||
(update :context d/nilv {})
|
||||
(assoc :source "backend")
|
||||
(update :source d/nilv "backend")
|
||||
(select-keys event-keys)
|
||||
(check-event))]
|
||||
(db/run! cfg append-audit-entry event))))
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
[app.config :as cf]
|
||||
[app.db :as db]
|
||||
[app.email :as eml]
|
||||
[app.http :as-alias http]
|
||||
[app.http.session :as session]
|
||||
[app.loggers.audit :as audit]
|
||||
[app.media :as media]
|
||||
@ -783,38 +784,42 @@ RETURNING id, deleted_at;")
|
||||
[:map {:title "NitrateAuditEvent"}
|
||||
[:name [:and [:string {:max 250}]
|
||||
[:re #"[\d\w-]{1,50}"]]]
|
||||
[:type {:optional true} ::sm/text]
|
||||
[:profile-id ::sm/uuid]
|
||||
[:props {:optional true} [:map-of :keyword :any]]])
|
||||
[:props {:optional true} [:map-of :keyword :any]]
|
||||
[:context {:optional true} [:map-of :keyword :any]]])
|
||||
|
||||
(def ^:private schema:push-audit-events-params
|
||||
[:map {:title "PushAuditEventsParams"}
|
||||
[:events [:vector schema:nitrate-audit-event]]])
|
||||
|
||||
(defn- submit-nitrate-audit-event
|
||||
[cfg {:keys [name profile-id props]}]
|
||||
(let [now (ct/now)]
|
||||
(audit/submit* cfg {:type "action"
|
||||
:name name
|
||||
:profile-id profile-id
|
||||
:props (or props {})
|
||||
:context {}
|
||||
:tracked-at now
|
||||
:created-at now
|
||||
:source "nitrate"
|
||||
:ip-addr "0.0.0.0"})))
|
||||
|
||||
(sv/defmethod ::push-audit-events
|
||||
"Push audit events from Nitrate to Penpot audit log"
|
||||
"Push audit events from nitrate (strictly for nitrate backend
|
||||
events)"
|
||||
|
||||
{::doc/added "2.19"
|
||||
::audit/skip true
|
||||
::sm/params schema:push-audit-events-params
|
||||
::rpc/auth false}
|
||||
[{:keys [::db/pool] :as cfg} {:keys [events]}]
|
||||
(let [telemetry? (contains? cf/flags :telemetry)
|
||||
audit-log? (contains? cf/flags :audit-log)
|
||||
enabled? (and (not (db/read-only? pool))
|
||||
(or audit-log? telemetry?))]
|
||||
(when (and enabled? (seq events))
|
||||
(run! (partial submit-nitrate-audit-event cfg) events))
|
||||
[cfg {:keys [::rpc/request-at events] :as params}]
|
||||
(let [request (-> params meta ::http/request)
|
||||
context' (-> (audit/prepare-context-from-request request)
|
||||
(assoc :request-id (::rpc/request-id params)))
|
||||
|
||||
ip-addr (::rpc/ip-addr params)]
|
||||
|
||||
(run! (fn [{:keys [type name profile-id props context] :as event}]
|
||||
(let [context (-> (merge context context')
|
||||
(d/without-nils))]
|
||||
(audit/submit cfg {:type (d/nilv type "action")
|
||||
:name name
|
||||
:profile-id profile-id
|
||||
:props (or props {})
|
||||
:context context
|
||||
:tracked-at request-at
|
||||
:ip-addr ip-addr})))
|
||||
events)
|
||||
|
||||
nil))
|
||||
|
||||
|
||||
|
||||
@ -79,59 +79,66 @@
|
||||
:enable-auto-file-snapshot
|
||||
:disable-file-validation])
|
||||
|
||||
(defn state-init
|
||||
(defn init-config
|
||||
([next]
|
||||
(init-config nil next))
|
||||
([extra-flags next]
|
||||
(let [flags (into default-flags extra-flags)]
|
||||
(with-redefs [app.config/flags (flags/parse flags/default flags)
|
||||
app.config/config config
|
||||
app.loggers.audit/submit (constantly nil)
|
||||
app.auth/derive-password identity
|
||||
app.auth/verify-password (fn [a b] {:valid (= a b)})
|
||||
app.common.features/get-enabled-features
|
||||
(fn [& _] app.common.features/supported-features)]
|
||||
(cf/validate! :exit-on-error? false)
|
||||
(fs/create-dir "/tmp/penpot")
|
||||
(next)))))
|
||||
|
||||
(defn init-system
|
||||
[next]
|
||||
(with-redefs [app.config/flags (flags/parse flags/default default-flags)
|
||||
app.config/config config
|
||||
app.loggers.audit/submit (constantly nil)
|
||||
app.auth/derive-password identity
|
||||
app.auth/verify-password (fn [a b] {:valid (= a b)})
|
||||
app.common.features/get-enabled-features (fn [& _] app.common.features/supported-features)]
|
||||
(let [templates [{:id "test"
|
||||
:name "test"
|
||||
:file-uri "test"
|
||||
:thumbnail-uri "test"
|
||||
:path (-> "backend_tests/test_files/template.penpot" io/resource fs/path)}]
|
||||
system (-> (merge main/system-config main/worker-config)
|
||||
(assoc-in [:app.redis/client :app.redis/uri] (:redis-uri config))
|
||||
(assoc-in [::db/pool ::db/uri] (:database-uri config))
|
||||
(assoc-in [::db/pool ::db/username] (:database-username config))
|
||||
(assoc-in [::db/pool ::db/password] (:database-password config))
|
||||
(assoc-in [:app.rpc/methods :app.setup/templates] templates)
|
||||
(assoc-in [:app.rpc/methods :app.setup/templates] templates)
|
||||
(update :app.rpc/rlimit assoc
|
||||
:app.loggers.mattermost/reporter nil
|
||||
:app.loggers.database/reporter nil)
|
||||
(update :app.rpc/methods assoc
|
||||
:app.setup/templates templates
|
||||
:app.loggers.mattermost/reporter nil
|
||||
:app.loggers.database/reporter nil)
|
||||
(dissoc :app.srepl/server
|
||||
:app.http/server
|
||||
:app.http/route
|
||||
:app.setup/templates
|
||||
:app.http.oauth/handler
|
||||
:app.notifications/handler
|
||||
:app.loggers.mattermost/reporter
|
||||
:app.loggers.database/reporter
|
||||
:app.worker/cron
|
||||
:app.worker/dispatcher
|
||||
[:app.main/default :app.worker/runner]
|
||||
[:app.main/webhook :app.worker/runner]))
|
||||
_ (ig/load-namespaces system)
|
||||
system (-> (ig/expand system) (ig/init))]
|
||||
(try
|
||||
(binding [*system* system
|
||||
*pool* (:app.db/pool system)]
|
||||
(next))
|
||||
(finally
|
||||
(ig/halt! system)))))
|
||||
|
||||
(cf/validate! :exit-on-error? false)
|
||||
|
||||
(fs/create-dir "/tmp/penpot")
|
||||
|
||||
(let [templates [{:id "test"
|
||||
:name "test"
|
||||
:file-uri "test"
|
||||
:thumbnail-uri "test"
|
||||
:path (-> "backend_tests/test_files/template.penpot" io/resource fs/path)}]
|
||||
system (-> (merge main/system-config main/worker-config)
|
||||
(assoc-in [:app.redis/client :app.redis/uri] (:redis-uri config))
|
||||
(assoc-in [::db/pool ::db/uri] (:database-uri config))
|
||||
(assoc-in [::db/pool ::db/username] (:database-username config))
|
||||
(assoc-in [::db/pool ::db/password] (:database-password config))
|
||||
(assoc-in [:app.rpc/methods :app.setup/templates] templates)
|
||||
(assoc-in [:app.rpc/methods :app.setup/templates] templates)
|
||||
(update :app.rpc/rlimit assoc
|
||||
:app.loggers.mattermost/reporter nil
|
||||
:app.loggers.database/reporter nil)
|
||||
(update :app.rpc/methods assoc
|
||||
:app.setup/templates templates
|
||||
:app.loggers.mattermost/reporter nil
|
||||
:app.loggers.database/reporter nil)
|
||||
(dissoc :app.srepl/server
|
||||
:app.http/server
|
||||
:app.http/route
|
||||
:app.setup/templates
|
||||
:app.http.oauth/handler
|
||||
:app.notifications/handler
|
||||
:app.loggers.mattermost/reporter
|
||||
:app.loggers.database/reporter
|
||||
:app.worker/cron
|
||||
:app.worker/dispatcher
|
||||
[:app.main/default :app.worker/runner]
|
||||
[:app.main/webhook :app.worker/runner]))
|
||||
_ (ig/load-namespaces system)
|
||||
system (-> (ig/expand system)
|
||||
(ig/init))]
|
||||
(try
|
||||
(binding [*system* system
|
||||
*pool* (:app.db/pool system)]
|
||||
(next))
|
||||
(finally
|
||||
(ig/halt! system))))))
|
||||
(def state-init
|
||||
(t/compose-fixtures init-config init-system))
|
||||
|
||||
(defn database-reset
|
||||
[next]
|
||||
@ -386,29 +393,15 @@
|
||||
(assoc :app.rpc/request-at (ct/now)))))))
|
||||
|
||||
(defn management-command!
|
||||
([data]
|
||||
(management-command! data nil))
|
||||
([{:keys [::type] :as data} flags-to-add]
|
||||
(let [flags (reduce conj cf/flags (or flags-to-add []))
|
||||
|
||||
resolve-management-methods
|
||||
(requiring-resolve 'app.rpc/resolve-management-methods)
|
||||
|
||||
methods
|
||||
(with-redefs [cf/flags flags]
|
||||
(resolve-management-methods *system*))
|
||||
|
||||
[_ method-fn]
|
||||
(get methods type)]
|
||||
|
||||
(when-not method-fn
|
||||
(ex/raise :type :assertion
|
||||
:code :rpc-method-not-found
|
||||
:hint (str/ffmt "management rpc method '%' not found" (name type))))
|
||||
|
||||
(try-on! (method-fn (-> data
|
||||
(dissoc ::type)
|
||||
(assoc :app.rpc/request-at (ct/now))))))))
|
||||
[{:keys [::type] :as data}]
|
||||
(let [[_ method-fn] (get-in *system* [:app.rpc/management-methods type])]
|
||||
(when-not method-fn
|
||||
(ex/raise :type :assertion
|
||||
:code :rpc-method-not-found
|
||||
:hint (str/ffmt "management rpc method '%' not found" (name type))))
|
||||
(try-on! (method-fn (-> data
|
||||
(dissoc ::type)
|
||||
(assoc :app.rpc/request-at (ct/now)))))))
|
||||
|
||||
(defn run-task!
|
||||
([name]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user