Don't sign fetches to instance actor when refreshing their keys

Closes #963

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2021-11-29 10:29:26 +01:00 committed by tykayn
parent e9ca950067
commit 9665b15f96
4 changed files with 17 additions and 14 deletions

View File

@ -14,37 +14,38 @@ defmodule Mobilizon.Federation.ActivityPub.Actor do
@doc """ @doc """
Getting an actor from url, eventually creating it if we don't have it locally or if it needs an update Getting an actor from url, eventually creating it if we don't have it locally or if it needs an update
""" """
@spec get_or_fetch_actor_by_url(url :: String.t(), preload :: boolean()) :: @spec get_or_fetch_actor_by_url(url :: String.t(), options :: Keyword.t()) ::
{:ok, Actor.t()} {:ok, Actor.t()}
| {:error, make_actor_errors} | {:error, make_actor_errors}
| {:error, :no_internal_relay_actor} | {:error, :no_internal_relay_actor}
| {:error, :url_nil} | {:error, :url_nil}
def get_or_fetch_actor_by_url(url, preload \\ false) def get_or_fetch_actor_by_url(url, options \\ [])
def get_or_fetch_actor_by_url(nil, _preload), do: {:error, :url_nil}
def get_or_fetch_actor_by_url("https://www.w3.org/ns/activitystreams#Public", _preload) do def get_or_fetch_actor_by_url("https://www.w3.org/ns/activitystreams#Public", _preload) do
%Actor{url: url} = Relay.get_actor() %Actor{url: url} = Relay.get_actor()
get_or_fetch_actor_by_url(url) get_or_fetch_actor_by_url(url)
end end
def get_or_fetch_actor_by_url(url, preload) do def get_or_fetch_actor_by_url(url, options) when is_binary(url) and is_list(options) do
Logger.debug("Getting or fetching actor by URL #{url}") Logger.debug("Getting or fetching actor by URL #{url}")
preload = Keyword.get(options, :preload, false)
case Actors.get_actor_by_url(url, preload) do case Actors.get_actor_by_url(url, preload) do
{:ok, %Actor{} = cached_actor} -> {:ok, %Actor{} = cached_actor} ->
if Actors.needs_update?(cached_actor) do if Actors.needs_update?(cached_actor) do
__MODULE__.make_actor_from_url(url, preload: preload) __MODULE__.make_actor_from_url(url, options)
else else
{:ok, cached_actor} {:ok, cached_actor}
end end
{:error, :actor_not_found} -> {:error, :actor_not_found} ->
# For tests, see https://github.com/jjh42/mock#not-supported---mocking-internal-function-calls and Mobilizon.Federation.ActivityPubTest # For tests, see https://github.com/jjh42/mock#not-supported---mocking-internal-function-calls and Mobilizon.Federation.ActivityPubTest
__MODULE__.make_actor_from_url(url, preload: preload) __MODULE__.make_actor_from_url(url, options)
end end
end end
def get_or_fetch_actor_by_url(nil, _preload), do: {:error, :url_nil}
@type make_actor_errors :: Fetcher.fetch_actor_errors() | :actor_is_local @type make_actor_errors :: Fetcher.fetch_actor_errors() | :actor_is_local
@doc """ @doc """

View File

@ -210,7 +210,8 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
def handle_incoming( def handle_incoming(
%{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = _data %{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = _data
) do ) do
with {:ok, %Actor{} = followed} <- ActivityPubActor.get_or_fetch_actor_by_url(followed, true), with {:ok, %Actor{} = followed} <-
ActivityPubActor.get_or_fetch_actor_by_url(followed, preload: true),
{:ok, %Actor{} = follower} <- ActivityPubActor.get_or_fetch_actor_by_url(follower), {:ok, %Actor{} = follower} <- ActivityPubActor.get_or_fetch_actor_by_url(follower),
{:ok, activity, object} <- {:ok, activity, object} <-
Actions.Follow.follow(follower, followed, id, false) do Actions.Follow.follow(follower, followed, id, false) do

View File

@ -52,7 +52,8 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do
{:ok, String.t()} {:ok, String.t()}
| {:error, :actor_not_found | :pem_decode_error} | {:error, :actor_not_found | :pem_decode_error}
defp get_public_key_for_url(url) do defp get_public_key_for_url(url) do
with {:ok, %Actor{} = actor} <- ActivityPubActor.get_or_fetch_actor_by_url(url) do with {:ok, %Actor{} = actor} <-
ActivityPubActor.get_or_fetch_actor_by_url(url, ignore_sign_object_fetches: true) do
get_actor_public_key(actor) get_actor_public_key(actor)
end end
end end

View File

@ -126,7 +126,7 @@ defmodule Mobilizon.Federation.ActivityPub.ActorTest do
needs_update?: fn _ -> false end needs_update?: fn _ -> false end
]}, ]},
{ActivityPubActor, [:passthrough], {ActivityPubActor, [:passthrough],
make_actor_from_url: fn @actor_url, preload: false -> make_actor_from_url: fn @actor_url, [] ->
{:ok, {:ok,
%Actor{ %Actor{
preferred_username: "tcit", preferred_username: "tcit",
@ -138,7 +138,7 @@ defmodule Mobilizon.Federation.ActivityPub.ActorTest do
ActivityPubActor.get_or_fetch_actor_by_url(@actor_url) ActivityPubActor.get_or_fetch_actor_by_url(@actor_url)
assert_called(Actors.needs_update?(:_)) assert_called(Actors.needs_update?(:_))
refute called(ActivityPubActor.make_actor_from_url(@actor_url, preload: false)) refute called(ActivityPubActor.make_actor_from_url(@actor_url, []))
end end
# Fetch doesn't use cache if Actors.needs_update? returns true # Fetch doesn't use cache if Actors.needs_update? returns true
@ -155,7 +155,7 @@ defmodule Mobilizon.Federation.ActivityPub.ActorTest do
needs_update?: fn _ -> true end needs_update?: fn _ -> true end
]}, ]},
{ActivityPubActor, [:passthrough], {ActivityPubActor, [:passthrough],
make_actor_from_url: fn @actor_url, preload: false -> make_actor_from_url: fn @actor_url, [] ->
{:ok, {:ok,
%Actor{ %Actor{
preferred_username: "tcit", preferred_username: "tcit",
@ -169,7 +169,7 @@ defmodule Mobilizon.Federation.ActivityPub.ActorTest do
assert_called(ActivityPubActor.get_or_fetch_actor_by_url(@actor_url)) assert_called(ActivityPubActor.get_or_fetch_actor_by_url(@actor_url))
assert_called(Actors.get_actor_by_url(@actor_url, false)) assert_called(Actors.get_actor_by_url(@actor_url, false))
assert_called(Actors.needs_update?(:_)) assert_called(Actors.needs_update?(:_))
assert_called(ActivityPubActor.make_actor_from_url(@actor_url, preload: false)) assert_called(ActivityPubActor.make_actor_from_url(@actor_url, []))
end end
end end
@ -182,7 +182,7 @@ defmodule Mobilizon.Federation.ActivityPub.ActorTest do
assert match?( assert match?(
{:error, :actor_deleted}, {:error, :actor_deleted},
ActivityPubActor.make_actor_from_url(@actor_url, preload: false) ActivityPubActor.make_actor_from_url(@actor_url, [])
) )
end end