aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlex Gleason <alex@alexgleason.me>2021-01-06 14:52:02 -0600
committerAlex Gleason <alex@alexgleason.me>2021-01-06 14:53:22 -0600
commit4c76e3e3b704b1213d3c6220b81d56b72d8fc7db (patch)
treeb0fa1bfc6772e89920be8bcb70e36a654d320161 /lib
parent5e128a6be30563adc3b8a938aa68d18ac04cdfa0 (diff)
downloadpleroma-4c76e3e3b704b1213d3c6220b81d56b72d8fc7db.tar.gz
Optionally store user IP addresses, #1708
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/ecto_type/ip_address.ex22
-rw-r--r--lib/pleroma/user.ex9
-rw-r--r--lib/pleroma/web/plugs/store_user_ip_plug.ex39
-rw-r--r--lib/pleroma/web/router.ex1
4 files changed, 71 insertions, 0 deletions
diff --git a/lib/pleroma/ecto_type/ip_address.ex b/lib/pleroma/ecto_type/ip_address.ex
new file mode 100644
index 000000000..5b9b5f50e
--- /dev/null
+++ b/lib/pleroma/ecto_type/ip_address.ex
@@ -0,0 +1,22 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.EctoType.IpAddress do
+ alias Postgrex.INET
+ @behaviour Ecto.Type
+
+ def type, do: :inet
+
+ def cast(%INET{address: ip, netmask: nil}), do: {:ok, ip}
+ def cast(ip) when is_tuple(ip), do: {:ok, ip}
+
+ def load(%INET{address: ip, netmask: nil}), do: {:ok, ip}
+
+ def dump(ip) when is_tuple(ip), do: {:ok, %INET{address: ip, netmask: nil}}
+ def dump(_), do: :error
+
+ def equal?(a, b), do: a == b
+
+ def embed_as(_), do: :self
+end
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 52730fd8d..382de29c5 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -146,6 +146,7 @@ defmodule Pleroma.User do
field(:inbox, :string)
field(:shared_inbox, :string)
field(:accepts_chat_messages, :boolean, default: nil)
+ field(:last_known_ip, Pleroma.EctoType.IpAddress)
embeds_one(
:notification_settings,
@@ -2457,4 +2458,12 @@ defmodule Pleroma.User do
def get_host(%User{ap_id: ap_id} = _user) do
URI.parse(ap_id).host
end
+
+ def update_last_known_ip(%User{last_known_ip: ip} = user, ip), do: {:ok, user}
+
+ def update_last_known_ip(%User{} = user, ip) when is_tuple(ip) do
+ user
+ |> change(last_known_ip: ip)
+ |> update_and_set_cache()
+ end
end
diff --git a/lib/pleroma/web/plugs/store_user_ip_plug.ex b/lib/pleroma/web/plugs/store_user_ip_plug.ex
new file mode 100644
index 000000000..5e2245a41
--- /dev/null
+++ b/lib/pleroma/web/plugs/store_user_ip_plug.ex
@@ -0,0 +1,39 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.StoreUserIpPlug do
+ @moduledoc """
+ Stores the user's last known IP address in the database if enabled.
+ User IP addresses are shown in AdminAPI.
+ """
+
+ alias Pleroma.Config
+ alias Pleroma.User
+ import Plug.Conn
+
+ @behaviour Plug
+
+ def init(_), do: nil
+
+ # IP address hasn't changed, so skip
+ def call(
+ %{remote_ip: ip, assigns: %{remote_ip_found: true, user: %User{last_known_ip: ip}}} =
+ conn,
+ _
+ ),
+ do: conn
+
+ # Store user IP if enabled
+ def call(%{remote_ip: ip, assigns: %{remote_ip_found: true, user: %User{} = user}} = conn, _) do
+ with true <- Config.get([__MODULE__, :enabled]),
+ {:ok, %User{} = user} <- User.update_last_known_ip(user, ip) do
+ assign(conn, :user, user)
+ else
+ _ -> conn
+ end
+ end
+
+ # Fail silently
+ def call(conn, _), do: conn
+end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index aefc9f0be..b8565b6dd 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -56,6 +56,7 @@ defmodule Pleroma.Web.Router do
plug(Pleroma.Web.Plugs.UserEnabledPlug)
plug(Pleroma.Web.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Web.Plugs.EnsureUserTokenAssignsPlug)
+ plug(Pleroma.Web.Plugs.StoreUserIpPlug)
end
pipeline :base_api do