instances: drop has_request_signatures

This property was introduced as a way to gauge whether and
how much enabling authfetch might break passive federation in
#312.

However, with the db field defaulting to false, there’s no distinction
between instances without valid signatures and those which just never
attempted to fetch anything from the local instance.
Furthermore, this was never exposed anywhere and required manually
checking the database or cachex state via a remote shell.

Given the above it appears this doesn't actually
provide anything useful, thus drop it.
This commit is contained in:
Oneric 2025-02-02 02:13:31 +01:00
parent f2ca71f1ad
commit 8dad70e8e7
7 changed files with 10 additions and 122 deletions

View file

@ -161,7 +161,6 @@ defp cachex_children do
build_cachex("banned_urls", default_ttl: :timer.hours(24 * 30), limit: 5_000),
build_cachex("translations", default_ttl: :timer.hours(24 * 30), limit: 2500),
build_cachex("instances", default_ttl: :timer.hours(24), ttl_interval: 1000, limit: 2500),
build_cachex("request_signatures", default_ttl: :timer.hours(24 * 30), limit: 3000),
build_cachex("rel_me", default_ttl: :timer.hours(24 * 30), limit: 300),
build_cachex("host_meta", default_ttl: :timer.minutes(120), limit: 5000),
build_cachex("http_backoff", default_ttl: :timer.hours(24 * 30), limit: 10000)

View file

@ -43,6 +43,4 @@ def host(url_or_host) when is_binary(url_or_host) do
url_or_host
end
end
defdelegate set_request_signatures(url_or_host), to: Instance
end

View file

@ -26,7 +26,6 @@ defmodule Pleroma.Instances.Instance do
field(:favicon, :string)
field(:metadata_updated_at, :naive_datetime)
field(:nodeinfo, :map, default: %{})
field(:has_request_signatures, :boolean)
timestamps()
end
@ -40,8 +39,7 @@ def changeset(struct, params \\ %{}) do
:unreachable_since,
:favicon,
:nodeinfo,
:metadata_updated_at,
:has_request_signatures
:metadata_updated_at
])
|> validate_required([:host])
|> unique_constraint(:host)
@ -332,24 +330,4 @@ def get_cached_by_url(url_or_host) do
end)
end
end
def set_request_signatures(url_or_host) when is_binary(url_or_host) do
host = host(url_or_host)
existing_record = Repo.get_by(Instance, %{host: host})
changes = %{has_request_signatures: true}
cond do
is_nil(existing_record) ->
%Instance{}
|> changeset(Map.put(changes, :host, host))
|> Repo.insert()
true ->
existing_record
|> changeset(changes)
|> Repo.update()
end
end
def set_request_signatures(_), do: {:error, :invalid_input}
end

View file

@ -10,10 +10,8 @@ defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
use Pleroma.Web, :verified_routes
alias Pleroma.Activity
alias Pleroma.Instances
require Logger
@cachex Pleroma.Config.get([:cachex, :provider], Cachex)
def init(options) do
options
@ -27,7 +25,6 @@ def call(conn, _opts) do
if get_format(conn) in ["json", "activity+json"] do
conn
|> maybe_assign_valid_signature()
|> maybe_record_signature_success()
else
conn
end
@ -110,36 +107,4 @@ defp maybe_assign_valid_signature(conn) do
defp has_signature_header?(conn) do
conn |> get_req_header("signature") |> Enum.at(0, false)
end
defp maybe_record_signature_success(
%{assigns: %{valid_signature: true, signature_user: signature_user}} = conn
) do
# inboxes implicitly need http signatures for authentication
# so we don't really know if the instance will have broken federation after
# we turn on authorized_fetch_mode.
#
# to "check" this is a signed fetch, verify if method is GET
if conn.method == "GET" do
actor_host = URI.parse(signature_user.ap_id).host
case @cachex.get(:request_signatures_cache, actor_host) do
{:ok, nil} ->
Logger.debug("Successful signature from #{actor_host}")
Instances.set_request_signatures(actor_host)
@cachex.put(:request_signatures_cache, actor_host, true)
{:ok, true} ->
:noop
any ->
Logger.warning(
"expected request signature cache to return a boolean, instead got #{inspect(any)}"
)
end
end
conn
end
defp maybe_record_signature_success(conn), do: conn
end

View file

@ -0,0 +1,9 @@
defmodule Pleroma.Repo.Migrations.DropInstanceHasRequestSignatures do
use Ecto.Migration
def change do
alter table(:instances) do
remove(:has_request_signatures, :boolean, default: false, null: false)
end
end
end

View file

@ -4,7 +4,6 @@
defmodule Pleroma.InstancesTest do
alias Pleroma.Instances
alias Pleroma.Instances.Instance
use Pleroma.DataCase
@ -122,21 +121,4 @@ test "keeps unreachable url or host unreachable" do
refute Instances.reachable?(host)
end
end
describe "set_request_signatures/1" do
test "sets instance has request signatures" do
host = "domain.com"
{:ok, instance} = Instances.set_request_signatures(host)
assert instance.has_request_signatures
{:ok, cached_instance} = Instance.get_cached_by_url(host)
assert cached_instance.has_request_signatures
end
test "returns error status on non-binary input" do
assert {:error, _} = Instances.set_request_signatures(nil)
assert {:error, _} = Instances.set_request_signatures(1)
end
end
end

View file

@ -7,8 +7,6 @@ defmodule Pleroma.Web.Plugs.HTTPSignaturePlugTest do
@moduletag :mocked
import Pleroma.Factory
alias Pleroma.Web.Plugs.HTTPSignaturePlug
alias Pleroma.Instances.Instance
alias Pleroma.Repo
import Plug.Conn
import Phoenix.Controller, only: [put_format: 2]
@ -41,20 +39,6 @@ defmodule Pleroma.Web.Plugs.HTTPSignaturePlugTest do
:ok
end
defp submit_to_plug(host), do: submit_to_plug(host, :get, "/doesntmattter")
defp submit_to_plug(host, method, path) do
params = %{"actor" => "http://#{host}/users/admin"}
build_conn(method, path, params)
|> put_req_header(
"signature",
"keyId=\"http://#{host}/users/admin#main-key"
)
|> put_format("activity+json")
|> HTTPSignaturePlug.call(%{})
end
test "it call HTTPSignatures to check validity if the actor signed it", %{user: user} do
params = %{"actor" => user.ap_id}
conn = build_conn(:get, "/doesntmattter", params)
@ -74,33 +58,6 @@ test "it call HTTPSignatures to check validity if the actor signed it", %{user:
assert called(HTTPSignatures.validate_conn(:_, :_))
end
test "it sets request signatures property on the instance" do
host = "mastodon.example.org"
conn = submit_to_plug(host)
assert conn.assigns.valid_signature == true
instance = Repo.get_by(Instance, %{host: host})
assert instance.has_request_signatures
end
test "it does not set request signatures property on the instance when using inbox" do
host = "mastodon.example.org"
conn = submit_to_plug(host, :post, "/inbox")
assert conn.assigns.valid_signature == true
# we don't even create the instance entry if its just POST /inbox
refute Repo.get_by(Instance, %{host: host})
end
test "it does not set request signatures property on the instance when its cached" do
host = "mastodon.example.org"
Cachex.put(:request_signatures_cache, host, true)
conn = submit_to_plug(host)
assert conn.assigns.valid_signature == true
# we don't even create the instance entry if it was already done
refute Repo.get_by(Instance, %{host: host})
end
describe "requires a signature when `authorized_fetch_mode` is enabled" do
setup do
clear_config([:activitypub, :authorized_fetch_mode], true)