diff --git a/backend/src/app/loggers/audit.clj b/backend/src/app/loggers/audit.clj index 4851373cf..c0ca61da9 100644 --- a/backend/src/app/loggers/audit.clj +++ b/backend/src/app/loggers/audit.clj @@ -80,13 +80,17 @@ (remove #(contains? reserved-props (key %)))) props)) -(defn params->context - "Extract default context properties from RPC params object" +(defn event-from-rpc-params + "Create a base event skeleton with pre-filled some important + data that can be extracted from RPC params object" [params] - (d/without-nils - {:external-session-id (::rpc/external-session-id params) - :event-origin (::rpc/external-event-origin params) - :triggered-by (::rpc/handler-name params)})) + (let [context {:external-session-id (::rpc/external-session-id params) + :external-event-origin (::rpc/external-event-origin params) + :triggered-by (::rpc/handler-name params)}] + {::type "action" + ::profile-id (::rpc/profile-id params) + ::ip-addr (::rpc/ip-addr params) + ::context (d/without-nils context)})) ;; --- SPECS diff --git a/backend/src/app/rpc.clj b/backend/src/app/rpc.clj index 9ee6a0abb..09fff7b89 100644 --- a/backend/src/app/rpc.clj +++ b/backend/src/app/rpc.clj @@ -29,6 +29,7 @@ [app.rpc.rlimit :as rlimit] [app.setup :as-alias setup] [app.storage :as-alias sto] + [app.util.inet :as inet] [app.util.services :as sv] [app.util.time :as dt] [clojure.spec.alpha :as s] @@ -81,7 +82,9 @@ (defn- get-external-event-origin [request] (when-let [origin (rreq/get-header request "x-event-origin")] - (when-not (> (count origin) 256) + (when-not (or (> (count origin) 256) + (= origin "null") + (str/blank? origin)) origin))) (defn- rpc-handler @@ -93,11 +96,13 @@ profile-id (or (::session/profile-id request) (::actoken/profile-id request)) + ip-addr (inet/parse-request request) session-id (get-external-session-id request) event-origin (get-external-event-origin request) data (-> params (assoc ::handler-name handler-name) + (assoc ::ip-addr ip-addr) (assoc ::request-at (dt/now)) (assoc ::external-session-id session-id) (assoc ::external-event-origin event-origin) diff --git a/backend/src/app/rpc/commands/management.clj b/backend/src/app/rpc/commands/management.clj index bf7883175..e7055b47f 100644 --- a/backend/src/app/rpc/commands/management.clj +++ b/backend/src/app/rpc/commands/management.clj @@ -413,15 +413,13 @@ {:modified-at (dt/now)} {:id project-id}) - (let [props (audit/clean-props params) - context (audit/params->context params)] + (let [props (audit/clean-props 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}))) + (let [props (assoc props :id file-id) + event (-> (audit/event-from-rpc-params params) + (assoc ::audit/name "create-file") + (assoc ::audit/props props))] + (audit/submit! cfg event)))) result)))) diff --git a/backend/src/app/rpc/commands/teams.clj b/backend/src/app/rpc/commands/teams.clj index f30bc8870..e01e2ae36 100644 --- a/backend/src/app/rpc/commands/teams.clj +++ b/backend/src/app/rpc/commands/teams.clj @@ -787,18 +787,15 @@ (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/type "action" - ::audit/name (if updated? - "update-team-invitation" - "create-team-invitation") - ::audit/profile-id (:id profile) - ::audit/props props - ::audit/context context})) + (let [props (-> (dissoc tprops :profile-id) + (audit/clean-props)) + evname (if updated? + "update-team-invitation" + "create-team-invitation") + event (-> (audit/event-from-rpc-params params) + (assoc ::audit/name evname) + (assoc ::audit/props props))] + (audit/submit! cfg event)) (eml/send! {::eml/conn conn ::eml/factory eml/invite-to-team @@ -882,62 +879,51 @@ (sv/defmethod ::create-team-with-invitations {::doc/added "1.17" ::sm/params schema:create-team-with-invitations} - [{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id emails role name] :as params}] - (db/with-atomic [conn pool] + [cfg {:keys [::rpc/profile-id emails role name] :as params}] - (let [features (-> (cfeat/get-enabled-features cf/flags) - (cfeat/check-client-features! (:features params))) + (db/tx-run! cfg + (fn [{:keys [::db/conn] :as cfg}] + (let [features (-> (cfeat/get-enabled-features cf/flags) + (cfeat/check-client-features! (:features params))) - params (-> params - (assoc :profile-id profile-id) - (assoc :features features)) + params (-> params + (assoc :profile-id profile-id) + (assoc :features features)) - cfg (assoc cfg ::db/conn conn) - team (create-team cfg params) - profile (db/get-by-id conn :profile profile-id) - emails (into #{} (map profile/clean-email) emails) - context (audit/params->context params)] + cfg (assoc cfg ::db/conn conn) + team (create-team cfg params) + profile (db/get-by-id conn :profile profile-id) + emails (into #{} (map profile/clean-email) emails)] - ;; Create invitations for all provided emails. - (->> emails - (map (fn [email] - (-> params - (assoc :team team) - (assoc :profile profile) - (assoc :email email) - (assoc :role role)))) - (run! (partial create-invitation cfg))) + (let [props {:name name :features features} + event (-> (audit/event-from-rpc-params params) + (assoc ::audit/name "create-team") + (assoc ::audit/props props))] + (audit/submit! cfg event)) - (run! (partial quotes/check-quote! conn) - (list {::quotes/id ::quotes/teams-per-profile - ::quotes/profile-id profile-id} - {::quotes/id ::quotes/invitations-per-team - ::quotes/profile-id profile-id - ::quotes/team-id (:id team) - ::quotes/incr (count emails)} - {::quotes/id ::quotes/profiles-per-team - ::quotes/profile-id profile-id - ::quotes/team-id (:id team) - ::quotes/incr (count emails)})) + ;; Create invitations for all provided emails. + (->> emails + (map (fn [email] + (-> params + (assoc :team team) + (assoc :profile profile) + (assoc :email email) + (assoc :role role)))) + (run! (partial create-invitation cfg))) - (audit/submit! cfg - {::audit/type "action" - ::audit/name "create-team" - ::audit/profile-id profile-id - ::audit/props {:name name - :features features} - ::audit/context context}) + (run! (partial quotes/check-quote! conn) + (list {::quotes/id ::quotes/teams-per-profile + ::quotes/profile-id profile-id} + {::quotes/id ::quotes/invitations-per-team + ::quotes/profile-id profile-id + ::quotes/team-id (:id team) + ::quotes/incr (count emails)} + {::quotes/id ::quotes/profiles-per-team + ::quotes/profile-id profile-id + ::quotes/team-id (:id team) + ::quotes/incr (count emails)})) - (audit/submit! cfg - {::audit/type "command" - ::audit/name "create-team-invitations" - ::audit/profile-id profile-id - ::audit/props {:emails emails - :role role - :profile-id profile-id - :invitations (count emails)}}) - - (vary-meta team assoc ::audit/props {:invitations (count emails)})))) + (vary-meta team assoc ::audit/props {:invitations (count emails)}))))) ;; --- Query: get-team-invitation-token diff --git a/backend/src/app/rpc/commands/verify_token.clj b/backend/src/app/rpc/commands/verify_token.clj index 1fc83bc85..14c9024bc 100644 --- a/backend/src/app/rpc/commands/verify_token.clj +++ b/backend/src/app/rpc/commands/verify_token.clj @@ -169,19 +169,15 @@ ;; if we have logged-in user and it matches the invitation we proceed ;; with accepting the invitation and joining the current profile to the ;; invited team. - (let [context (audit/params->context params) - props {:team-id (:team-id claims) - :role (:role claims) - :invitation-id (:id invitation)}] + (let [props {:team-id (:team-id claims) + :role (:role claims) + :invitation-id (:id invitation)} + event (-> (audit/event-from-rpc-params params) + (assoc ::audit/name "accept-team-invitation") + (assoc ::audit/props props))] (accept-invitation cfg claims invitation profile) - (audit/submit! cfg - {::audit/type "action" - ::audit/name "accept-team-invitation" - ::audit/profile-id profile-id - ::audit/props props - ::audit/context context}) - + (audit/submit! cfg event) (assoc claims :state :created)) (ex/raise :type :validation diff --git a/backend/test/backend_tests/rpc_audit_test.clj b/backend/test/backend_tests/rpc_audit_test.clj index 78d0e4d41..14bff7ea6 100644 --- a/backend/test/backend_tests/rpc_audit_test.clj +++ b/backend/test/backend_tests/rpc_audit_test.clj @@ -28,7 +28,8 @@ ring.request/Request (get-header [_ name] (case name - "x-forwarded-for" "127.0.0.44")))) + "x-forwarded-for" "127.0.0.44" + "x-real-ip" "127.0.0.43")))) (t/deftest push-events-1 (with-redefs [app.config/flags #{:audit-log}] @@ -46,6 +47,7 @@ :profile-id (:id prof) :timestamp (dt/now) :type "action"}]} + params (with-meta params {:app.http/request http-request})