From 280f461ba7681c83b4eb80a3613ad609f3beb435 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 22 Apr 2021 12:17:56 +0200 Subject: [PATCH] Refactor the ActivityPub module Signed-off-by: Thomas Citharel --- lib/federation/activity_pub/activity_pub.ex | 134 +----------------- lib/federation/activity_pub/actor.ex | 102 +++++++++++++ lib/federation/activity_pub/federator.ex | 4 +- lib/federation/activity_pub/fetcher.ex | 37 +++++ lib/federation/activity_pub/refresher.ex | 5 +- lib/federation/activity_pub/relay.ex | 16 ++- lib/federation/activity_pub/transmogrifier.ex | 59 ++++---- lib/federation/activity_pub/utils.ex | 8 +- .../activity_stream/converter/discussion.ex | 6 +- .../activity_stream/converter/flag.ex | 7 +- .../activity_stream/converter/member.ex | 6 +- .../activity_stream/converter/post.ex | 6 +- .../activity_stream/converter/resource.ex | 5 +- .../activity_stream/converter/todo.ex | 3 +- .../activity_stream/converter/todo_list.ex | 4 +- .../activity_stream/converter/utils.ex | 7 +- lib/federation/http_signatures/signature.ex | 6 +- lib/federation/web_finger/web_finger.ex | 4 +- lib/graphql/api/search.ex | 3 +- lib/graphql/resolvers/group.ex | 5 +- lib/graphql/resolvers/member.ex | 3 +- lib/graphql/resolvers/person.ex | 3 +- lib/mix/tasks/mobilizon/actors/refresh.ex | 6 +- .../controllers/activity_pub_controller.ex | 3 +- lib/web/plugs/mapped_signature_to_identity.ex | 4 +- .../activity_pub/activity_pub_test.exs | 115 +-------------- test/federation/activity_pub/actor_test.exs | 120 ++++++++++++++++ .../transmogrifier/delete_test.exs | 10 +- .../transmogrifier/posts_test.exs | 1 - .../activity_pub/transmogrifier_test.exs | 11 +- test/graphql/api/search_test.exs | 5 +- test/mobilizon/actors/actors_test.exs | 9 +- 32 files changed, 385 insertions(+), 332 deletions(-) create mode 100644 lib/federation/activity_pub/actor.ex create mode 100644 test/federation/activity_pub/actor_test.exs diff --git a/lib/federation/activity_pub/activity_pub.ex b/lib/federation/activity_pub/activity_pub.ex index 08cd8e825..67be09626 100644 --- a/lib/federation/activity_pub/activity_pub.ex +++ b/lib/federation/activity_pub/activity_pub.ex @@ -39,11 +39,12 @@ defmodule Mobilizon.Federation.ActivityPub do Visibility } + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor + alias Mobilizon.Federation.ActivityPub.Types.{Managable, Ownable} - alias Mobilizon.Federation.ActivityStream.{Converter, Convertible} + alias Mobilizon.Federation.ActivityStream.Convertible alias Mobilizon.Federation.HTTPSignatures.Signature - alias Mobilizon.Federation.WebFinger alias Mobilizon.Service.Notifications.Scheduler alias Mobilizon.Storage.Page @@ -154,40 +155,6 @@ defmodule Mobilizon.Federation.ActivityPub do end end - @doc """ - 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(String.t(), boolean) :: {:ok, Actor.t()} | {:error, String.t()} - def get_or_fetch_actor_by_url(url, preload \\ false) - - def get_or_fetch_actor_by_url(nil, _preload), do: {:error, "Can't fetch a nil url"} - - def get_or_fetch_actor_by_url("https://www.w3.org/ns/activitystreams#Public", _preload) do - with %Actor{url: url} <- Relay.get_actor() do - get_or_fetch_actor_by_url(url) - end - end - - @spec get_or_fetch_actor_by_url(String.t(), boolean()) :: {:ok, Actor.t()} | {:error, any()} - def get_or_fetch_actor_by_url(url, preload) do - with {:ok, %Actor{} = cached_actor} <- Actors.get_actor_by_url(url, preload), - false <- Actors.needs_update?(cached_actor) do - {:ok, cached_actor} - else - _ -> - # For tests, see https://github.com/jjh42/mock#not-supported---mocking-internal-function-calls and Mobilizon.Federation.ActivityPubTest - case __MODULE__.make_actor_from_url(url, preload) do - {:ok, %Actor{} = actor} -> - {:ok, actor} - - {:error, err} -> - Logger.debug("Could not fetch by AP id") - Logger.debug(inspect(err)) - {:error, "Could not fetch by AP id"} - end - end - end - @doc """ Create an activity of type `Create` @@ -302,7 +269,8 @@ defmodule Mobilizon.Federation.ActivityPub do local \\ true, public \\ true ) do - with {:ok, %Actor{id: object_owner_actor_id}} <- get_or_fetch_actor_by_url(object["actor"]), + with {:ok, %Actor{id: object_owner_actor_id}} <- + ActivityPubActor.get_or_fetch_actor_by_url(object["actor"]), {:ok, %Share{} = _share} <- Share.create(object["id"], actor.id, object_owner_actor_id), announce_data <- make_announce_data(actor, object, activity_id, public), {:ok, activity} <- create_activity(announce_data, local), @@ -619,64 +587,6 @@ defmodule Mobilizon.Federation.ActivityPub do end end - @doc """ - Create an actor locally by its URL (AP ID) - """ - @spec make_actor_from_url(String.t(), boolean()) :: {:ok, %Actor{}} | {:error, any()} - def make_actor_from_url(url, preload \\ false) do - if are_same_origin?(url, Endpoint.url()) do - {:error, "Can't make a local actor from URL"} - else - case fetch_and_prepare_actor_from_url(url) do - {:ok, data} -> - Actors.upsert_actor(data, preload) - - # Request returned 410 - {:error, :actor_deleted} -> - Logger.info("Actor was deleted") - {:error, :actor_deleted} - - {:error, e} -> - Logger.warn("Failed to make actor from url") - {:error, e} - end - end - end - - @doc """ - Find an actor in our local database or call WebFinger to find what's its AP ID is and then fetch it - """ - @spec find_or_make_actor_from_nickname(String.t(), atom() | nil) :: tuple() - def find_or_make_actor_from_nickname(nickname, type \\ nil) do - case Actors.get_actor_by_name(nickname, type) do - %Actor{} = actor -> - {:ok, actor} - - nil -> - make_actor_from_nickname(nickname) - end - end - - @spec find_or_make_person_from_nickname(String.t()) :: tuple() - def find_or_make_person_from_nickname(nick), do: find_or_make_actor_from_nickname(nick, :Person) - - @spec find_or_make_group_from_nickname(String.t()) :: tuple() - def find_or_make_group_from_nickname(nick), do: find_or_make_actor_from_nickname(nick, :Group) - - @doc """ - Create an actor inside our database from username, using WebFinger to find out its AP ID and then fetch it - """ - @spec make_actor_from_nickname(String.t()) :: {:ok, %Actor{}} | {:error, any()} - def make_actor_from_nickname(nickname) do - case WebFinger.finger(nickname) do - {:ok, url} when is_binary(url) -> - make_actor_from_url(url) - - _e -> - {:error, "No ActivityPub URL found in WebFinger"} - end - end - @spec is_create_activity?(Activity.t()) :: boolean defp is_create_activity?(%Activity{data: %{"type" => "Create"}}), do: true defp is_create_activity?(_), do: false @@ -794,40 +704,6 @@ defmodule Mobilizon.Federation.ActivityPub do ) end - # Fetching a remote actor's information through its AP ID - @spec fetch_and_prepare_actor_from_url(String.t()) :: {:ok, map()} | {:error, atom()} | any() - defp fetch_and_prepare_actor_from_url(url) do - Logger.debug("Fetching and preparing actor from url") - Logger.debug(inspect(url)) - - res = - with {:ok, %{status: 200, body: body}} <- - Tesla.get(url, - headers: [{"Accept", "application/activity+json"}], - follow_redirect: true - ), - :ok <- Logger.debug("response okay, now decoding json"), - {:ok, data} <- Jason.decode(body) do - Logger.debug("Got activity+json response at actor's endpoint, now converting data") - {:ok, Converter.Actor.as_to_model_data(data)} - else - # Actor is gone, probably deleted - {:ok, %{status: 410}} -> - Logger.info("Response HTTP 410") - {:error, :actor_deleted} - - {:error, e} -> - Logger.warn("Could not decode actor at fetch #{url}, #{inspect(e)}") - {:error, e} - - e -> - Logger.warn("Could not decode actor at fetch #{url}, #{inspect(e)}") - {:error, e} - end - - res - end - @doc """ Return all public activities (events & comments) for an actor """ diff --git a/lib/federation/activity_pub/actor.ex b/lib/federation/activity_pub/actor.ex new file mode 100644 index 000000000..aad2f2f6a --- /dev/null +++ b/lib/federation/activity_pub/actor.ex @@ -0,0 +1,102 @@ +defmodule Mobilizon.Federation.ActivityPub.Actor do + @moduledoc """ + Module to handle ActivityPub Actor interactions + """ + + alias Mobilizon.Actors + alias Mobilizon.Actors.Actor + alias Mobilizon.Federation.ActivityPub.{Fetcher, Relay} + alias Mobilizon.Federation.WebFinger + alias Mobilizon.Web.Endpoint + require Logger + import Mobilizon.Federation.ActivityPub.Utils, only: [are_same_origin?: 2] + + @doc """ + 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(String.t(), boolean) :: {:ok, Actor.t()} | {:error, String.t()} + def get_or_fetch_actor_by_url(url, preload \\ false) + + def get_or_fetch_actor_by_url(nil, _preload), do: {:error, "Can't fetch a nil url"} + + def get_or_fetch_actor_by_url("https://www.w3.org/ns/activitystreams#Public", _preload) do + with %Actor{url: url} <- Relay.get_actor() do + get_or_fetch_actor_by_url(url) + end + end + + @spec get_or_fetch_actor_by_url(String.t(), boolean()) :: {:ok, Actor.t()} | {:error, any()} + def get_or_fetch_actor_by_url(url, preload) do + with {:ok, %Actor{} = cached_actor} <- Actors.get_actor_by_url(url, preload), + false <- Actors.needs_update?(cached_actor) do + {:ok, cached_actor} + else + _ -> + # For tests, see https://github.com/jjh42/mock#not-supported---mocking-internal-function-calls and Mobilizon.Federation.ActivityPubTest + case __MODULE__.make_actor_from_url(url, preload) do + {:ok, %Actor{} = actor} -> + {:ok, actor} + + {:error, err} -> + Logger.debug("Could not fetch by AP id") + Logger.debug(inspect(err)) + {:error, "Could not fetch by AP id"} + end + end + end + + @doc """ + Create an actor locally by its URL (AP ID) + """ + @spec make_actor_from_url(String.t(), boolean()) :: {:ok, %Actor{}} | {:error, any()} + def make_actor_from_url(url, preload \\ false) do + if are_same_origin?(url, Endpoint.url()) do + {:error, "Can't make a local actor from URL"} + else + case Fetcher.fetch_and_prepare_actor_from_url(url) do + {:ok, data} -> + Actors.upsert_actor(data, preload) + + # Request returned 410 + {:error, :actor_deleted} -> + Logger.info("Actor was deleted") + {:error, :actor_deleted} + + {:error, e} -> + Logger.warn("Failed to make actor from url") + {:error, e} + end + end + end + + @doc """ + Find an actor in our local database or call WebFinger to find what's its AP ID is and then fetch it + """ + @spec find_or_make_actor_from_nickname(String.t(), atom() | nil) :: tuple() + def find_or_make_actor_from_nickname(nickname, type \\ nil) do + case Actors.get_actor_by_name(nickname, type) do + %Actor{} = actor -> + {:ok, actor} + + nil -> + make_actor_from_nickname(nickname) + end + end + + @spec find_or_make_group_from_nickname(String.t()) :: tuple() + def find_or_make_group_from_nickname(nick), do: find_or_make_actor_from_nickname(nick, :Group) + + @doc """ + Create an actor inside our database from username, using WebFinger to find out its AP ID and then fetch it + """ + @spec make_actor_from_nickname(String.t()) :: {:ok, %Actor{}} | {:error, any()} + def make_actor_from_nickname(nickname) do + case WebFinger.finger(nickname) do + {:ok, url} when is_binary(url) -> + make_actor_from_url(url) + + _e -> + {:error, "No ActivityPub URL found in WebFinger"} + end + end +end diff --git a/lib/federation/activity_pub/federator.ex b/lib/federation/activity_pub/federator.ex index 8d0e7a7f9..4bed74643 100644 --- a/lib/federation/activity_pub/federator.ex +++ b/lib/federation/activity_pub/federator.ex @@ -13,6 +13,7 @@ defmodule Mobilizon.Federation.ActivityPub.Federator do alias Mobilizon.Actors.Actor alias Mobilizon.Federation.ActivityPub alias Mobilizon.Federation.ActivityPub.{Activity, Transmogrifier} + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor require Logger @@ -42,7 +43,8 @@ defmodule Mobilizon.Federation.ActivityPub.Federator do Logger.debug(inspect(activity)) Logger.debug(fn -> "Running publish for #{activity.data["id"]}" end) - with {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(activity.data["actor"]) do + with {:ok, %Actor{} = actor} <- + ActivityPubActor.get_or_fetch_actor_by_url(activity.data["actor"]) do Logger.info(fn -> "Sending #{activity.data["id"]} out via AP" end) ActivityPub.publish(actor, activity) end diff --git a/lib/federation/activity_pub/fetcher.ex b/lib/federation/activity_pub/fetcher.ex index 7808c9710..7d1b73d63 100644 --- a/lib/federation/activity_pub/fetcher.ex +++ b/lib/federation/activity_pub/fetcher.ex @@ -8,6 +8,7 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do alias Mobilizon.Federation.HTTPSignatures.Signature alias Mobilizon.Federation.ActivityPub.{Relay, Transmogrifier} + alias Mobilizon.Federation.ActivityStream.Converter.Actor, as: ActorConverter alias Mobilizon.Service.HTTP.ActivityPub, as: ActivityPubClient import Mobilizon.Federation.ActivityPub.Utils, @@ -94,6 +95,42 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do end end + @doc """ + Fetching a remote actor's information through its AP ID + """ + @spec fetch_and_prepare_actor_from_url(String.t()) :: {:ok, map()} | {:error, atom()} | any() + def fetch_and_prepare_actor_from_url(url) do + Logger.debug("Fetching and preparing actor from url") + Logger.debug(inspect(url)) + + res = + with {:ok, %{status: 200, body: body}} <- + Tesla.get(url, + headers: [{"Accept", "application/activity+json"}], + follow_redirect: true + ), + :ok <- Logger.debug("response okay, now decoding json"), + {:ok, data} <- Jason.decode(body) do + Logger.debug("Got activity+json response at actor's endpoint, now converting data") + {:ok, ActorConverter.as_to_model_data(data)} + else + # Actor is gone, probably deleted + {:ok, %{status: 410}} -> + Logger.info("Response HTTP 410") + {:error, :actor_deleted} + + {:error, e} -> + Logger.warn("Could not decode actor at fetch #{url}, #{inspect(e)}") + {:error, e} + + e -> + Logger.warn("Could not decode actor at fetch #{url}, #{inspect(e)}") + {:error, e} + end + + res + end + @spec origin_check(String.t(), map()) :: boolean() defp origin_check(url, data) do if origin_check?(url, data) do diff --git a/lib/federation/activity_pub/refresher.ex b/lib/federation/activity_pub/refresher.ex index e4ff02be5..dec998427 100644 --- a/lib/federation/activity_pub/refresher.ex +++ b/lib/federation/activity_pub/refresher.ex @@ -6,6 +6,7 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do alias Mobilizon.Actors alias Mobilizon.Actors.Actor alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.{Fetcher, Relay, Transmogrifier, Utils} require Logger @@ -31,7 +32,7 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do end def refresh_profile(%Actor{type: type, url: url}) when type in [:Person, :Application] do - with {:ok, %Actor{outbox_url: outbox_url}} <- ActivityPub.make_actor_from_url(url), + with {:ok, %Actor{outbox_url: outbox_url}} <- ActivityPubActor.make_actor_from_url(url), :ok <- fetch_collection(outbox_url, Relay.get_actor()) do :ok end @@ -49,7 +50,7 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do discussions_url: discussions_url, events_url: events_url }} <- - ActivityPub.make_actor_from_url(group_url), + ActivityPubActor.make_actor_from_url(group_url), :ok <- fetch_collection(outbox_url, on_behalf_of), :ok <- fetch_collection(members_url, on_behalf_of), :ok <- fetch_collection(resources_url, on_behalf_of), diff --git a/lib/federation/activity_pub/relay.ex b/lib/federation/activity_pub/relay.ex index b0a8997c9..8266d94f5 100644 --- a/lib/federation/activity_pub/relay.ex +++ b/lib/federation/activity_pub/relay.ex @@ -13,6 +13,7 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do alias Mobilizon.Federation.ActivityPub alias Mobilizon.Federation.ActivityPub.{Activity, Refresher, Transmogrifier} + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.WebFinger alias Mobilizon.GraphQL.API.Follows @@ -37,7 +38,8 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do def follow(address) do with {:ok, target_instance} <- fetch_actor(address), %Actor{} = local_actor <- get_actor(), - {:ok, %Actor{} = target_actor} <- ActivityPub.get_or_fetch_actor_by_url(target_instance), + {:ok, %Actor{} = target_actor} <- + ActivityPubActor.get_or_fetch_actor_by_url(target_instance), {:ok, activity, follow} <- Follows.follow(local_actor, target_actor) do Logger.info("Relay: followed instance #{target_instance}; id=#{activity.data["id"]}") {:ok, activity, follow} @@ -56,7 +58,8 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do def unfollow(address) do with {:ok, target_instance} <- fetch_actor(address), %Actor{} = local_actor <- get_actor(), - {:ok, %Actor{} = target_actor} <- ActivityPub.get_or_fetch_actor_by_url(target_instance), + {:ok, %Actor{} = target_actor} <- + ActivityPubActor.get_or_fetch_actor_by_url(target_instance), {:ok, activity, follow} <- Follows.unfollow(local_actor, target_actor) do Logger.info("Relay: unfollowed instance #{target_instance}: id=#{activity.data["id"]}") {:ok, activity, follow} @@ -73,7 +76,8 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do with {:ok, target_instance} <- fetch_actor(address), %Actor{} = local_actor <- get_actor(), - {:ok, %Actor{} = target_actor} <- ActivityPub.get_or_fetch_actor_by_url(target_instance), + {:ok, %Actor{} = target_actor} <- + ActivityPubActor.get_or_fetch_actor_by_url(target_instance), {:ok, activity, follow} <- Follows.accept(target_actor, local_actor) do {:ok, activity, follow} end @@ -84,7 +88,8 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do with {:ok, target_instance} <- fetch_actor(address), %Actor{} = local_actor <- get_actor(), - {:ok, %Actor{} = target_actor} <- ActivityPub.get_or_fetch_actor_by_url(target_instance), + {:ok, %Actor{} = target_actor} <- + ActivityPubActor.get_or_fetch_actor_by_url(target_instance), {:ok, activity, follow} <- Follows.reject(target_actor, local_actor) do {:ok, activity, follow} end @@ -94,7 +99,8 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do Logger.debug("We're trying to refresh a remote instance") with {:ok, target_instance} <- fetch_actor(address), - {:ok, %Actor{} = target_actor} <- ActivityPub.get_or_fetch_actor_by_url(target_instance) do + {:ok, %Actor{} = target_actor} <- + ActivityPubActor.get_or_fetch_actor_by_url(target_instance) do Refresher.refresh_profile(target_actor) end end diff --git a/lib/federation/activity_pub/transmogrifier.ex b/lib/federation/activity_pub/transmogrifier.ex index 1e5ab2fb1..3399e9b9b 100644 --- a/lib/federation/activity_pub/transmogrifier.ex +++ b/lib/federation/activity_pub/transmogrifier.ex @@ -18,6 +18,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do alias Mobilizon.Federation.ActivityPub alias Mobilizon.Federation.ActivityPub.{Activity, Refresher, Relay, Utils} + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.Types.Ownable alias Mobilizon.Federation.ActivityStream.{Converter, Convertible} alias Mobilizon.Tombstone @@ -117,12 +118,13 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do def handle_incoming(%{ "type" => "Create", - "object" => %{"type" => "Group", "id" => group_url} = _object - }) do - Logger.info("Handle incoming to create a group") + "object" => %{"type" => type, "id" => actor_url} = _object + }) + when type in ["Group", "Person", "Actor"] do + Logger.info("Handle incoming to create an actor") - with {:ok, %Actor{} = group} <- ActivityPub.get_or_fetch_actor_by_url(group_url) do - {:ok, nil, group} + with {:ok, %Actor{} = actor} <- ActivityPubActor.get_or_fetch_actor_by_url(actor_url) do + {:ok, nil, actor} end end @@ -201,8 +203,8 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do def handle_incoming( %{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = _data ) do - with {:ok, %Actor{} = followed} <- ActivityPub.get_or_fetch_actor_by_url(followed, true), - {:ok, %Actor{} = follower} <- ActivityPub.get_or_fetch_actor_by_url(follower), + with {:ok, %Actor{} = followed} <- ActivityPubActor.get_or_fetch_actor_by_url(followed, true), + {:ok, %Actor{} = follower} <- ActivityPubActor.get_or_fetch_actor_by_url(follower), {:ok, activity, object} <- ActivityPub.follow(follower, followed, id, false) do {:ok, activity, object} else @@ -221,7 +223,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do with {:existing_todo_list, nil} <- {:existing_todo_list, Todos.get_todo_list_by_url(object_url)}, - {:ok, %Actor{url: actor_url}} <- ActivityPub.get_or_fetch_actor_by_url(actor_url), + {:ok, %Actor{url: actor_url}} <- ActivityPubActor.get_or_fetch_actor_by_url(actor_url), object_data when is_map(object_data) <- object |> Converter.TodoList.as_to_model_data(), {:ok, %Activity{} = activity, %TodoList{} = todo_list} <- @@ -295,7 +297,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do } = data ) do with actor_url <- Utils.get_actor(data), - {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(actor_url), + {:ok, %Actor{} = actor} <- ActivityPubActor.get_or_fetch_actor_by_url(actor_url), {:object_not_found, {:ok, %Activity{} = activity, object}} <- {:object_not_found, do_handle_incoming_accept_following(accepted_object, actor) || @@ -328,7 +330,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do %{"type" => "Reject", "object" => rejected_object, "actor" => _actor, "id" => id} = data ) do with actor_url <- Utils.get_actor(data), - {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(actor_url), + {:ok, %Actor{} = actor} <- ActivityPubActor.get_or_fetch_actor_by_url(actor_url), {:object_not_found, {:ok, activity, object}} <- {:object_not_found, do_handle_incoming_reject_following(rejected_object, actor) || @@ -359,7 +361,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do ) do with actor_url <- Utils.get_actor(data), {:ok, %Actor{id: actor_id, suspended: false} = actor} <- - ActivityPub.get_or_fetch_actor_by_url(actor_url), + ActivityPubActor.get_or_fetch_actor_by_url(actor_url), :ok <- Logger.debug("Fetching contained object"), {:ok, entity} <- process_announce_data(object, actor), :ok <- eventually_create_share(object, entity, actor_id) do @@ -380,7 +382,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do ) when object_type in ["Person", "Group", "Application", "Service", "Organization"] do with {:ok, %Actor{suspended: false} = old_actor} <- - ActivityPub.get_or_fetch_actor_by_url(object["id"]), + ActivityPubActor.get_or_fetch_actor_by_url(object["id"]), object_data <- object |> Converter.Actor.as_to_model_data(), {:ok, %Activity{} = activity, %Actor{} = new_actor} <- @@ -403,7 +405,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do ) do with actor <- Utils.get_actor(update_data), {:ok, %Actor{url: actor_url, suspended: false} = actor} <- - ActivityPub.get_or_fetch_actor_by_url(actor), + ActivityPubActor.get_or_fetch_actor_by_url(actor), {:ok, %Event{} = old_event} <- object |> Utils.get_url() |> ActivityPub.fetch_object_from_url(), object_data <- Converter.Event.as_to_model_data(object), @@ -428,7 +430,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do with actor <- Utils.get_actor(update_data), {:ok, %Actor{url: actor_url, suspended: false}} <- - ActivityPub.get_or_fetch_actor_by_url(actor), + ActivityPubActor.get_or_fetch_actor_by_url(actor), {:origin_check, true} <- {:origin_check, Utils.origin_check?(actor_url, update_data)}, object_data <- Converter.Comment.as_to_model_data(object), {:ok, old_entity} <- object |> Utils.get_url() |> ActivityPub.fetch_object_from_url(), @@ -448,7 +450,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do ) do with actor <- Utils.get_actor(update_data), {:ok, %Actor{url: actor_url, suspended: false} = actor} <- - ActivityPub.get_or_fetch_actor_by_url(actor), + ActivityPubActor.get_or_fetch_actor_by_url(actor), {:ok, %Post{} = old_post} <- object |> Utils.get_url() |> ActivityPub.fetch_object_from_url(), object_data <- Converter.Post.as_to_model_data(object), @@ -476,7 +478,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do when type in ["ResourceCollection", "Document"] do with actor <- Utils.get_actor(update_data), {:ok, %Actor{url: actor_url, suspended: false}} <- - ActivityPub.get_or_fetch_actor_by_url(actor), + ActivityPubActor.get_or_fetch_actor_by_url(actor), {:ok, %Resource{} = old_resource} <- object |> Utils.get_url() |> ActivityPub.fetch_object_from_url(), object_data <- Converter.Resource.as_to_model_data(object), @@ -501,7 +503,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do with actor <- Utils.get_actor(update_data), {:ok, %Actor{url: actor_url, suspended: false} = actor} <- - ActivityPub.get_or_fetch_actor_by_url(actor), + ActivityPubActor.get_or_fetch_actor_by_url(actor), {:origin_check, true} <- {:origin_check, Utils.origin_check?(actor_url, update_data)}, object_data <- Converter.Member.as_to_model_data(object), {:ok, old_entity} <- object |> Utils.get_url() |> ActivityPub.fetch_object_from_url(), @@ -543,7 +545,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do } = data ) do with actor <- Utils.get_actor(data), - {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(actor), + {:ok, %Actor{} = actor} <- ActivityPubActor.get_or_fetch_actor_by_url(actor), {:ok, object} <- fetch_obj_helper_as_activity_streams(object_id), {:ok, activity, object} <- ActivityPub.unannounce(actor, object, id, cancelled_activity_id, false) do @@ -561,8 +563,9 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do "id" => id } = _data ) do - with {:ok, %Actor{domain: nil} = followed} <- ActivityPub.get_or_fetch_actor_by_url(followed), - {:ok, %Actor{} = follower} <- ActivityPub.get_or_fetch_actor_by_url(follower), + with {:ok, %Actor{domain: nil} = followed} <- + ActivityPubActor.get_or_fetch_actor_by_url(followed), + {:ok, %Actor{} = follower} <- ActivityPubActor.get_or_fetch_actor_by_url(follower), {:ok, activity, object} <- ActivityPub.unfollow(follower, followed, id, false) do {:ok, activity, object} else @@ -579,7 +582,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do ) do with actor_url <- Utils.get_actor(data), {:actor, {:ok, %Actor{} = actor}} <- - {:actor, ActivityPub.get_or_fetch_actor_by_url(actor_url)}, + {:actor, ActivityPubActor.get_or_fetch_actor_by_url(actor_url)}, object_id <- Utils.get_url(object), {:ok, object} <- is_group_object_gone(object_id), {:origin_check, true} <- @@ -622,7 +625,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do when type in ["ResourceCollection", "Document"] do with actor <- Utils.get_actor(data), {:ok, %Actor{url: actor_url, suspended: false} = actor} <- - ActivityPub.get_or_fetch_actor_by_url(actor), + ActivityPubActor.get_or_fetch_actor_by_url(actor), {:ok, %Resource{} = old_resource} <- object |> Utils.get_url() |> ActivityPub.fetch_object_from_url(), object_data <- Converter.Resource.as_to_model_data(object), @@ -654,7 +657,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do ) do with actor <- Utils.get_actor(data), {:ok, %Actor{url: _actor_url, suspended: false} = actor} <- - ActivityPub.get_or_fetch_actor_by_url(actor), + ActivityPubActor.get_or_fetch_actor_by_url(actor), object <- Utils.get_url(object), {:ok, object} <- ActivityPub.fetch_object_from_url(object), {:ok, activity, object} <- @@ -672,7 +675,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do def handle_incoming(%{"type" => "Leave", "object" => object, "actor" => actor} = data) do with actor <- Utils.get_actor(data), - {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(actor), + {:ok, %Actor{} = actor} <- ActivityPubActor.get_or_fetch_actor_by_url(actor), object <- Utils.get_url(object), {:ok, object} <- ActivityPub.fetch_object_from_url(object), {:ok, activity, object} <- ActivityPub.leave(object, actor, false) do @@ -702,10 +705,10 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do Logger.info("Handle incoming to invite someone") with {:ok, %Actor{} = actor} <- - data |> Utils.get_actor() |> ActivityPub.get_or_fetch_actor_by_url(), + data |> Utils.get_actor() |> ActivityPubActor.get_or_fetch_actor_by_url(), {:ok, object} <- object |> Utils.get_url() |> ActivityPub.fetch_object_from_url(), {:ok, %Actor{} = target} <- - target |> Utils.get_url() |> ActivityPub.get_or_fetch_actor_by_url(), + target |> Utils.get_url() |> ActivityPubActor.get_or_fetch_actor_by_url(), {:ok, activity, %Member{} = member} <- ActivityPub.invite(object, actor, target, false, %{url: id}) do {:ok, activity, member} @@ -718,10 +721,10 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do Logger.info("Handle incoming to remove a member from a group") with {:ok, %Actor{id: moderator_id} = moderator} <- - data |> Utils.get_actor() |> ActivityPub.get_or_fetch_actor_by_url(), + data |> Utils.get_actor() |> ActivityPubActor.get_or_fetch_actor_by_url(), {:ok, person_id} <- get_remove_object(object), {:ok, %Actor{type: :Group, id: group_id} = group} <- - origin |> Utils.get_url() |> ActivityPub.get_or_fetch_actor_by_url(), + origin |> Utils.get_url() |> ActivityPubActor.get_or_fetch_actor_by_url(), {:is_admin, {:ok, %Member{role: role}}} when role in [:moderator, :administrator, :creator] <- {:is_admin, Actors.get_member(moderator_id, group_id)}, diff --git a/lib/federation/activity_pub/utils.ex b/lib/federation/activity_pub/utils.ex index d1cb0a3ed..01ad1abc6 100644 --- a/lib/federation/activity_pub/utils.ex +++ b/lib/federation/activity_pub/utils.ex @@ -14,6 +14,7 @@ defmodule Mobilizon.Federation.ActivityPub.Utils do alias Mobilizon.Federation.ActivityPub alias Mobilizon.Federation.ActivityPub.{Activity, Federator, Relay} + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.Types.Ownable alias Mobilizon.Federation.ActivityStream.Converter alias Mobilizon.Federation.HTTPSignatures @@ -175,7 +176,7 @@ defmodule Mobilizon.Federation.ActivityPub.Utils do @spec remote_actors(list(String.t())) :: list(Actor.t()) def remote_actors(recipients) do recipients - |> Enum.map(fn url -> ActivityPub.get_or_fetch_actor_by_url(url) end) + |> Enum.map(fn url -> ActivityPubActor.get_or_fetch_actor_by_url(url) end) |> Enum.map(fn {status, actor} -> case status do :ok -> @@ -259,8 +260,9 @@ defmodule Mobilizon.Federation.ActivityPub.Utils do are_same_origin?(id, actor) end - def origin_check?(_id, %{"type" => type} = _params) when type in ["Actor", "Person", "Group"], - do: true + def origin_check?(id, %{"type" => type, "id" => actor_id} = _params) + when type in ["Actor", "Person", "Group"], + do: id == actor_id def origin_check?(_id, %{"actor" => nil} = _args), do: false diff --git a/lib/federation/activity_stream/converter/discussion.ex b/lib/federation/activity_stream/converter/discussion.ex index abc4196bd..2029923d6 100644 --- a/lib/federation/activity_stream/converter/discussion.ex +++ b/lib/federation/activity_stream/converter/discussion.ex @@ -8,7 +8,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Discussion do alias Mobilizon.Actors.Actor alias Mobilizon.Discussions.Discussion - alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityStream.{Converter, Convertible} alias Mobilizon.Federation.ActivityStream.Converter.Discussion, as: DiscussionConverter alias Mobilizon.Storage.Repo @@ -49,10 +49,10 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Discussion do def as_to_model_data(%{"type" => "Note", "name" => name} = object) when not is_nil(name) do with creator_url <- Map.get(object, "actor"), {:ok, %Actor{id: creator_id, suspended: false}} <- - ActivityPub.get_or_fetch_actor_by_url(creator_url), + ActivityPubActor.get_or_fetch_actor_by_url(creator_url), actor_url <- Map.get(object, "attributedTo"), {:ok, %Actor{id: actor_id, suspended: false}} <- - ActivityPub.get_or_fetch_actor_by_url(actor_url) do + ActivityPubActor.get_or_fetch_actor_by_url(actor_url) do %{ title: name, actor_id: actor_id, diff --git a/lib/federation/activity_stream/converter/flag.ex b/lib/federation/activity_stream/converter/flag.ex index 975b78a84..290551e02 100644 --- a/lib/federation/activity_stream/converter/flag.ex +++ b/lib/federation/activity_stream/converter/flag.ex @@ -14,7 +14,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Flag do alias Mobilizon.Events.Event alias Mobilizon.Reports.Report - alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.Relay alias Mobilizon.Federation.ActivityStream.{Converter, Convertible} @@ -65,10 +65,11 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Flag do @spec as_to_model(map) :: map def as_to_model(%{"object" => objects} = object) do - with {:ok, %Actor{} = reporter} <- ActivityPub.get_or_fetch_actor_by_url(object["actor"]), + with {:ok, %Actor{} = reporter} <- + ActivityPubActor.get_or_fetch_actor_by_url(object["actor"]), %Actor{} = reported <- Enum.reduce_while(objects, nil, fn url, _ -> - case ActivityPub.get_or_fetch_actor_by_url(url) do + case ActivityPubActor.get_or_fetch_actor_by_url(url) do {:ok, %Actor{} = actor} -> {:halt, actor} diff --git a/lib/federation/activity_stream/converter/member.ex b/lib/federation/activity_stream/converter/member.ex index 0d55e8ef1..be4db50a5 100644 --- a/lib/federation/activity_stream/converter/member.ex +++ b/lib/federation/activity_stream/converter/member.ex @@ -8,7 +8,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Member do alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Member, as: MemberModel - alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.Utils alias Mobilizon.Federation.ActivityStream.Convertible @@ -53,5 +53,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Member do @spec get_actor(String.t() | map() | nil) :: {:ok, Actor.t()} | {:error, String.t()} defp get_actor(nil), do: {:error, "nil property found for actor data"} - defp get_actor(actor), do: actor |> Utils.get_url() |> ActivityPub.get_or_fetch_actor_by_url() + + defp get_actor(actor), + do: actor |> Utils.get_url() |> ActivityPubActor.get_or_fetch_actor_by_url() end diff --git a/lib/federation/activity_stream/converter/post.ex b/lib/federation/activity_stream/converter/post.ex index 020fda4aa..f8d23c7ce 100644 --- a/lib/federation/activity_stream/converter/post.ex +++ b/lib/federation/activity_stream/converter/post.ex @@ -6,7 +6,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Post do internal one, and back. """ alias Mobilizon.Actors.Actor - alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.{Audience, Utils} alias Mobilizon.Federation.ActivityStream.{Converter, Convertible} alias Mobilizon.Federation.ActivityStream.Converter.Media, as: MediaConverter @@ -91,7 +91,9 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Post do @spec get_actor(String.t() | map() | nil) :: {:ok, Actor.t()} | {:error, String.t()} defp get_actor(nil), do: {:error, "nil property found for actor data"} - defp get_actor(actor), do: actor |> Utils.get_url() |> ActivityPub.get_or_fetch_actor_by_url() + + defp get_actor(actor), + do: actor |> Utils.get_url() |> ActivityPubActor.get_or_fetch_actor_by_url() defp to_date(nil), do: nil defp to_date(%DateTime{} = date), do: DateTime.to_iso8601(date) diff --git a/lib/federation/activity_stream/converter/resource.ex b/lib/federation/activity_stream/converter/resource.ex index 7c045f256..0472ca1b0 100644 --- a/lib/federation/activity_stream/converter/resource.ex +++ b/lib/federation/activity_stream/converter/resource.ex @@ -7,6 +7,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Resource do """ alias Mobilizon.Actors.Actor alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.Utils alias Mobilizon.Federation.ActivityStream.{Converter, Convertible} alias Mobilizon.Resources @@ -88,7 +89,9 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Resource do @spec get_actor(String.t() | map() | nil) :: {:ok, Actor.t()} | {:error, String.t()} defp get_actor(nil), do: {:error, "nil property found for actor data"} - defp get_actor(actor), do: actor |> Utils.get_url() |> ActivityPub.get_or_fetch_actor_by_url() + + defp get_actor(actor), + do: actor |> Utils.get_url() |> ActivityPubActor.get_or_fetch_actor_by_url() defp get_context(%Resource{parent_id: nil, actor: %Actor{resources_url: resources_url}}), do: resources_url diff --git a/lib/federation/activity_stream/converter/todo.ex b/lib/federation/activity_stream/converter/todo.ex index fad2d8a53..fdd6f38c8 100644 --- a/lib/federation/activity_stream/converter/todo.ex +++ b/lib/federation/activity_stream/converter/todo.ex @@ -7,6 +7,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Todo do """ alias Mobilizon.Actors.Actor alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityStream.{Converter, Convertible} alias Mobilizon.Todos alias Mobilizon.Todos.{Todo, TodoList} @@ -51,7 +52,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Todo do %{"type" => "Todo", "actor" => actor_url, "todoList" => todo_list_url} = object ) do with {:ok, %Actor{id: creator_id} = _creator} <- - ActivityPub.get_or_fetch_actor_by_url(actor_url), + ActivityPubActor.get_or_fetch_actor_by_url(actor_url), {:todo_list, %TodoList{id: todo_list_id}} <- {:todo_list, Todos.get_todo_list_by_url(todo_list_url)} do %{ diff --git a/lib/federation/activity_stream/converter/todo_list.ex b/lib/federation/activity_stream/converter/todo_list.ex index 657e97df3..76ad46fc7 100644 --- a/lib/federation/activity_stream/converter/todo_list.ex +++ b/lib/federation/activity_stream/converter/todo_list.ex @@ -6,7 +6,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.TodoList do internal one, and back. """ alias Mobilizon.Actors.Actor - alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityStream.{Converter, Convertible} alias Mobilizon.Todos.TodoList @@ -39,7 +39,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.TodoList do @impl Converter @spec as_to_model_data(map) :: {:ok, map} | {:error, any()} def as_to_model_data(%{"type" => "TodoList", "actor" => actor_url} = object) do - case ActivityPub.get_or_fetch_actor_by_url(actor_url) do + case ActivityPubActor.get_or_fetch_actor_by_url(actor_url) do {:ok, %Actor{type: :Group, id: group_id} = _group} -> %{ title: object["name"], diff --git a/lib/federation/activity_stream/converter/utils.ex b/lib/federation/activity_stream/converter/utils.ex index 79c604a63..a78456bd2 100644 --- a/lib/federation/activity_stream/converter/utils.ex +++ b/lib/federation/activity_stream/converter/utils.ex @@ -10,7 +10,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do alias Mobilizon.Mention alias Mobilizon.Storage.Repo - alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityStream.Converter.Media, as: MediaConverter alias Mobilizon.Web.Endpoint @@ -114,7 +114,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do @spec create_mention(map(), list()) :: list() defp create_mention(mention, acc) when is_map(mention) do with true <- mention["type"] == "Mention", - {:ok, %Actor{id: actor_id}} <- ActivityPub.get_or_fetch_actor_by_url(mention["href"]) do + {:ok, %Actor{id: actor_id}} <- + ActivityPubActor.get_or_fetch_actor_by_url(mention["href"]) do acc ++ [%{actor_id: actor_id}] else _err -> @@ -169,7 +170,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do @spec fetch_actor(String.t()) :: Actor.t() defp fetch_actor(actor_url) do with {:ok, %Actor{suspended: false} = actor} <- - ActivityPub.get_or_fetch_actor_by_url(actor_url) do + ActivityPubActor.get_or_fetch_actor_by_url(actor_url) do actor end end diff --git a/lib/federation/http_signatures/signature.ex b/lib/federation/http_signatures/signature.ex index 787b4ccb4..ff703a3ed 100644 --- a/lib/federation/http_signatures/signature.ex +++ b/lib/federation/http_signatures/signature.ex @@ -12,7 +12,7 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do alias Mobilizon.Actors.Actor - alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor require Logger @@ -53,7 +53,7 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do {:ok, String.t()} | {:error, :actor_fetch_error | :pem_decode_error | :actor_not_fetchable} defp get_public_key_for_url(url) do - with {:ok, %Actor{keys: keys}} <- ActivityPub.get_or_fetch_actor_by_url(url), + with {:ok, %Actor{keys: keys}} <- ActivityPubActor.get_or_fetch_actor_by_url(url), {:ok, public_key} <- prepare_public_key(keys) do {:ok, public_key} else @@ -90,7 +90,7 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do with %{"keyId" => kid} <- HTTPSignatures.signature_for_conn(conn), actor_id <- key_id_to_actor_url(kid), :ok <- Logger.debug("Refetching public key for #{actor_id}"), - {:ok, _actor} <- ActivityPub.make_actor_from_url(actor_id), + {:ok, _actor} <- ActivityPubActor.make_actor_from_url(actor_id), {:ok, public_key} <- get_public_key_for_url(actor_id) do {:ok, public_key} end diff --git a/lib/federation/web_finger/web_finger.ex b/lib/federation/web_finger/web_finger.ex index fbde57e4b..409f67b8f 100644 --- a/lib/federation/web_finger/web_finger.ex +++ b/lib/federation/web_finger/web_finger.ex @@ -10,7 +10,7 @@ defmodule Mobilizon.Federation.WebFinger do alias Mobilizon.Actors alias Mobilizon.Actors.Actor - alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.WebFinger.XmlBuilder alias Mobilizon.Service.HTTP.{HostMetaClient, WebfingerClient} alias Mobilizon.Web.Endpoint @@ -56,7 +56,7 @@ defmodule Mobilizon.Federation.WebFinger do {:ok, represent_actor(actor, "JSON")} else _e -> - case ActivityPub.get_or_fetch_actor_by_url(resource) do + case ActivityPubActor.get_or_fetch_actor_by_url(resource) do {:ok, %Actor{} = actor} when not is_nil(actor) -> {:ok, represent_actor(actor, "JSON")} diff --git a/lib/graphql/api/search.ex b/lib/graphql/api/search.ex index f0f1ec83c..d652dcb68 100644 --- a/lib/graphql/api/search.ex +++ b/lib/graphql/api/search.ex @@ -10,6 +10,7 @@ defmodule Mobilizon.GraphQL.API.Search do alias Mobilizon.Storage.Page alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor require Logger @@ -92,7 +93,7 @@ defmodule Mobilizon.GraphQL.API.Search do # If the search string is an username @spec process_from_username(String.t()) :: Page.t() defp process_from_username(search) do - case ActivityPub.find_or_make_actor_from_nickname(search) do + case ActivityPubActor.find_or_make_actor_from_nickname(search) do {:ok, actor} -> %Page{total: 1, elements: [actor]} diff --git a/lib/graphql/resolvers/group.ex b/lib/graphql/resolvers/group.ex index c31892ca7..e5ed6a2f3 100644 --- a/lib/graphql/resolvers/group.ex +++ b/lib/graphql/resolvers/group.ex @@ -7,6 +7,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do alias Mobilizon.{Actors, Events, Users} alias Mobilizon.Actors.{Actor, Member} alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.GraphQL.API alias Mobilizon.Users.User alias Mobilizon.Web.Upload @@ -27,7 +28,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do } ) do with {:group, {:ok, %Actor{id: group_id, suspended: false} = group}} <- - {:group, ActivityPub.find_or_make_group_from_nickname(name)}, + {:group, ActivityPubActor.find_or_make_group_from_nickname(name)}, {:actor, %Actor{id: actor_id} = _actor} <- {:actor, Users.get_actor_for_user(user)}, {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)} do {:ok, group} @@ -45,7 +46,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do def find_group(_parent, %{preferred_username: name}, _resolution) do with {:ok, %Actor{suspended: false} = actor} <- - ActivityPub.find_or_make_group_from_nickname(name), + ActivityPubActor.find_or_make_group_from_nickname(name), %Actor{} = actor <- restrict_fields_for_non_member_request(actor) do {:ok, actor} else diff --git a/lib/graphql/resolvers/member.ex b/lib/graphql/resolvers/member.ex index 3e20194a9..8af57bba5 100644 --- a/lib/graphql/resolvers/member.ex +++ b/lib/graphql/resolvers/member.ex @@ -7,6 +7,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do alias Mobilizon.{Actors, Users} alias Mobilizon.Actors.{Actor, Member} alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.Refresher alias Mobilizon.Storage.Page alias Mobilizon.Users.User @@ -70,7 +71,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do target_actor_username |> String.trim() |> String.trim_leading("@"), {:target_actor_username, {:ok, %Actor{id: target_actor_id} = target_actor}} <- {:target_actor_username, - ActivityPub.find_or_make_actor_from_nickname(target_actor_username)}, + ActivityPubActor.find_or_make_actor_from_nickname(target_actor_username)}, {:existant, true} <- {:existant, check_member_not_existant_or_rejected(target_actor_id, group.id)}, {:ok, _activity, %Member{} = member} <- ActivityPub.invite(group, actor, target_actor) do diff --git a/lib/graphql/resolvers/person.ex b/lib/graphql/resolvers/person.ex index 70c720a81..06b898531 100644 --- a/lib/graphql/resolvers/person.ex +++ b/lib/graphql/resolvers/person.ex @@ -13,6 +13,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do import Mobilizon.Web.Gettext alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor require Logger alias Mobilizon.Web.Upload @@ -39,7 +40,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do context: %{current_user: %User{} = user} }) do with {:ok, %Actor{id: actor_id} = actor} <- - ActivityPub.find_or_make_actor_from_nickname(preferred_username), + ActivityPubActor.find_or_make_actor_from_nickname(preferred_username), {:own, {:is_owned, _}} <- {:own, User.owns_actor(user, actor_id)} do {:ok, actor} else diff --git a/lib/mix/tasks/mobilizon/actors/refresh.ex b/lib/mix/tasks/mobilizon/actors/refresh.ex index 44bca92e7..893af5f2b 100644 --- a/lib/mix/tasks/mobilizon/actors/refresh.ex +++ b/lib/mix/tasks/mobilizon/actors/refresh.ex @@ -4,7 +4,7 @@ defmodule Mix.Tasks.Mobilizon.Actors.Refresh do """ use Mix.Task alias Mobilizon.Actors.Actor - alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Storage.Repo import Ecto.Query import Mix.Tasks.Mobilizon.Common @@ -65,7 +65,7 @@ defmodule Mix.Tasks.Mobilizon.Actors.Refresh do def run([preferred_username]) do start_mobilizon() - case ActivityPub.make_actor_from_nickname(preferred_username) do + case ActivityPubActor.make_actor_from_nickname(preferred_username) do {:ok, %Actor{}} -> shell_info(""" Actor #{preferred_username} refreshed @@ -89,7 +89,7 @@ defmodule Mix.Tasks.Mobilizon.Actors.Refresh do @spec make_actor(String.t(), boolean()) :: any() defp make_actor(username, verbose) do - ActivityPub.make_actor_from_nickname(username) + ActivityPubActor.make_actor_from_nickname(username) rescue _ -> if verbose do diff --git a/lib/web/controllers/activity_pub_controller.ex b/lib/web/controllers/activity_pub_controller.ex index 909369976..d8609359a 100644 --- a/lib/web/controllers/activity_pub_controller.ex +++ b/lib/web/controllers/activity_pub_controller.ex @@ -10,6 +10,7 @@ defmodule Mobilizon.Web.ActivityPubController do alias Mobilizon.Actors.{Actor, Member} alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.{Federator, Utils} alias Mobilizon.Web.ActivityPub.ActorView @@ -108,7 +109,7 @@ defmodule Mobilizon.Web.ActivityPubController do def inbox(%{assigns: %{valid_signature: true}} = conn, %{"name" => preferred_username} = params) do with %Actor{url: recipient_url} = recipient <- Actors.get_local_actor_by_name(preferred_username), - {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(params["actor"]), + {:ok, %Actor{} = actor} <- ActivityPubActor.get_or_fetch_actor_by_url(params["actor"]), true <- Utils.recipient_in_message(recipient, actor, params), params <- Utils.maybe_splice_recipient(recipient_url, params) do Federator.enqueue(:incoming_ap_doc, params) diff --git a/lib/web/plugs/mapped_signature_to_identity.ex b/lib/web/plugs/mapped_signature_to_identity.ex index 84262bc3f..548f3ac0c 100644 --- a/lib/web/plugs/mapped_signature_to_identity.ex +++ b/lib/web/plugs/mapped_signature_to_identity.ex @@ -12,7 +12,7 @@ defmodule Mobilizon.Web.Plugs.MappedSignatureToIdentity do alias Mobilizon.Actors.Actor - alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.Utils alias Mobilizon.Federation.HTTPSignatures.Signature @@ -34,7 +34,7 @@ defmodule Mobilizon.Web.Plugs.MappedSignatureToIdentity do @spec actor_from_key_id(Plug.Conn.t()) :: Actor.t() | nil defp actor_from_key_id(conn) do with key_actor_id when is_binary(key_actor_id) <- key_id_from_conn(conn), - {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(key_actor_id) do + {:ok, %Actor{} = actor} <- ActivityPubActor.get_or_fetch_actor_by_url(key_actor_id) do actor else _ -> diff --git a/test/federation/activity_pub/activity_pub_test.exs b/test/federation/activity_pub/activity_pub_test.exs index ac4f697bf..776ba7e23 100644 --- a/test/federation/activity_pub/activity_pub_test.exs +++ b/test/federation/activity_pub/activity_pub_test.exs @@ -11,13 +11,12 @@ defmodule Mobilizon.Federation.ActivityPubTest do import Mox import Mobilizon.Factory - alias Mobilizon.{Actors, Discussions, Events} - alias Mobilizon.Actors.Actor + alias Mobilizon.{Discussions, Events} alias Mobilizon.Resources.Resource alias Mobilizon.Todos.{Todo, TodoList} alias Mobilizon.Federation.ActivityPub - alias Mobilizon.Federation.ActivityPub.{Relay, Utils} + alias Mobilizon.Federation.ActivityPub.Utils alias Mobilizon.Federation.HTTPSignatures.Signature alias Mobilizon.Service.HTTP.ActivityPub.Mock @@ -40,116 +39,6 @@ defmodule Mobilizon.Federation.ActivityPubTest do end end - describe "fetching actor from its url" do - test "returns an actor from nickname" do - use_cassette "activity_pub/fetch_tcit@framapiaf.org" do - assert {:ok, - %Actor{preferred_username: "tcit", domain: "framapiaf.org", visibility: :public} = - _actor} = ActivityPub.make_actor_from_nickname("tcit@framapiaf.org") - end - - use_cassette "activity_pub/fetch_tcit@framapiaf.org_not_discoverable" do - assert {:ok, - %Actor{preferred_username: "tcit", domain: "framapiaf.org", visibility: :unlisted} = - _actor} = ActivityPub.make_actor_from_nickname("tcit@framapiaf.org") - end - end - - @actor_url "https://framapiaf.org/users/tcit" - test "returns an actor from url" do - # Initial fetch - use_cassette "activity_pub/fetch_framapiaf.org_users_tcit" do - # Unlisted because discoverable is not present in the JSON payload - assert {:ok, - %Actor{preferred_username: "tcit", domain: "framapiaf.org", visibility: :unlisted}} = - ActivityPub.get_or_fetch_actor_by_url(@actor_url) - end - - # Fetch uses cache if Actors.needs_update? returns false - with_mocks([ - {Actors, [:passthrough], - [ - get_actor_by_url: fn @actor_url, false -> - {:ok, - %Actor{ - preferred_username: "tcit", - domain: "framapiaf.org" - }} - end, - needs_update?: fn _ -> false end - ]}, - {ActivityPub, [:passthrough], - make_actor_from_url: fn @actor_url, false -> - {:ok, - %Actor{ - preferred_username: "tcit", - domain: "framapiaf.org" - }} - end} - ]) do - assert {:ok, %Actor{preferred_username: "tcit", domain: "framapiaf.org"}} = - ActivityPub.get_or_fetch_actor_by_url(@actor_url) - - assert_called(Actors.needs_update?(:_)) - refute called(ActivityPub.make_actor_from_url(@actor_url, false)) - end - - # Fetch doesn't use cache if Actors.needs_update? returns true - with_mocks([ - {Actors, [:passthrough], - [ - get_actor_by_url: fn @actor_url, false -> - {:ok, - %Actor{ - preferred_username: "tcit", - domain: "framapiaf.org" - }} - end, - needs_update?: fn _ -> true end - ]}, - {ActivityPub, [:passthrough], - make_actor_from_url: fn @actor_url, false -> - {:ok, - %Actor{ - preferred_username: "tcit", - domain: "framapiaf.org" - }} - end} - ]) do - assert {:ok, %Actor{preferred_username: "tcit", domain: "framapiaf.org"}} = - ActivityPub.get_or_fetch_actor_by_url(@actor_url) - - assert_called(ActivityPub.get_or_fetch_actor_by_url(@actor_url)) - assert_called(Actors.get_actor_by_url(@actor_url, false)) - assert_called(Actors.needs_update?(:_)) - assert_called(ActivityPub.make_actor_from_url(@actor_url, false)) - end - end - - @public_url "https://www.w3.org/ns/activitystreams#Public" - test "activitystreams#Public uri returns Relay actor" do - assert ActivityPub.get_or_fetch_actor_by_url(@public_url) == {:ok, Relay.get_actor()} - end - end - - describe "create activities" do - # test "removes doubled 'to' recipients" do - # actor = insert(:actor) - # - # {:ok, activity, _} = - # ActivityPub.create(%{ - # to: ["user1", "user1", "user2"], - # actor: actor, - # context: "", - # object: %{} - # }) - # - # assert activity.data["to"] == ["user1", "user2"] - # assert activity.actor == actor.url - # assert activity.recipients == ["user1", "user2"] - # end - end - describe "fetching an" do test "object by url" do url = "https://framapiaf.org/users/Framasoft/statuses/102093631881522097" diff --git a/test/federation/activity_pub/actor_test.exs b/test/federation/activity_pub/actor_test.exs new file mode 100644 index 000000000..69ebc5daa --- /dev/null +++ b/test/federation/activity_pub/actor_test.exs @@ -0,0 +1,120 @@ +defmodule Mobilizon.Federation.ActivityPub.ActorTest do + use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney + use Mobilizon.DataCase + + import Mock + + alias Mobilizon.Actors + alias Mobilizon.Actors.Actor + + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor + alias Mobilizon.Federation.ActivityPub.{Fetcher, Relay} + + describe "fetching actor from its url" do + test "returns an actor from nickname" do + use_cassette "activity_pub/fetch_tcit@framapiaf.org" do + assert {:ok, + %Actor{preferred_username: "tcit", domain: "framapiaf.org", visibility: :public} = + _actor} = ActivityPubActor.make_actor_from_nickname("tcit@framapiaf.org") + end + + use_cassette "activity_pub/fetch_tcit@framapiaf.org_not_discoverable" do + assert {:ok, + %Actor{preferred_username: "tcit", domain: "framapiaf.org", visibility: :unlisted} = + _actor} = ActivityPubActor.make_actor_from_nickname("tcit@framapiaf.org") + end + end + + @actor_url "https://framapiaf.org/users/tcit" + test "returns an actor from url" do + # Initial fetch + use_cassette "activity_pub/fetch_framapiaf.org_users_tcit" do + # Unlisted because discoverable is not present in the JSON payload + assert {:ok, + %Actor{preferred_username: "tcit", domain: "framapiaf.org", visibility: :unlisted}} = + ActivityPubActor.get_or_fetch_actor_by_url(@actor_url) + end + + # Fetch uses cache if Actors.needs_update? returns false + with_mocks([ + {Actors, [:passthrough], + [ + get_actor_by_url: fn @actor_url, false -> + {:ok, + %Actor{ + preferred_username: "tcit", + domain: "framapiaf.org" + }} + end, + needs_update?: fn _ -> false end + ]}, + {ActivityPubActor, [:passthrough], + make_actor_from_url: fn @actor_url, false -> + {:ok, + %Actor{ + preferred_username: "tcit", + domain: "framapiaf.org" + }} + end} + ]) do + assert {:ok, %Actor{preferred_username: "tcit", domain: "framapiaf.org"}} = + ActivityPubActor.get_or_fetch_actor_by_url(@actor_url) + + assert_called(Actors.needs_update?(:_)) + refute called(ActivityPubActor.make_actor_from_url(@actor_url, false)) + end + + # Fetch doesn't use cache if Actors.needs_update? returns true + with_mocks([ + {Actors, [:passthrough], + [ + get_actor_by_url: fn @actor_url, false -> + {:ok, + %Actor{ + preferred_username: "tcit", + domain: "framapiaf.org" + }} + end, + needs_update?: fn _ -> true end + ]}, + {ActivityPubActor, [:passthrough], + make_actor_from_url: fn @actor_url, false -> + {:ok, + %Actor{ + preferred_username: "tcit", + domain: "framapiaf.org" + }} + end} + ]) do + assert {:ok, %Actor{preferred_username: "tcit", domain: "framapiaf.org"}} = + 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.needs_update?(:_)) + assert_called(ActivityPubActor.make_actor_from_url(@actor_url, false)) + end + end + + test "handles remote actor being deleted" do + with_mocks([ + {Fetcher, [:passthrough], + fetch_and_prepare_actor_from_url: fn @actor_url -> + {:error, :actor_deleted} + end} + ]) do + assert match?( + {:error, :actor_deleted}, + ActivityPubActor.make_actor_from_url(@actor_url, false) + ) + + assert_called(Fetcher.fetch_and_prepare_actor_from_url(@actor_url)) + end + end + + @public_url "https://www.w3.org/ns/activitystreams#Public" + test "activitystreams#Public uri returns Relay actor" do + assert ActivityPubActor.get_or_fetch_actor_by_url(@public_url) == {:ok, Relay.get_actor()} + end + end +end diff --git a/test/federation/activity_pub/transmogrifier/delete_test.exs b/test/federation/activity_pub/transmogrifier/delete_test.exs index 30717266a..cefd4d64f 100644 --- a/test/federation/activity_pub/transmogrifier/delete_test.exs +++ b/test/federation/activity_pub/transmogrifier/delete_test.exs @@ -3,7 +3,6 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.DeleteTest do use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney use Oban.Testing, repo: Mobilizon.Storage.Repo import Mobilizon.Factory - import ExUnit.CaptureLog import Mox alias Mobilizon.{Actors, Discussions, Events, Posts, Resources} @@ -78,7 +77,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.DeleteTest do data |> Map.put("object", object) - :error = Transmogrifier.handle_incoming(data) + {:error, :unknown_actor} = Transmogrifier.handle_incoming(data) assert Discussions.get_comment_from_url(comment.url) end @@ -119,13 +118,14 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.DeleteTest do test "it fails for incoming actor deletes with spoofed origin" do %{url: url} = insert(:actor) - deleted_actor_url = "https://framapiaf.org/users/admin" data = File.read!("test/fixtures/mastodon-delete-user.json") |> Jason.decode!() |> Map.put("actor", url) + deleted_actor_url = "https://framapiaf.org/users/admin" + deleted_actor_data = File.read!("test/fixtures/mastodon-actor.json") |> Jason.decode!() @@ -137,9 +137,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.DeleteTest do {:ok, %Tesla.Env{status: 200, body: deleted_actor_data}} end) - assert capture_log(fn -> - assert :error == Transmogrifier.handle_incoming(data) - end) =~ "Object origin check failed" + assert :error == Transmogrifier.handle_incoming(data) assert Actors.get_actor_by_url(url) end diff --git a/test/federation/activity_pub/transmogrifier/posts_test.exs b/test/federation/activity_pub/transmogrifier/posts_test.exs index 2ccbb4fe2..c79b01a0a 100644 --- a/test/federation/activity_pub/transmogrifier/posts_test.exs +++ b/test/federation/activity_pub/transmogrifier/posts_test.exs @@ -7,7 +7,6 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.PostsTest do alias Mobilizon.Federation.ActivityPub.{Activity, Transmogrifier} alias Mobilizon.Federation.ActivityStream.Convertible alias Mobilizon.Posts.Post - alias Mobilizon.Service.HTTP.ActivityPub.Mock describe "handle incoming posts" do setup :verify_on_exit! diff --git a/test/federation/activity_pub/transmogrifier_test.exs b/test/federation/activity_pub/transmogrifier_test.exs index f04ad5a77..d344b5633 100644 --- a/test/federation/activity_pub/transmogrifier_test.exs +++ b/test/federation/activity_pub/transmogrifier_test.exs @@ -21,6 +21,7 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do alias Mobilizon.Todos.{Todo, TodoList} alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.Utils alias Mobilizon.Federation.ActivityPub.{Activity, Relay, Transmogrifier} alias Mobilizon.Federation.ActivityStream.Convertible @@ -89,7 +90,7 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do preferred_username: "member" ) - with_mock ActivityPub, [:passthrough], + with_mock ActivityPubActor, [:passthrough], get_or_fetch_actor_by_url: fn url -> case url do ^group_url -> {:ok, group} @@ -168,7 +169,7 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do group = insert(:group, domain: "morebilizon.com", url: @mobilizon_group_url) %Actor{url: actor_url} = actor = insert(:actor) - with_mock ActivityPub, [:passthrough], + with_mock ActivityPubActor, [:passthrough], get_or_fetch_actor_by_url: fn url -> case url do @mobilizon_group_url -> {:ok, group} @@ -198,7 +199,7 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do test "it accepts incoming todo lists and handles group being not found" do %Actor{url: actor_url} = actor = insert(:actor) - with_mock ActivityPub, [:passthrough], + with_mock ActivityPubActor, [:passthrough], get_or_fetch_actor_by_url: fn url -> case url do @mobilizon_group_url -> {:error, "Not found"} @@ -274,7 +275,7 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do group = insert(:group, domain: "morebilizon.com", url: @mobilizon_group_url) %Actor{url: actor_url} = actor = insert(:actor) - with_mock ActivityPub, [:passthrough], + with_mock ActivityPubActor, [:passthrough], get_or_fetch_actor_by_url: fn url -> case url do @mobilizon_group_url -> {:ok, group} @@ -304,7 +305,7 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do test "it accepts incoming todo lists and handles group being not found" do %Actor{url: actor_url} = actor = insert(:actor) - with_mock ActivityPub, [:passthrough], + with_mock ActivityPubActor, [:passthrough], get_or_fetch_actor_by_url: fn url -> case url do @mobilizon_group_url -> {:error, "Not found"} diff --git a/test/graphql/api/search_test.exs b/test/graphql/api/search_test.exs index 74e8a65ea..2d0b1351f 100644 --- a/test/graphql/api/search_test.exs +++ b/test/graphql/api/search_test.exs @@ -12,14 +12,15 @@ defmodule Mobilizon.GraphQL.API.SearchTest do alias Mobilizon.GraphQL.API.Search alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor test "search an user by username" do - with_mock ActivityPub, + with_mock ActivityPubActor, find_or_make_actor_from_nickname: fn "toto@domain.tld" -> {:ok, %Actor{id: 42}} end do assert {:ok, %Page{total: 1, elements: [%Actor{id: 42}]}} == Search.search_actors(%{term: "toto@domain.tld"}, 1, 10, :Person) - assert_called(ActivityPub.find_or_make_actor_from_nickname("toto@domain.tld")) + assert_called(ActivityPubActor.find_or_make_actor_from_nickname("toto@domain.tld")) end end diff --git a/test/mobilizon/actors/actors_test.exs b/test/mobilizon/actors/actors_test.exs index ca4ef2ba7..94abd067e 100644 --- a/test/mobilizon/actors/actors_test.exs +++ b/test/mobilizon/actors/actors_test.exs @@ -13,7 +13,7 @@ defmodule Mobilizon.ActorsTest do alias Mobilizon.Service.Workers alias Mobilizon.Storage.Page - alias Mobilizon.Federation.ActivityPub + alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Web.Upload.Uploader @@ -106,7 +106,7 @@ defmodule Mobilizon.ActorsTest do preferred_username: preferred_username, domain: domain, avatar: %FileModel{name: picture_name} = _picture - } = _actor} = ActivityPub.get_or_fetch_actor_by_url(@remote_account_url) + } = _actor} = ActivityPubActor.get_or_fetch_actor_by_url(@remote_account_url) assert picture_name == "a28c50ce5f2b13fd.jpg" @@ -156,7 +156,8 @@ defmodule Mobilizon.ActorsTest do test "get_actor_by_name_with_preload!/1 returns the remote actor with its organized events" do use_cassette "actors/remote_actor_mastodon_tcit" do - with {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(@remote_account_url) do + with {:ok, %Actor{} = actor} <- + ActivityPubActor.get_or_fetch_actor_by_url(@remote_account_url) do assert Actors.get_actor_by_name_with_preload( "#{actor.preferred_username}@#{actor.domain}" ).organized_events == [] @@ -186,7 +187,7 @@ defmodule Mobilizon.ActorsTest do %{actor: %Actor{id: actor_id}} do use_cassette "actors/remote_actor_mastodon_tcit" do with {:ok, %Actor{id: actor2_id}} <- - ActivityPub.get_or_fetch_actor_by_url(@remote_account_url) do + ActivityPubActor.get_or_fetch_actor_by_url(@remote_account_url) do %Page{total: 2, elements: actors} = Actors.build_actors_by_username_or_name_page("tcit", actor_type: [:Person],