diff --git a/backend/src/app/auth/oidc.clj b/backend/src/app/auth/oidc.clj index b48bdc9ac..f340a5141 100644 --- a/backend/src/app/auth/oidc.clj +++ b/backend/src/app/auth/oidc.clj @@ -26,6 +26,7 @@ [app.rpc.commands.profile :as profile] [app.setup :as-alias setup] [app.tokens :as tokens] + [app.util.inet :as inet] [app.util.json :as json] [app.util.time :as dt] [buddy.sign.jwk :as jwk] @@ -574,7 +575,7 @@ (audit/submit! cfg {::audit/type "command" ::audit/name "login-with-oidc" ::audit/profile-id (:id profile) - ::audit/ip-addr (audit/parse-client-ip request) + ::audit/ip-addr (inet/parse-request request) ::audit/props props ::audit/context context}) diff --git a/backend/src/app/loggers/audit.clj b/backend/src/app/loggers/audit.clj index ea00cdd45..4851373cf 100644 --- a/backend/src/app/loggers/audit.clj +++ b/backend/src/app/loggers/audit.clj @@ -21,28 +21,18 @@ [app.rpc :as-alias rpc] [app.rpc.retry :as rtry] [app.setup :as-alias setup] + [app.util.inet :as inet] [app.util.services :as-alias sv] [app.util.time :as dt] [app.worker :as wrk] [clojure.spec.alpha :as s] [cuerdas.core :as str] - [integrant.core :as ig] - [ring.request :as rreq])) + [integrant.core :as ig])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; HELPERS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defn parse-client-ip - [request] - (let [ip-addr (or (some-> (rreq/get-header request "x-forwarded-for") (str/split ",") first) - (rreq/get-header request "x-real-ip") - (some-> (rreq/remote-addr request) str)) - ip-addr (-> ip-addr - (str/split ":" 2) - (first))] - ip-addr)) - (defn extract-utm-params "Extracts additional data from params and namespace them under `penpot` ns." @@ -100,7 +90,6 @@ ;; --- SPECS - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; COLLECTOR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -167,14 +156,16 @@ (assoc :external-session-id session-id) (assoc :external-event-origin event-origin) (assoc :access-token-id (some-> token-id str)) - (d/without-nils))] + (d/without-nils)) + + ip-addr (inet/parse-request request)] {::type (or (::type resultm) (::rpc/type cfg)) ::name (or (::name resultm) (::sv/name mdata)) ::profile-id profile-id - ::ip-addr (some-> request parse-client-ip) + ::ip-addr ip-addr ::props props ::context context @@ -202,7 +193,7 @@ :name (::name event) :type (::type event) :profile-id (::profile-id event) - :ip-addr (::ip-addr event "0.0.0.0") + :ip-addr (::ip-addr event) :context (::context event {}) :props (::props event {}) :source "backend"} @@ -246,8 +237,7 @@ (assoc :created-at tnow) (update :tracked-at #(or % tnow)) (assoc :props {}) - (assoc :context {}) - (assoc :ip-addr "0.0.0.0"))] + (assoc :context {}))] (append-audit-entry! cfg params))) (when (and (contains? cf/flags :webhooks) diff --git a/backend/src/app/rpc/commands/audit.clj b/backend/src/app/rpc/commands/audit.clj index 6af5f5b62..f43195dd7 100644 --- a/backend/src/app/rpc/commands/audit.clj +++ b/backend/src/app/rpc/commands/audit.clj @@ -14,11 +14,12 @@ [app.config :as cf] [app.db :as db] [app.http :as-alias http] - [app.loggers.audit :as audit] + [app.loggers.audit :as-alias audit] [app.rpc :as-alias rpc] [app.rpc.climit :as-alias climit] [app.rpc.doc :as-alias doc] [app.rpc.helpers :as rph] + [app.util.inet :as inet] [app.util.services :as sv] [app.util.time :as dt])) @@ -61,7 +62,7 @@ (defn- handle-events [{:keys [::db/pool]} {:keys [::rpc/profile-id events] :as params}] (let [request (-> params meta ::http/request) - ip-addr (audit/parse-client-ip request) + ip-addr (inet/parse-request request) tnow (dt/now) xform (comp (map (fn [event] diff --git a/backend/src/app/rpc/rlimit.clj b/backend/src/app/rpc/rlimit.clj index 0c0868f93..4e0924490 100644 --- a/backend/src/app/rpc/rlimit.clj +++ b/backend/src/app/rpc/rlimit.clj @@ -51,12 +51,12 @@ [app.common.uuid :as uuid] [app.config :as cf] [app.http :as-alias http] - [app.loggers.audit :refer [parse-client-ip]] [app.redis :as rds] [app.redis.script :as-alias rscript] [app.rpc :as-alias rpc] [app.rpc.helpers :as rph] [app.rpc.rlimit.result :as-alias lresult] + [app.util.inet :as inet] [app.util.services :as-alias sv] [app.util.time :as dt] [app.worker :as wrk] @@ -215,7 +215,7 @@ [{:keys [::rpc/profile-id] :as params}] (let [request (-> params meta ::http/request)] (or profile-id - (some-> request parse-client-ip) + (some-> request inet/parse-request) uuid/zero))) (defn process-request! diff --git a/backend/src/app/util/inet.clj b/backend/src/app/util/inet.clj new file mode 100644 index 000000000..9e3fca606 --- /dev/null +++ b/backend/src/app/util/inet.clj @@ -0,0 +1,37 @@ +;; 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.util.inet + "INET addr parsing and validation helpers" + (:require + [cuerdas.core :as str] + [ring.request :as rreq]) + (:import + com.google.common.net.InetAddresses + java.net.InetAddress)) + +(defn valid? + [s] + (InetAddresses/isInetAddress s)) + +(defn normalize + [s] + (try + (let [addr (InetAddresses/forString s)] + (.getHostAddress ^InetAddress addr)) + (catch Throwable _cause + nil))) + +(defn parse-request + [request] + (or (some-> (rreq/get-header request "x-real-ip") + (normalize)) + (some-> (rreq/get-header request "x-forwarded-for") + (str/split #"\s*,\s*") + (first) + (normalize)) + (some-> (rreq/remote-addr request) + (normalize)))) diff --git a/backend/src/app/util/websocket.clj b/backend/src/app/util/websocket.clj index 70d8eb406..b468c0e28 100644 --- a/backend/src/app/util/websocket.clj +++ b/backend/src/app/util/websocket.clj @@ -11,7 +11,7 @@ [app.common.logging :as l] [app.common.transit :as t] [app.common.uuid :as uuid] - [app.loggers.audit :refer [parse-client-ip]] + [app.util.inet :as inet] [app.util.time :as dt] [promesa.exec :as px] [promesa.exec.csp :as sp] @@ -84,7 +84,7 @@ output-ch (sp/chan :buf output-buff-size) hbeat-ch (sp/chan :buf (sp/sliding-buffer 6)) close-ch (sp/chan) - ip-addr (parse-client-ip request) + ip-addr (inet/parse-request request) uagent (rreq/get-header request "user-agent") id (uuid/next) state (atom {})