From 27d271b4efd452db791613b426c88f1fecee1b83 Mon Sep 17 00:00:00 2001 From: tusooa Date: Tue, 13 Dec 2022 21:30:10 -0500 Subject: [PATCH 01/12] Add maybe_anonymize_reporter/1 --- config/config.exs | 4 +- config/description.exs | 17 ++++++ lib/pleroma/web/activity_pub/utils.ex | 12 ++++ test/pleroma/web/activity_pub/utils_test.exs | 60 ++++++++++++++++++++ 4 files changed, 92 insertions(+), 1 deletion(-) diff --git a/config/config.exs b/config/config.exs index a231c5ba0..bbfd04973 100644 --- a/config/config.exs +++ b/config/config.exs @@ -364,7 +364,9 @@ config :pleroma, :activitypub, note_replies_output_limit: 5, sign_object_fetches: true, authorized_fetch_mode: false, - client_api_enabled: false + client_api_enabled: false, + anonymize_reporter: false, + anonymize_reporter_local_nickname: "" config :pleroma, :streamer, workers: 3, diff --git a/config/description.exs b/config/description.exs index 2f7dc30a0..243f9731a 100644 --- a/config/description.exs +++ b/config/description.exs @@ -1790,6 +1790,23 @@ config :pleroma, :config_description, [ key: :client_api_enabled, type: :boolean, description: "Allow client to server ActivityPub interactions" + }, + %{ + key: :anonymize_reporter, + type: :boolean, + label: "Anonymize local reports", + description: + "If true, replace local reporters with the designated local user for the copy to be sent to remote servers" + }, + %{ + key: :anonymize_reporter_local_nickname, + type: :string, + label: "Anonymized reporter", + description: + "The nickname of the designated local user that replaces the actual reporter in the copy to be sent to remote servers", + suggestions: [ + "lain" + ] } ] }, diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index f30c92abf..08c0d8e6a 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -875,6 +875,18 @@ defmodule Pleroma.Web.ActivityPub.Utils do {:ok, %{activity | data: new_data}} end + def maybe_anonymize_reporter(activity) do + with true <- Pleroma.Config.get([:activitypub, :anonymize_reporter]), + nickname when is_binary(nickname) <- + Pleroma.Config.get([:activitypub, :anonymize_reporter_local_nickname]), + %User{ap_id: ap_id, local: true} <- User.get_cached_by_nickname(nickname) do + activity + |> Map.put("actor", ap_id) + else + _ -> activity + end + end + def update_activity_visibility(activity, visibility) when visibility in @valid_visibilities do [to, cc, recipients] = activity diff --git a/test/pleroma/web/activity_pub/utils_test.exs b/test/pleroma/web/activity_pub/utils_test.exs index 45fef154e..fc289d712 100644 --- a/test/pleroma/web/activity_pub/utils_test.exs +++ b/test/pleroma/web/activity_pub/utils_test.exs @@ -670,4 +670,64 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do ) end end + + describe "maybe_anonymize_reporter/1" do + setup do + reporter = insert(:user) + report = %{"actor" => reporter.ap_id} + + %{ + placeholder: insert(:user), + reporter: reporter, + report: report + } + end + + test "anonymize when configured correctly", %{ + placeholder: placeholder, + report: report + } do + clear_config([:activitypub, :anonymize_reporter], true) + clear_config([:activitypub, :anonymize_reporter_local_nickname], placeholder.nickname) + + assert %{"actor" => placeholder.ap_id} == Utils.maybe_anonymize_reporter(report) + end + + test "do not anonymize when disabled", %{ + placeholder: placeholder, + reporter: reporter, + report: report + } do + clear_config([:activitypub, :anonymize_reporter], false) + clear_config([:activitypub, :anonymize_reporter_local_nickname], placeholder.nickname) + + assert %{"actor" => reporter.ap_id} == Utils.maybe_anonymize_reporter(report) + end + + test "do not anonymize when user does not exist", %{ + placeholder: placeholder, + reporter: reporter, + report: report + } do + clear_config([:activitypub, :anonymize_reporter], true) + + clear_config( + [:activitypub, :anonymize_reporter_local_nickname], + placeholder.nickname <> "MewMew" + ) + + assert %{"actor" => reporter.ap_id} == Utils.maybe_anonymize_reporter(report) + end + + test "do not anonymize when user is not local", %{ + reporter: reporter, + report: report + } do + placeholder = insert(:user, local: false) + clear_config([:activitypub, :anonymize_reporter], true) + clear_config([:activitypub, :anonymize_reporter_local_nickname], placeholder.nickname) + + assert %{"actor" => reporter.ap_id} == Utils.maybe_anonymize_reporter(report) + end + end end From 58ec4fd1eec3d7ac59025ab7dfca2ae9475d1b10 Mon Sep 17 00:00:00 2001 From: tusooa Date: Tue, 13 Dec 2022 22:41:19 -0500 Subject: [PATCH 02/12] Anonymize reporter before federating --- lib/pleroma/web/activity_pub/activity_pub.ex | 1 + lib/pleroma/web/activity_pub/utils.ex | 18 ++++++++-- .../web/activity_pub/activity_pub_test.exs | 35 +++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 62c7a7b31..7bf501f77 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -415,6 +415,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do with flag_data <- make_flag_data(params, additional), {:ok, activity} <- insert(flag_data, local), {:ok, stripped_activity} <- strip_report_status_data(activity), + stripped_activity <- maybe_anonymize_reporter(stripped_activity), _ <- notify_and_stream(activity), :ok <- maybe_federate(stripped_activity) do diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 08c0d8e6a..f230730ab 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -875,15 +875,29 @@ defmodule Pleroma.Web.ActivityPub.Utils do {:ok, %{activity | data: new_data}} end - def maybe_anonymize_reporter(activity) do + def get_anonymized_reporter do with true <- Pleroma.Config.get([:activitypub, :anonymize_reporter]), nickname when is_binary(nickname) <- Pleroma.Config.get([:activitypub, :anonymize_reporter_local_nickname]), %User{ap_id: ap_id, local: true} <- User.get_cached_by_nickname(nickname) do + ap_id + else + _ -> nil + end + end + + def maybe_anonymize_reporter(%Activity{data: data} = activity) do + %Activity{activity | data: maybe_anonymize_reporter(data)} + end + + def maybe_anonymize_reporter(activity) do + ap_id = get_anonymized_reporter() + + if is_binary(ap_id) do activity |> Map.put("actor", ap_id) else - _ -> activity + activity end end diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs index c16f081f6..a4030ff03 100644 --- a/test/pleroma/web/activity_pub/activity_pub_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_test.exs @@ -1707,6 +1707,41 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert_called(Utils.maybe_federate(%{activity | data: new_data})) end + test "anonymize reporter from Flag, before federating it, if configured so", + %{ + reporter: reporter, + context: context, + target_account: target_account, + reported_activity: reported_activity, + object_ap_id: object_ap_id, + content: content + } do + placeholder = insert(:user) + clear_config([:activitypub, :anonymize_reporter], true) + clear_config([:activitypub, :anonymize_reporter_local_nickname], placeholder.nickname) + # Workaround "could not checkout connection" problem + # https://elixirforum.com/t/ecto-timeout-errors-when-wrapping-into-cachex-calls-in-tests/19078/11 + %User{} = User.get_cached_by_nickname(placeholder.nickname) + + with_mock Utils, [:passthrough], [] do + {:ok, activity} = + ActivityPub.flag(%{ + actor: reporter, + context: context, + account: target_account, + statuses: [reported_activity], + content: content + }) + + new_data = + activity.data + |> put_in(["object"], [target_account.ap_id, object_ap_id]) + |> Map.put("actor", placeholder.ap_id) + + assert_called(Utils.maybe_federate(%{activity | data: new_data})) + end + end + test_with_mock "reverts on error", %{ reporter: reporter, From 1121f099e98c62bd6ee7a5a7e4124ae36a45fba1 Mon Sep 17 00:00:00 2001 From: tusooa Date: Thu, 15 Dec 2022 20:20:11 -0500 Subject: [PATCH 03/12] Ensure actor in Activity is also anonymized --- lib/pleroma/web/activity_pub/utils.ex | 3 ++- .../pleroma/web/activity_pub/activity_pub_test.exs | 4 +++- test/pleroma/web/activity_pub/utils_test.exs | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index f230730ab..0b989d02d 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -887,7 +887,8 @@ defmodule Pleroma.Web.ActivityPub.Utils do end def maybe_anonymize_reporter(%Activity{data: data} = activity) do - %Activity{activity | data: maybe_anonymize_reporter(data)} + new_data = maybe_anonymize_reporter(data) + %Activity{activity | actor: new_data["actor"], data: new_data} end def maybe_anonymize_reporter(activity) do diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs index a4030ff03..0eb262fc6 100644 --- a/test/pleroma/web/activity_pub/activity_pub_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_test.exs @@ -1738,7 +1738,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do |> put_in(["object"], [target_account.ap_id, object_ap_id]) |> Map.put("actor", placeholder.ap_id) - assert_called(Utils.maybe_federate(%{activity | data: new_data})) + assert_called( + Utils.maybe_federate(%{activity | actor: placeholder.ap_id, data: new_data}) + ) end end diff --git a/test/pleroma/web/activity_pub/utils_test.exs b/test/pleroma/web/activity_pub/utils_test.exs index fc289d712..a48639c38 100644 --- a/test/pleroma/web/activity_pub/utils_test.exs +++ b/test/pleroma/web/activity_pub/utils_test.exs @@ -693,6 +693,20 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do assert %{"actor" => placeholder.ap_id} == Utils.maybe_anonymize_reporter(report) end + test "anonymize Activity", %{ + placeholder: placeholder, + reporter: reporter, + report: report + } do + clear_config([:activitypub, :anonymize_reporter], true) + clear_config([:activitypub, :anonymize_reporter_local_nickname], placeholder.nickname) + report_activity = %Activity{actor: reporter, data: report} + anon_id = placeholder.ap_id + + assert %Activity{actor: ^anon_id, data: %{"actor" => ^anon_id}} = + Utils.maybe_anonymize_reporter(report_activity) + end + test "do not anonymize when disabled", %{ placeholder: placeholder, reporter: reporter, From b5c97e9ee07545486afb5d5bba3081b427a65334 Mon Sep 17 00:00:00 2001 From: tusooa Date: Tue, 28 Feb 2023 09:01:18 -0500 Subject: [PATCH 04/12] Put strip and anonymize process in prepare_outgoing It is not useful to call maybe_federate() with the processed activity, because it will only record the activity id, and put it into the queue. When the job is invoked, it reads from the database for the activity. This means the changes we just made will be discarded. In this commit, I moved the stripping and anonymizing procedures to Transmogrifier.prepare_outgoing, which is called after the federator reads the activity from the database. --- lib/pleroma/web/activity_pub/activity_pub.ex | 5 +- .../web/activity_pub/transmogrifier.ex | 8 +++ lib/pleroma/web/activity_pub/utils.ex | 14 +++-- .../web/activity_pub/activity_pub_test.exs | 63 ------------------- .../web/activity_pub/transmogrifier_test.exs | 63 +++++++++++++++++++ 5 files changed, 82 insertions(+), 71 deletions(-) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 7bf501f77..a25cc1e03 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -414,11 +414,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do with flag_data <- make_flag_data(params, additional), {:ok, activity} <- insert(flag_data, local), - {:ok, stripped_activity} <- strip_report_status_data(activity), - stripped_activity <- maybe_anonymize_reporter(stripped_activity), _ <- notify_and_stream(activity), - :ok <- - maybe_federate(stripped_activity) do + :ok <- maybe_federate(activity) do User.all_users_with_privilege(:reports_manage_reports) |> Enum.filter(fn user -> user.ap_id != actor end) |> Enum.filter(fn user -> not is_nil(user.email) end) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 6517f5eff..0f8e01396 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -891,6 +891,14 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end + def prepare_outgoing(%{"type" => "Flag"} = data) do + with {:ok, stripped_activity} <- Utils.strip_report_status_data(data), + stripped_activity <- Utils.maybe_anonymize_reporter(stripped_activity), + stripped_activity <- Map.merge(stripped_activity, Utils.make_json_ld_header()) do + {:ok, stripped_activity} + end + end + def prepare_outgoing(%{"type" => _type} = data) do data = data diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 0b989d02d..807ec8710 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -859,8 +859,14 @@ defmodule Pleroma.Web.ActivityPub.Utils do def update_report_state(_, _), do: {:error, "Unsupported state"} - def strip_report_status_data(activity) do - [actor | reported_activities] = activity.data["object"] + def strip_report_status_data(%Activity{} = activity) do + with {:ok, new_data} <- strip_report_status_data(activity.data) do + {:ok, %{activity | data: new_data}} + end + end + + def strip_report_status_data(data) do + [actor | reported_activities] = data["object"] stripped_activities = Enum.reduce(reported_activities, [], fn act, acc -> @@ -870,9 +876,9 @@ defmodule Pleroma.Web.ActivityPub.Utils do end end) - new_data = put_in(activity.data, ["object"], [actor | stripped_activities]) + new_data = put_in(data, ["object"], [actor | stripped_activities]) - {:ok, %{activity | data: new_data}} + {:ok, new_data} end def get_anonymized_reporter do diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs index 0eb262fc6..6da60d64b 100644 --- a/test/pleroma/web/activity_pub/activity_pub_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_test.exs @@ -1681,69 +1681,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do } = activity end - test_with_mock "strips status data from Flag, before federating it", - %{ - reporter: reporter, - context: context, - target_account: target_account, - reported_activity: reported_activity, - object_ap_id: object_ap_id, - content: content - }, - Utils, - [:passthrough], - [] do - {:ok, activity} = - ActivityPub.flag(%{ - actor: reporter, - context: context, - account: target_account, - statuses: [reported_activity], - content: content - }) - - new_data = put_in(activity.data, ["object"], [target_account.ap_id, object_ap_id]) - - assert_called(Utils.maybe_federate(%{activity | data: new_data})) - end - - test "anonymize reporter from Flag, before federating it, if configured so", - %{ - reporter: reporter, - context: context, - target_account: target_account, - reported_activity: reported_activity, - object_ap_id: object_ap_id, - content: content - } do - placeholder = insert(:user) - clear_config([:activitypub, :anonymize_reporter], true) - clear_config([:activitypub, :anonymize_reporter_local_nickname], placeholder.nickname) - # Workaround "could not checkout connection" problem - # https://elixirforum.com/t/ecto-timeout-errors-when-wrapping-into-cachex-calls-in-tests/19078/11 - %User{} = User.get_cached_by_nickname(placeholder.nickname) - - with_mock Utils, [:passthrough], [] do - {:ok, activity} = - ActivityPub.flag(%{ - actor: reporter, - context: context, - account: target_account, - statuses: [reported_activity], - content: content - }) - - new_data = - activity.data - |> put_in(["object"], [target_account.ap_id, object_ap_id]) - |> Map.put("actor", placeholder.ap_id) - - assert_called( - Utils.maybe_federate(%{activity | actor: placeholder.ap_id, data: new_data}) - ) - end - end - test_with_mock "reverts on error", %{ reporter: reporter, diff --git a/test/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs index e0395d7bb..e34a101b2 100644 --- a/test/pleroma/web/activity_pub/transmogrifier_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier_test.exs @@ -642,6 +642,69 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do assert [_, _, %{"@language" => "pl"}] = modified["@context"] end + + test "it strips report data" do + reporter = insert(:user) + target_account = insert(:user) + content = "foobar" + {:ok, reported_activity} = CommonAPI.post(target_account, %{status: content}) + context = Utils.generate_context_id() + + object_ap_id = reported_activity.object.data["id"] + + assert {:ok, activity} = + Pleroma.Web.ActivityPub.ActivityPub.flag(%{ + actor: reporter, + context: context, + account: target_account, + statuses: [reported_activity], + content: content + }) + + {:ok, data} = Transmogrifier.prepare_outgoing(activity.data) + + expected_data = + activity.data + |> put_in(["object"], [target_account.ap_id, object_ap_id]) + |> Map.put("actor", reporter.ap_id) + |> Map.merge(Utils.make_json_ld_header()) + + assert data == expected_data + end + + test "it strips report data and anonymize" do + placeholder = insert(:user) + + reporter = insert(:user) + target_account = insert(:user) + content = "foobar" + {:ok, reported_activity} = CommonAPI.post(target_account, %{status: content}) + context = Utils.generate_context_id() + + object_ap_id = reported_activity.object.data["id"] + + assert {:ok, activity} = + Pleroma.Web.ActivityPub.ActivityPub.flag(%{ + actor: reporter, + context: context, + account: target_account, + statuses: [reported_activity], + content: content + }) + + clear_config([:activitypub, :anonymize_reporter], true) + clear_config([:activitypub, :anonymize_reporter_local_nickname], placeholder.nickname) + + {:ok, data} = Transmogrifier.prepare_outgoing(activity.data) + + expected_data = + activity.data + |> put_in(["object"], [target_account.ap_id, object_ap_id]) + |> Map.put("actor", placeholder.ap_id) + |> Map.merge(Utils.make_json_ld_header()) + + assert data == expected_data + end end describe "actor rewriting" do From 58afb15eab26deba823c0a5de499f4695be900a3 Mon Sep 17 00:00:00 2001 From: tusooa Date: Wed, 1 Mar 2023 22:42:51 -0500 Subject: [PATCH 05/12] Make ActivityPub.Publisher aware of the actor change by Transmogrifier --- lib/pleroma/web/activity_pub/publisher.ex | 13 ++++++ .../web/activity_pub/publisher_test.exs | 44 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex index f160f1e17..fbc548913 100644 --- a/lib/pleroma/web/activity_pub/publisher.ex +++ b/lib/pleroma/web/activity_pub/publisher.ex @@ -92,6 +92,19 @@ defmodule Pleroma.Web.ActivityPub.Publisher do uri = %{path: path} = URI.parse(inbox) {:ok, data} = Transmogrifier.prepare_outgoing(activity.data) + {actor, activity, data} = + with {_, false} <- {:actor_changed?, data["actor"] != activity.data["actor"]} do + {orig_actor, activity, data} + else + {:actor_changed?, true} -> + # If prepare_outgoing changes the actor, re-get it from the db + actor = User.get_cached_by_ap_id(data["actor"]) + + activity = %Activity{activity | actor: actor.ap_id} + + {actor, activity, data} + end + param_cc = Map.get(params, :cc, []) diff --git a/test/pleroma/web/activity_pub/publisher_test.exs b/test/pleroma/web/activity_pub/publisher_test.exs index b7ff0ed5f..01311091a 100644 --- a/test/pleroma/web/activity_pub/publisher_test.exs +++ b/test/pleroma/web/activity_pub/publisher_test.exs @@ -379,6 +379,50 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do ) end + test_with_mock "Publishes with the new actor if prepare_outgoing changes the actor.", + Pleroma.Web.Federator.Publisher, + [:passthrough], + [] do + other_user = + insert(:user, %{ + local: false, + inbox: "https://domain.com/users/nick1/inbox", + ap_enabled: true + }) + + actor = insert(:user) + replaced_actor = insert(:user) + + note_activity = + insert(:note_activity, + user: actor, + data_attrs: %{"to" => [other_user.ap_id]} + ) + + with_mock Pleroma.Web.ActivityPub.Transmogrifier, + prepare_outgoing: fn data -> {:ok, Map.put(data, "actor", replaced_actor.ap_id)} end do + res = Publisher.publish(actor, note_activity) + + assert res == :ok + + refute called( + Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{ + inbox: "https://domain.com/users/nick1/inbox", + actor_id: actor.id, + id: note_activity.data["id"] + }) + ) + + assert called( + Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{ + inbox: "https://domain.com/users/nick1/inbox", + actor_id: replaced_actor.id, + id: note_activity.data["id"] + }) + ) + end + end + test_with_mock "publishes an activity with BCC to all relevant peers.", Pleroma.Web.ActivityPub.Publisher, [:passthrough], From 9d62fca315ab4b0c026828209c0cbc4df243af5b Mon Sep 17 00:00:00 2001 From: tusooa Date: Tue, 18 Jul 2023 18:08:00 -0400 Subject: [PATCH 06/12] Add changelog for anonymizing reports --- changelog.d/report-anon.add | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/report-anon.add diff --git a/changelog.d/report-anon.add b/changelog.d/report-anon.add new file mode 100644 index 000000000..3238d1636 --- /dev/null +++ b/changelog.d/report-anon.add @@ -0,0 +1 @@ +Allow anonymizing reports sent to remote servers From 1df7d428bccd1631fc7988675e4e249af129c5cd Mon Sep 17 00:00:00 2001 From: Ekaterina Vaartis Date: Wed, 18 Jun 2025 20:11:08 +0300 Subject: [PATCH 07/12] Update preparing and tests for current codebase --- lib/pleroma/web/activity_pub/publisher.ex | 15 +++----- .../web/activity_pub/publisher_test.exs | 38 +++++++++---------- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex index fbc548913..707609c2c 100644 --- a/lib/pleroma/web/activity_pub/publisher.ex +++ b/lib/pleroma/web/activity_pub/publisher.ex @@ -92,19 +92,16 @@ defmodule Pleroma.Web.ActivityPub.Publisher do uri = %{path: path} = URI.parse(inbox) {:ok, data} = Transmogrifier.prepare_outgoing(activity.data) - {actor, activity, data} = + + {actor, data} = with {_, false} <- {:actor_changed?, data["actor"] != activity.data["actor"]} do - {orig_actor, activity, data} + {actor, data} else {:actor_changed?, true} -> # If prepare_outgoing changes the actor, re-get it from the db - actor = User.get_cached_by_ap_id(data["actor"]) - - activity = %Activity{activity | actor: actor.ap_id} - - {actor, activity, data} - end - + new_actor = User.get_cached_by_ap_id(data["actor"]) + {new_actor, data} + end param_cc = Map.get(params, :cc, []) diff --git a/test/pleroma/web/activity_pub/publisher_test.exs b/test/pleroma/web/activity_pub/publisher_test.exs index 01311091a..2c9f5fa39 100644 --- a/test/pleroma/web/activity_pub/publisher_test.exs +++ b/test/pleroma/web/activity_pub/publisher_test.exs @@ -380,14 +380,18 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do end test_with_mock "Publishes with the new actor if prepare_outgoing changes the actor.", - Pleroma.Web.Federator.Publisher, + Pleroma.Web.ActivityPub.Publisher, [:passthrough], [] do + mock(fn + %{method: :post, url: "https://domain.com/users/nick1/inbox", body: body} -> + {:ok, %Tesla.Env{status: 200, body: body}} + end) + other_user = insert(:user, %{ local: false, - inbox: "https://domain.com/users/nick1/inbox", - ap_enabled: true + inbox: "https://domain.com/users/nick1/inbox" }) actor = insert(:user) @@ -401,25 +405,19 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do with_mock Pleroma.Web.ActivityPub.Transmogrifier, prepare_outgoing: fn data -> {:ok, Map.put(data, "actor", replaced_actor.ap_id)} end do - res = Publisher.publish(actor, note_activity) + prepared = + Publisher.prepare_one(%{ + inbox: "https://domain.com/users/nick1/inbox", + activity_id: note_activity.id, + cc: ["https://domain.com/users/nick2/inbox"] + }) - assert res == :ok + {:ok, decoded} = Jason.decode(prepared.json) + assert decoded["actor"] == replaced_actor.ap_id - refute called( - Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{ - inbox: "https://domain.com/users/nick1/inbox", - actor_id: actor.id, - id: note_activity.data["id"] - }) - ) - - assert called( - Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{ - inbox: "https://domain.com/users/nick1/inbox", - actor_id: replaced_actor.id, - id: note_activity.data["id"] - }) - ) + {:ok, published} = Publisher.publish_one(prepared) + sent_activity = Jason.decode!(published.body) + assert sent_activity["actor"] == replaced_actor.ap_id end end From 871e9e84926c93acffa72a710907b98ef88192fb Mon Sep 17 00:00:00 2001 From: Ekaterina Vaartis Date: Thu, 19 Jun 2025 12:36:31 +0300 Subject: [PATCH 08/12] Make unaddressed_message? condsider [] as empty --- changelog.d/fix-report-empty-fields.fix | 1 + lib/pleroma/web/activity_pub/utils.ex | 6 +++++- .../web/activity_pub/activity_pub_controller_test.exs | 5 ++--- 3 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 changelog.d/fix-report-empty-fields.fix diff --git a/changelog.d/fix-report-empty-fields.fix b/changelog.d/fix-report-empty-fields.fix new file mode 100644 index 000000000..ba0a2b2a2 --- /dev/null +++ b/changelog.d/fix-report-empty-fields.fix @@ -0,0 +1 @@ +Fix reports being rejected when the activity had an empty CC or TO field (instead of not having them at all) \ No newline at end of file diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 807ec8710..c5a6901d4 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -82,7 +82,11 @@ defmodule Pleroma.Web.ActivityPub.Utils do def unaddressed_message?(params), do: [params["to"], params["cc"], params["bto"], params["bcc"]] - |> Enum.all?(&is_nil(&1)) + |> Enum.all?(fn + nil -> true + [] -> true + _ -> false + end) @spec recipient_in_message(User.t(), User.t(), map()) :: boolean() def recipient_in_message(%User{ap_id: ap_id} = recipient, %User{} = actor, params), diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs index 46b3d5f0d..0c35f4aab 100644 --- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs @@ -1205,9 +1205,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do } ], "actor" => actor.ap_id, - "cc" => [ - reported_user.ap_id - ], + # CC and TO might either not exist at all, or be empty. We should be able to handle either. + # "cc" => [], "content" => "test", "context" => "context", "id" => "http://#{remote_domain}/activities/02be56cf-35e3-46b4-b2c6-47ae08dfee9e", From 71785d7ff7643ff99c042c6bbb5eb45eac2ad7a5 Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Fri, 5 Sep 2025 09:52:12 +0400 Subject: [PATCH 09/12] PublisherTest: Add test for signature replacement --- .../web/activity_pub/publisher_test.exs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/test/pleroma/web/activity_pub/publisher_test.exs b/test/pleroma/web/activity_pub/publisher_test.exs index 1bf301813..8da9df23c 100644 --- a/test/pleroma/web/activity_pub/publisher_test.exs +++ b/test/pleroma/web/activity_pub/publisher_test.exs @@ -14,6 +14,8 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do alias Pleroma.Object alias Pleroma.Tests.ObanHelpers alias Pleroma.Web.ActivityPub.Publisher + alias Pleroma.Web.ActivityPub.Utils + alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.CommonAPI @as_public "https://www.w3.org/ns/activitystreams#Public" @@ -552,4 +554,42 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do assert decoded["cc"] == ["https://example.com/specific/user"] end + + describe "prepare_one/1 with reporter anonymization" do + test_with_mock "signs with the anonymized actor keys when Transmogrifier changes actor", + Pleroma.Signature, + [:passthrough], + sign: fn %Pleroma.User{} = user, headers -> + send(self(), {:signed_as, user.ap_id}) + "TESTSIG" + end do + placeholder = insert(:user) + reporter = insert(:user) + target_account = insert(:user) + + clear_config([:activitypub, :anonymize_reporter], true) + clear_config([:activitypub, :anonymize_reporter_local_nickname], placeholder.nickname) + + {:ok, reported} = CommonAPI.post(target_account, %{status: "content"}) + context = Utils.generate_context_id() + + {:ok, activity} = + ActivityPub.flag(%{ + actor: reporter, + context: context, + account: target_account, + statuses: [reported], + content: "reason" + }) + + _prepared = + Publisher.prepare_one(%{ + inbox: "http://remote.example/users/alice/inbox", + activity_id: activity.id + }) + + assert_received {:signed_as, ap_id} + assert ap_id == placeholder.ap_id + end + end end From 3de250da2361518b764beba26201c160c2e279dc Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Fri, 5 Sep 2025 14:18:12 +0400 Subject: [PATCH 10/12] PublisherTest: Use mox instead of mock. --- config/test.exs | 1 + lib/pleroma/signature.ex | 1 + lib/pleroma/signature/api.ex | 14 ++++++++++++++ lib/pleroma/web/activity_pub/publisher.ex | 10 ++++++++-- test/pleroma/web/activity_pub/publisher_test.exs | 15 ++++++++------- test/support/data_case.ex | 1 + test/support/mocks.ex | 2 ++ 7 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 lib/pleroma/signature/api.ex diff --git a/config/test.exs b/config/test.exs index fefdc2bbc..6446ad49f 100644 --- a/config/test.exs +++ b/config/test.exs @@ -170,6 +170,7 @@ config :pleroma, Pleroma.Upload.Filter.Mogrify, config_impl: Pleroma.StaticStubb config :pleroma, Pleroma.Upload.Filter.Mogrify, mogrify_impl: Pleroma.MogrifyMock config :pleroma, Pleroma.Signature, http_signatures_impl: Pleroma.StubbedHTTPSignaturesMock +config :pleroma, Pleroma.Web.ActivityPub.Publisher, signature_impl: Pleroma.SignatureMock peer_module = if String.to_integer(System.otp_release()) >= 25 do diff --git a/lib/pleroma/signature.ex b/lib/pleroma/signature.ex index 195513478..47d9d46f6 100644 --- a/lib/pleroma/signature.ex +++ b/lib/pleroma/signature.ex @@ -3,6 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Signature do + @behaviour Pleroma.Signature.API @behaviour HTTPSignatures.Adapter alias Pleroma.EctoType.ActivityPub.ObjectValidators diff --git a/lib/pleroma/signature/api.ex b/lib/pleroma/signature/api.ex new file mode 100644 index 000000000..8b4f0c2e4 --- /dev/null +++ b/lib/pleroma/signature/api.ex @@ -0,0 +1,14 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Signature.API do + @moduledoc """ + Behaviour for signing requests and producing HTTP Date headers. + + This is used to allow tests to replace the signing implementation with Mox. + """ + + @callback sign(user :: Pleroma.User.t(), headers :: map()) :: String.t() + @callback signed_date() :: String.t() +end diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex index 9b37712db..1d8896857 100644 --- a/lib/pleroma/web/activity_pub/publisher.ex +++ b/lib/pleroma/web/activity_pub/publisher.ex @@ -26,6 +26,12 @@ defmodule Pleroma.Web.ActivityPub.Publisher do ActivityPub outgoing federation module. """ + @signature_impl Application.compile_env( + :pleroma, + [__MODULE__, :signature_impl], + Pleroma.Signature + ) + @doc """ Enqueue publishing a single activity. """ @@ -125,10 +131,10 @@ defmodule Pleroma.Web.ActivityPub.Publisher do digest = "SHA-256=" <> (:crypto.hash(:sha256, json) |> Base.encode64()) - date = Pleroma.Signature.signed_date() + date = @signature_impl.signed_date() signature = - Pleroma.Signature.sign(actor, %{ + @signature_impl.sign(actor, %{ "(request-target)": "post #{path}", host: signature_host(uri), "content-length": byte_size(json), diff --git a/test/pleroma/web/activity_pub/publisher_test.exs b/test/pleroma/web/activity_pub/publisher_test.exs index 8da9df23c..4721b2432 100644 --- a/test/pleroma/web/activity_pub/publisher_test.exs +++ b/test/pleroma/web/activity_pub/publisher_test.exs @@ -556,13 +556,14 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do end describe "prepare_one/1 with reporter anonymization" do - test_with_mock "signs with the anonymized actor keys when Transmogrifier changes actor", - Pleroma.Signature, - [:passthrough], - sign: fn %Pleroma.User{} = user, headers -> - send(self(), {:signed_as, user.ap_id}) - "TESTSIG" - end do + test "signs with the anonymized actor keys when Transmogrifier changes actor" do + Pleroma.SignatureMock + |> Mox.stub(:signed_date, fn -> Pleroma.Signature.signed_date() end) + |> Mox.expect(:sign, fn %Pleroma.User{} = user, _headers -> + send(self(), {:signed_as, user.ap_id}) + "TESTSIG" + end) + placeholder = insert(:user) reporter = insert(:user) target_account = insert(:user) diff --git a/test/support/data_case.ex b/test/support/data_case.ex index 304bee5da..e33ab4b34 100644 --- a/test/support/data_case.ex +++ b/test/support/data_case.ex @@ -119,6 +119,7 @@ defmodule Pleroma.DataCase do Mox.stub_with(Pleroma.StubbedHTTPSignaturesMock, Pleroma.Test.HTTPSignaturesProxy) Mox.stub_with(Pleroma.DateTimeMock, Pleroma.DateTime.Impl) + Mox.stub_with(Pleroma.SignatureMock, Pleroma.Signature) end def ensure_local_uploader(context) do diff --git a/test/support/mocks.ex b/test/support/mocks.ex index b26834871..25bcb6472 100644 --- a/test/support/mocks.ex +++ b/test/support/mocks.ex @@ -40,3 +40,5 @@ Mox.defmock(Pleroma.Language.LanguageDetectorMock, Mox.defmock(Pleroma.DateTimeMock, for: Pleroma.DateTime) Mox.defmock(Pleroma.MogrifyMock, for: Pleroma.MogrifyBehaviour) + +Mox.defmock(Pleroma.SignatureMock, for: Pleroma.Signature.API) From b023e1591ce207d429d92b6fd1293bc49673c26e Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Fri, 5 Sep 2025 15:04:33 +0400 Subject: [PATCH 11/12] PublisherTest: Mock -> Mox --- config/test.exs | 3 + lib/pleroma/web/activity_pub/publisher.ex | 11 ++- .../web/activity_pub/transmogrifier.ex | 1 + .../web/activity_pub/transmogrifier/api.ex | 11 +++ .../web/activity_pub/publisher_test.exs | 78 +++++++------------ test/support/data_case.ex | 5 ++ test/support/mocks.ex | 4 + 7 files changed, 62 insertions(+), 51 deletions(-) create mode 100644 lib/pleroma/web/activity_pub/transmogrifier/api.ex diff --git a/config/test.exs b/config/test.exs index 6446ad49f..4da2b4f57 100644 --- a/config/test.exs +++ b/config/test.exs @@ -172,6 +172,9 @@ config :pleroma, Pleroma.Upload.Filter.Mogrify, mogrify_impl: Pleroma.MogrifyMoc config :pleroma, Pleroma.Signature, http_signatures_impl: Pleroma.StubbedHTTPSignaturesMock config :pleroma, Pleroma.Web.ActivityPub.Publisher, signature_impl: Pleroma.SignatureMock +config :pleroma, Pleroma.Web.ActivityPub.Publisher, + transmogrifier_impl: Pleroma.Web.ActivityPub.TransmogrifierMock + peer_module = if String.to_integer(System.otp_release()) >= 25 do :peer diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex index 1d8896857..b1c8a8fc1 100644 --- a/lib/pleroma/web/activity_pub/publisher.ex +++ b/lib/pleroma/web/activity_pub/publisher.ex @@ -13,7 +13,6 @@ defmodule Pleroma.Web.ActivityPub.Publisher do alias Pleroma.User alias Pleroma.Web.ActivityPub.Publisher.Prepared alias Pleroma.Web.ActivityPub.Relay - alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Workers.PublisherWorker require Pleroma.Constants @@ -32,6 +31,12 @@ defmodule Pleroma.Web.ActivityPub.Publisher do Pleroma.Signature ) + @transmogrifier_impl Application.compile_env( + :pleroma, + [__MODULE__, :transmogrifier_impl], + Pleroma.Web.ActivityPub.Transmogrifier + ) + @doc """ Enqueue publishing a single activity. """ @@ -74,7 +79,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do Determine if an activity can be represented by running it through Transmogrifier. """ def representable?(%Activity{} = activity) do - with {:ok, _data} <- Transmogrifier.prepare_outgoing(activity.data) do + with {:ok, _data} <- @transmogrifier_impl.prepare_outgoing(activity.data) do true else _e -> @@ -97,7 +102,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do Logger.debug("Federating #{ap_id} to #{inbox}") uri = %{path: path} = URI.parse(inbox) - {:ok, data} = Transmogrifier.prepare_outgoing(activity.data) + {:ok, data} = @transmogrifier_impl.prepare_outgoing(activity.data) {actor, data} = with {_, false} <- {:actor_changed?, data["actor"] != activity.data["actor"]} do diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 9fd6dca8a..00339fad9 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do @moduledoc """ A module to handle coding from internal to wire ActivityPub and back. """ + @behaviour Pleroma.Web.ActivityPub.Transmogrifier.API alias Pleroma.Activity alias Pleroma.EctoType.ActivityPub.ObjectValidators alias Pleroma.Maps diff --git a/lib/pleroma/web/activity_pub/transmogrifier/api.ex b/lib/pleroma/web/activity_pub/transmogrifier/api.ex new file mode 100644 index 000000000..b9f65d17c --- /dev/null +++ b/lib/pleroma/web/activity_pub/transmogrifier/api.ex @@ -0,0 +1,11 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.Transmogrifier.API do + @moduledoc """ + Behaviour for the subset of Transmogrifier used by Publisher. + """ + + @callback prepare_outgoing(map()) :: {:ok, map()} | {:error, term()} +end diff --git a/test/pleroma/web/activity_pub/publisher_test.exs b/test/pleroma/web/activity_pub/publisher_test.exs index 4721b2432..7c59caebb 100644 --- a/test/pleroma/web/activity_pub/publisher_test.exs +++ b/test/pleroma/web/activity_pub/publisher_test.exs @@ -8,7 +8,6 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do import Pleroma.Factory import Tesla.Mock - import Mock alias Pleroma.Activity alias Pleroma.Object @@ -170,10 +169,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do end describe "publish/2" do - test_with_mock "doesn't publish a non-public activity to quarantined instances.", - Pleroma.Web.ActivityPub.Publisher, - [:passthrough], - [] do + test "doesn't publish a non-public activity to quarantined instances." do Config.put([:instance, :quarantined_instances], [{"domain.com", "some reason"}]) follower = @@ -208,10 +204,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do ) end - test_with_mock "Publishes a non-public activity to non-quarantined instances.", - Pleroma.Web.ActivityPub.Publisher, - [:passthrough], - [] do + test "Publishes a non-public activity to non-quarantined instances." do Config.put([:instance, :quarantined_instances], [{"somedomain.com", "some reason"}]) follower = @@ -247,10 +240,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do ) end - test_with_mock "Publishes to directly addressed actors with higher priority.", - Pleroma.Web.ActivityPub.Publisher, - [:passthrough], - [] do + test "Publishes to directly addressed actors with higher priority." do note_activity = insert(:direct_note_activity) actor = Pleroma.User.get_by_ap_id(note_activity.data["actor"]) @@ -259,21 +249,17 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do assert res == :ok - assert called( - Publisher.enqueue_one( - %{ - inbox: :_, - activity_id: note_activity.id - }, - priority: 0 - ) - ) + assert_enqueued( + worker: "Pleroma.Workers.PublisherWorker", + args: %{ + "op" => "publish_one", + "params" => %{"activity_id" => note_activity.id} + }, + priority: 0 + ) end - test_with_mock "Publishes with the new actor if prepare_outgoing changes the actor.", - Pleroma.Web.ActivityPub.Publisher, - [:passthrough], - [] do + test "Publishes with the new actor if prepare_outgoing changes the actor." do mock(fn %{method: :post, url: "https://domain.com/users/nick1/inbox", body: body} -> {:ok, %Tesla.Env{status: 200, body: body}} @@ -294,28 +280,27 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do data_attrs: %{"to" => [other_user.ap_id]} ) - with_mock Pleroma.Web.ActivityPub.Transmogrifier, - prepare_outgoing: fn data -> {:ok, Map.put(data, "actor", replaced_actor.ap_id)} end do - prepared = - Publisher.prepare_one(%{ - inbox: "https://domain.com/users/nick1/inbox", - activity_id: note_activity.id, - cc: ["https://domain.com/users/nick2/inbox"] - }) + Pleroma.Web.ActivityPub.TransmogrifierMock + |> Mox.expect(:prepare_outgoing, fn data -> + {:ok, Map.put(data, "actor", replaced_actor.ap_id)} + end) - {:ok, decoded} = Jason.decode(prepared.json) - assert decoded["actor"] == replaced_actor.ap_id + prepared = + Publisher.prepare_one(%{ + inbox: "https://domain.com/users/nick1/inbox", + activity_id: note_activity.id, + cc: ["https://domain.com/users/nick2/inbox"] + }) - {:ok, published} = Publisher.publish_one(prepared) - sent_activity = Jason.decode!(published.body) - assert sent_activity["actor"] == replaced_actor.ap_id - end + {:ok, decoded} = Jason.decode(prepared.json) + assert decoded["actor"] == replaced_actor.ap_id + + {:ok, published} = Publisher.publish_one(prepared) + sent_activity = Jason.decode!(published.body) + assert sent_activity["actor"] == replaced_actor.ap_id end - test_with_mock "publishes an activity with BCC to all relevant peers.", - Pleroma.Web.ActivityPub.Publisher, - [:passthrough], - [] do + test "publishes an activity with BCC to all relevant peers." do follower = insert(:user, %{ local: false, @@ -347,10 +332,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do ) end - test_with_mock "publishes a delete activity to peers who signed fetch requests to the create acitvity/object.", - Pleroma.Web.ActivityPub.Publisher, - [:passthrough], - [] do + test "publishes a delete activity to peers who signed fetch requests to the create acitvity/object." do fetcher = insert(:user, local: false, diff --git a/test/support/data_case.ex b/test/support/data_case.ex index e33ab4b34..1ef386851 100644 --- a/test/support/data_case.ex +++ b/test/support/data_case.ex @@ -120,6 +120,11 @@ defmodule Pleroma.DataCase do Mox.stub_with(Pleroma.DateTimeMock, Pleroma.DateTime.Impl) Mox.stub_with(Pleroma.SignatureMock, Pleroma.Signature) + + Mox.stub_with( + Pleroma.Web.ActivityPub.TransmogrifierMock, + Pleroma.Web.ActivityPub.Transmogrifier + ) end def ensure_local_uploader(context) do diff --git a/test/support/mocks.ex b/test/support/mocks.ex index 25bcb6472..7e1244220 100644 --- a/test/support/mocks.ex +++ b/test/support/mocks.ex @@ -42,3 +42,7 @@ Mox.defmock(Pleroma.DateTimeMock, for: Pleroma.DateTime) Mox.defmock(Pleroma.MogrifyMock, for: Pleroma.MogrifyBehaviour) Mox.defmock(Pleroma.SignatureMock, for: Pleroma.Signature.API) + +Mox.defmock(Pleroma.Web.ActivityPub.TransmogrifierMock, + for: Pleroma.Web.ActivityPub.Transmogrifier.API +) From 5503247b1532a8ffeffec8614348cc5f52735f8c Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Fri, 5 Sep 2025 15:17:17 +0400 Subject: [PATCH 12/12] PublisherTest: Linting. --- test/pleroma/web/activity_pub/publisher_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/pleroma/web/activity_pub/publisher_test.exs b/test/pleroma/web/activity_pub/publisher_test.exs index 7c59caebb..a55993978 100644 --- a/test/pleroma/web/activity_pub/publisher_test.exs +++ b/test/pleroma/web/activity_pub/publisher_test.exs @@ -12,9 +12,9 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do alias Pleroma.Activity alias Pleroma.Object alias Pleroma.Tests.ObanHelpers + alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Publisher alias Pleroma.Web.ActivityPub.Utils - alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.CommonAPI @as_public "https://www.w3.org/ns/activitystreams#Public"