diff options
author | Alex Gleason <alex@alexgleason.me> | 2021-01-06 14:52:02 -0600 |
---|---|---|
committer | Alex Gleason <alex@alexgleason.me> | 2021-01-06 14:53:22 -0600 |
commit | 4c76e3e3b704b1213d3c6220b81d56b72d8fc7db (patch) | |
tree | b0fa1bfc6772e89920be8bcb70e36a654d320161 /lib | |
parent | 5e128a6be30563adc3b8a938aa68d18ac04cdfa0 (diff) | |
download | pleroma-4c76e3e3b704b1213d3c6220b81d56b72d8fc7db.tar.gz |
Optionally store user IP addresses, #1708
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/ecto_type/ip_address.ex | 22 | ||||
-rw-r--r-- | lib/pleroma/user.ex | 9 | ||||
-rw-r--r-- | lib/pleroma/web/plugs/store_user_ip_plug.ex | 39 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 1 |
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 |