0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-15 01:01:30 -05:00

Merge pull request #4772 from penpot/niwinz-audit-enhancements-2

 Minor enhancements to audit events related to clone-template
This commit is contained in:
Alejandro 2024-06-20 07:05:37 +02:00 committed by GitHub
commit 3e6b34c563
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 84 additions and 37 deletions

View file

@ -32,6 +32,7 @@
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[cuerdas.core :as str] [cuerdas.core :as str]
[integrant.core :as ig] [integrant.core :as ig]
[ring.request :as rreq]
[ring.response :as-alias rres])) [ring.response :as-alias rres]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -470,6 +471,9 @@
(some? (:invitation-token state)) (some? (:invitation-token state))
(assoc :invitation-token (:invitation-token state)) (assoc :invitation-token (:invitation-token state))
(some? (:external-session-id state))
(assoc :external-session-id (:external-session-id state))
;; If state token comes with props, merge them. The state token ;; If state token comes with props, merge them. The state token
;; props can contain pm_ and utm_ prefixed query params. ;; props can contain pm_ and utm_ prefixed query params.
(map? (:props state)) (map? (:props state))
@ -560,13 +564,16 @@
{:iss :auth {:iss :auth
:exp (dt/in-future "15m") :exp (dt/in-future "15m")
:props (:props info) :props (:props info)
:profile-id (:id profile)}))] :profile-id (:id profile)}))
props (audit/profile->props profile)
context (d/without-nils {:external-session-id (:external-session-id info)})]
(audit/submit! cfg {::audit/type "command" (audit/submit! cfg {::audit/type "command"
::audit/name "login-with-oidc" ::audit/name "login-with-oidc"
::audit/profile-id (:id profile) ::audit/profile-id (:id profile)
::audit/ip-addr (audit/parse-client-ip request) ::audit/ip-addr (audit/parse-client-ip request)
::audit/props (audit/profile->props profile)}) ::audit/props props
::audit/context context})
(->> (redirect-to-verify-token token) (->> (redirect-to-verify-token token)
(sxf request)))) (sxf request))))
@ -588,9 +595,11 @@
(defn- auth-handler (defn- auth-handler
[cfg {:keys [params] :as request}] [cfg {:keys [params] :as request}]
(let [props (audit/extract-utm-params params) (let [props (audit/extract-utm-params params)
esid (rreq/get-header request "x-external-session-id")
state (tokens/generate (::setup/props cfg) state (tokens/generate (::setup/props cfg)
{:iss :oauth {:iss :oauth
:invitation-token (:invitation-token params) :invitation-token (:invitation-token params)
:external-session-id esid
:props props :props props
:exp (dt/in-future "4h")}) :exp (dt/in-future "4h")})
uri (build-auth-uri cfg state)] uri (build-auth-uri cfg state)]

View file

@ -86,6 +86,13 @@
(remove #(contains? reserved-props (key %)))) (remove #(contains? reserved-props (key %))))
props)) props))
(defn params->context
"Extract default context properties from RPC params object"
[params]
(d/without-nils
{:external-session-id (::rpc/external-session-id params)
:triggered-by (::rpc/handler-name params)}))
;; --- SPECS ;; --- SPECS
@ -140,7 +147,7 @@
(::rpc/profile-id params) (::rpc/profile-id params)
uuid/zero) uuid/zero)
session-id (rreq/get-header request "x-external-session-id") session-id (get params ::rpc/external-session-id)
props (-> (or (::replace-props resultm) props (-> (or (::replace-props resultm)
(-> params (-> params
(merge (::props resultm)) (merge (::props resultm))

View file

@ -79,8 +79,12 @@
profile-id (or (::session/profile-id request) profile-id (or (::session/profile-id request)
(::actoken/profile-id request)) (::actoken/profile-id request))
session-id (rreq/get-header request "x-external-session-id")
data (-> params data (-> params
(assoc ::handler-name handler-name)
(assoc ::request-at (dt/now)) (assoc ::request-at (dt/now))
(assoc ::external-session-id session-id)
(assoc ::session/id (::session/id request)) (assoc ::session/id (::session/id request))
(assoc ::cond/key etag) (assoc ::cond/key etag)
(cond-> (uuid? profile-id) (cond-> (uuid? profile-id)

View file

@ -16,6 +16,7 @@
[app.config :as cf] [app.config :as cf]
[app.db :as db] [app.db :as db]
[app.http.sse :as sse] [app.http.sse :as sse]
[app.loggers.audit :as audit]
[app.loggers.webhooks :as-alias webhooks] [app.loggers.webhooks :as-alias webhooks]
[app.rpc :as-alias rpc] [app.rpc :as-alias rpc]
[app.rpc.commands.files :as files] [app.rpc.commands.files :as files]
@ -397,17 +398,32 @@
;; --- COMMAND: Clone Template ;; --- COMMAND: Clone Template
(defn- clone-template (defn- clone-template
[{:keys [::wrk/executor ::bf.v1/project-id] :as cfg} template] [cfg {:keys [project-id ::rpc/profile-id] :as params} template]
(db/tx-run! cfg (fn [{:keys [::db/conn] :as cfg}] (db/tx-run! cfg (fn [{:keys [::db/conn ::wrk/executor] :as cfg}]
;; NOTE: the importation process performs some operations that ;; NOTE: the importation process performs some operations that
;; are not very friendly with virtual threads, and for avoid ;; are not very friendly with virtual threads, and for avoid
;; unexpected blocking of other concurrent operations we ;; unexpected blocking of other concurrent operations we
;; dispatch that operation to a dedicated executor. ;; dispatch that operation to a dedicated executor.
(let [result (px/submit! executor (partial bf.v1/import-files! cfg template))] (let [cfg (-> cfg
(assoc ::bf.v1/project-id project-id)
(assoc ::bf.v1/profile-id profile-id))
result (px/invoke! executor (partial bf.v1/import-files! cfg template))]
(db/update! conn :project (db/update! conn :project
{:modified-at (dt/now)} {:modified-at (dt/now)}
{:id project-id}) {:id project-id})
(deref result)))))
(let [props (audit/clean-props params)
context (audit/params->context params)]
(doseq [file-id result]
(audit/submit! cfg
{::audit/type "action"
::audit/name "create-file"
::audit/profile-id profile-id
::audit/props (assoc props :id file-id)
::audit/context context})))
result))))
(def ^:private (def ^:private
schema:clone-template schema:clone-template
@ -425,16 +441,14 @@
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id project-id template-id] :as params}] [{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id project-id template-id] :as params}]
(let [project (db/get-by-id pool :project project-id {:columns [:id :team-id]}) (let [project (db/get-by-id pool :project project-id {:columns [:id :team-id]})
_ (teams/check-edition-permissions! pool profile-id (:team-id project)) _ (teams/check-edition-permissions! pool profile-id (:team-id project))
template (tmpl/get-template-stream cfg template-id) template (tmpl/get-template-stream cfg template-id)]
params (-> cfg
(assoc ::bf.v1/project-id (:id project))
(assoc ::bf.v1/profile-id profile-id))]
(when-not template (when-not template
(ex/raise :type :not-found (ex/raise :type :not-found
:code :template-not-found :code :template-not-found
:hint "template not found")) :hint "template not found"))
(sse/response #(clone-template params template)))) (sse/response #(clone-template cfg params template))))
;; --- COMMAND: Get list of builtin templates ;; --- COMMAND: Get list of builtin templates

View file

@ -763,6 +763,7 @@
{:id (:id member)})) {:id (:id member)}))
nil) nil)
(let [id (uuid/next) (let [id (uuid/next)
expire (dt/in-future "168h") ;; 7 days expire (dt/in-future "168h") ;; 7 days
invitation (db/exec-one! conn [sql:upsert-team-invitation id invitation (db/exec-one! conn [sql:upsert-team-invitation id
@ -783,14 +784,19 @@
(when (contains? cf/flags :log-invitation-tokens) (when (contains? cf/flags :log-invitation-tokens)
(l/info :hint "invitation token" :token itoken)) (l/info :hint "invitation token" :token itoken))
(let [props (-> (dissoc tprops :profile-id)
(audit/clean-props))
context (audit/params->context params)]
(audit/submit! cfg (audit/submit! cfg
{::audit/type "action" {::audit/type "action"
::audit/name (if updated? ::audit/name (if updated?
"update-team-invitation" "update-team-invitation"
"create-team-invitation") "create-team-invitation")
::audit/profile-id (:id profile) ::audit/profile-id (:id profile)
::audit/props (-> (dissoc tprops :profile-id) ::audit/props props
(d/without-nils))}) ::audit/context context}))
(eml/send! {::eml/conn conn (eml/send! {::eml/conn conn
::eml/factory eml/invite-to-team ::eml/factory eml/invite-to-team
@ -850,10 +856,11 @@
;; We don't re-send inviation to already existing members ;; We don't re-send inviation to already existing members
(remove (partial contains? members)) (remove (partial contains? members))
(map (fn [email] (map (fn [email]
{:email email (-> params
:team team (assoc :email email)
:profile profile (assoc :team team)
:role role})) (assoc :profile profile)
(assoc :role role))))
(keep (partial create-invitation cfg))) (keep (partial create-invitation cfg)))
emails)] emails)]
(with-meta {:total (count invitations) (with-meta {:total (count invitations)
@ -879,9 +886,11 @@
(let [features (-> (cfeat/get-enabled-features cf/flags) (let [features (-> (cfeat/get-enabled-features cf/flags)
(cfeat/check-client-features! (:features params))) (cfeat/check-client-features! (:features params)))
params (assoc params
:profile-id profile-id params (-> params
:features features) (assoc :profile-id profile-id)
(assoc :features features))
cfg (assoc cfg ::db/conn conn) cfg (assoc cfg ::db/conn conn)
team (create-team cfg params) team (create-team cfg params)
profile (db/get-by-id conn :profile profile-id) profile (db/get-by-id conn :profile profile-id)
@ -890,10 +899,11 @@
;; Create invitations for all provided emails. ;; Create invitations for all provided emails.
(->> emails (->> emails
(map (fn [email] (map (fn [email]
{:team team (-> params
:profile profile (assoc :team team)
:email email (assoc :profile profile)
:role role})) (assoc :email email)
(assoc :role role))))
(run! (partial create-invitation cfg))) (run! (partial create-invitation cfg)))
(run! (partial quotes/check-quote! conn) (run! (partial quotes/check-quote! conn)

View file

@ -137,6 +137,7 @@
(->> (http/send! {:method :post (->> (http/send! {:method :post
:uri uri :uri uri
:credentials "include" :credentials "include"
:headers {"x-external-session-id" (cf/external-session-id)}
:query params}) :query params})
(rx/map http/conditional-decode-transit) (rx/map http/conditional-decode-transit)
(rx/mapcat handle-response)))) (rx/mapcat handle-response))))
@ -146,6 +147,7 @@
(->> (http/send! {:method :post (->> (http/send! {:method :post
:uri (u/join cf/public-uri "api/export") :uri (u/join cf/public-uri "api/export")
:body (http/transit-data (dissoc params :blob?)) :body (http/transit-data (dissoc params :blob?))
:headers {"x-external-session-id" (cf/external-session-id)}
:credentials "include" :credentials "include"
:response-type (if blob? :blob :text)}) :response-type (if blob? :blob :text)})
(rx/map http/conditional-decode-transit) (rx/map http/conditional-decode-transit)
@ -165,6 +167,7 @@
(->> (http/send! {:method :post (->> (http/send! {:method :post
:uri (u/join cf/public-uri "api/rpc/command/" (name id)) :uri (u/join cf/public-uri "api/rpc/command/" (name id))
:credentials "include" :credentials "include"
:headers {"x-external-session-id" (cf/external-session-id)}
:body (http/form-data params)}) :body (http/form-data params)})
(rx/map http/conditional-decode-transit) (rx/map http/conditional-decode-transit)
(rx/mapcat handle-response))) (rx/mapcat handle-response)))