From ce517ff4e5a9cc144853ec8112bfac2a38a3a68a Mon Sep 17 00:00:00 2001 From: ilja Date: Thu, 8 Dec 2022 21:53:42 +0100 Subject: [PATCH 1/3] Fix tagpolicy to also work with Update Objects who got updated would just pass the TagPolicy, undoing the moderation that was set in place for the Actor. Now we check not only for Create activities, but also Update activities. --- .../web/activity_pub/mrf/tag_policy.ex | 18 +++--- .../web/activity_pub/mrf/tag_policy_test.exs | 60 +++++++++++++++++++ 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex index 56ae654f2..65a358c59 100644 --- a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex @@ -27,22 +27,22 @@ defp get_tags(_), do: [] defp process_tag( "mrf_tag:media-force-nsfw", %{ - "type" => "Create", + "type" => type, "object" => %{"attachment" => child_attachment} } = message ) - when length(child_attachment) > 0 do + when length(child_attachment) > 0 and type in ["Create", "Update"] do {:ok, Kernel.put_in(message, ["object", "sensitive"], true)} end defp process_tag( "mrf_tag:media-strip", %{ - "type" => "Create", + "type" => type, "object" => %{"attachment" => child_attachment} = object } = message ) - when length(child_attachment) > 0 do + when length(child_attachment) > 0 and type in ["Create", "Update"] do object = Map.delete(object, "attachment") message = Map.put(message, "object", object) @@ -52,13 +52,13 @@ defp process_tag( defp process_tag( "mrf_tag:force-unlisted", %{ - "type" => "Create", + "type" => type, "to" => to, "cc" => cc, "actor" => actor, "object" => object } = message - ) do + ) when type in ["Create", "Update"] do user = User.get_cached_by_ap_id(actor) if Enum.member?(to, Pleroma.Constants.as_public()) do @@ -85,13 +85,13 @@ defp process_tag( defp process_tag( "mrf_tag:sandbox", %{ - "type" => "Create", + "type" => type, "to" => to, "cc" => cc, "actor" => actor, "object" => object } = message - ) do + ) when type in ["Create", "Update"] do user = User.get_cached_by_ap_id(actor) if Enum.member?(to, Pleroma.Constants.as_public()) or @@ -152,7 +152,7 @@ def filter(%{"object" => target_actor, "type" => "Follow"} = message), do: filter_message(target_actor, message) @impl true - def filter(%{"actor" => actor, "type" => "Create"} = message), + def filter(%{"actor" => actor, "type" => type} = message) when type in ["Create", "Update"], do: filter_message(actor, message) @impl true diff --git a/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs b/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs index faaadff79..0c84b5bf3 100644 --- a/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs @@ -53,7 +53,24 @@ test "removes from public timelines" do "cc" => ["d"] } + edit_message = %{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{}, + "to" => [@public, "f"], + "cc" => [@public, "d"] + } + + edit_expect_message = %{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{"to" => ["f", actor.follower_address], "cc" => ["d"]}, + "to" => ["f", actor.follower_address], + "cc" => ["d"] + } + assert TagPolicy.filter(message) == {:ok, except_message} + assert TagPolicy.filter(edit_message) == {:ok, edit_expect_message} end end @@ -77,7 +94,24 @@ test "removes from the federated timeline" do "cc" => ["d", @public] } + edit_message = %{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{}, + "to" => [@public, "f"], + "cc" => [actor.follower_address, "d"] + } + + edit_expect_message = %{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{"to" => ["f", actor.follower_address], "cc" => ["d", @public]}, + "to" => ["f", actor.follower_address], + "cc" => ["d", @public] + } + assert TagPolicy.filter(message) == {:ok, except_message} + assert TagPolicy.filter(edit_message) == {:ok, edit_expect_message} end end @@ -97,7 +131,20 @@ test "removes attachments" do "object" => %{} } + edit_message = %{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{"attachment" => ["file1"]} + } + + edit_expect_message = %{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{} + } + assert TagPolicy.filter(message) == {:ok, except_message} + assert TagPolicy.filter(edit_message) == {:ok, edit_expect_message} end end @@ -117,7 +164,20 @@ test "Mark as sensitive on presence of attachments" do "object" => %{"tag" => ["test"], "attachment" => ["file1"], "sensitive" => true} } + edit_message = %{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{"tag" => ["test"], "attachment" => ["file1"]} + } + + edit_expect_message = %{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{"tag" => ["test"], "attachment" => ["file1"], "sensitive" => true} + } + assert TagPolicy.filter(message) == {:ok, except_message} + assert TagPolicy.filter(edit_message) == {:ok, edit_expect_message} end end end -- 2.43.0 From 1f863f0a36ebb0648c3d39ecb7ea9e3d01deab60 Mon Sep 17 00:00:00 2001 From: ilja Date: Thu, 8 Dec 2022 23:12:27 +0100 Subject: [PATCH 2/3] Fix MRF policies to also work with Update Objects who got updated would just pass through several of the MRF policies, undoing moderation in some situations. In the relevant cases we now check not only for Create activities, but also Update activities. I checked which ones checked explicitly on type Create using `grep '"type" => "Create"' lib/pleroma/web/activity_pub/mrf/*`. The following from that list have not been changed: * lib/pleroma/web/activity_pub/mrf/follow_bot_policy.ex * Not relevant for moderation * lib/pleroma/web/activity_pub/mrf/keyword_policy.ex * Already had a test for Update * lib/pleroma/web/activity_pub/mrf/object_age_policy.ex * In practice only relevant when fetching old objects (e.g. through Like or Announce). These are always wrapped in a Create. * lib/pleroma/web/activity_pub/mrf/reject_non_public.ex * We don't allow changing scope with Update, so not relevant here --- .../mrf/activity_expiration_policy.ex | 11 ++- .../activity_pub/mrf/anti_link_spam_policy.ex | 3 +- .../mrf/force_bot_unlisted_policy.ex | 5 +- .../web/activity_pub/mrf/hellthread_policy.ex | 4 +- .../web/activity_pub/mrf/mention_policy.ex | 2 +- .../web/activity_pub/mrf/simple_policy.ex | 9 +- .../web/activity_pub/mrf/tag_policy.ex | 6 +- .../mrf/activity_expiration_policy_test.exs | 42 +++++++- .../mrf/anti_link_spam_policy_test.exs | 95 +++++++++++++++++++ .../mrf/force_bot_unlisted_policy_test.exs | 25 +++++ .../mrf/hellthread_policy_test.exs | 44 +++++++-- .../activity_pub/mrf/mention_policy_test.exs | 48 ++++++++++ .../activity_pub/mrf/simple_policy_test.exs | 36 +++++++ 13 files changed, 308 insertions(+), 22 deletions(-) diff --git a/lib/pleroma/web/activity_pub/mrf/activity_expiration_policy.ex b/lib/pleroma/web/activity_pub/mrf/activity_expiration_policy.ex index e78254280..5f412566d 100644 --- a/lib/pleroma/web/activity_pub/mrf/activity_expiration_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/activity_expiration_policy.ex @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy do - @moduledoc "Adds expiration to all local Create activities" + @moduledoc "Adds expiration to all local Create/Update activities" @behaviour Pleroma.Web.ActivityPub.MRF.Policy @impl true @@ -25,8 +25,13 @@ defp local?(%{"actor" => actor}) do String.starts_with?(actor, Pleroma.Web.Endpoint.url()) end - defp note?(activity) do - match?(%{"type" => "Create", "object" => %{"type" => "Note"}}, activity) + defp note?(%{"type" => type, "object" => %{"type" => "Note"}}) + when type in ["Create", "Update"] do + true + end + + defp note?(_) do + false end defp maybe_add_expiration(activity) do diff --git a/lib/pleroma/web/activity_pub/mrf/anti_link_spam_policy.ex b/lib/pleroma/web/activity_pub/mrf/anti_link_spam_policy.ex index ba7c8400b..6885df863 100644 --- a/lib/pleroma/web/activity_pub/mrf/anti_link_spam_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/anti_link_spam_policy.ex @@ -29,7 +29,8 @@ defp contains_links?(%{"content" => content} = _object) do defp contains_links?(_), do: false @impl true - def filter(%{"type" => "Create", "actor" => actor, "object" => object} = message) do + def filter(%{"type" => type, "actor" => actor, "object" => object} = message) + when type in ["Create", "Update"] do with {:ok, %User{local: false} = u} <- User.get_or_fetch_by_ap_id(actor), {:contains_links, true} <- {:contains_links, contains_links?(object)}, {:old_user, true} <- {:old_user, old_user?(u)} do diff --git a/lib/pleroma/web/activity_pub/mrf/force_bot_unlisted_policy.ex b/lib/pleroma/web/activity_pub/mrf/force_bot_unlisted_policy.ex index 11871375e..fa6b93333 100644 --- a/lib/pleroma/web/activity_pub/mrf/force_bot_unlisted_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/force_bot_unlisted_policy.ex @@ -17,13 +17,14 @@ defp check_if_bot(user), do: check_by_actor_type(user) or check_by_nickname(user @impl true def filter( %{ - "type" => "Create", + "type" => type, "to" => to, "cc" => cc, "actor" => actor, "object" => object } = message - ) do + ) + when type in ["Create", "Update"] do user = User.get_cached_by_ap_id(actor) isbot = check_if_bot(user) diff --git a/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex b/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex index 504bd4d57..18704fc2c 100644 --- a/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex @@ -73,8 +73,8 @@ defp get_recipient_count(message) do end @impl true - def filter(%{"type" => "Create", "object" => %{"type" => object_type}} = message) - when object_type in ~w{Note Article} do + def filter(%{"type" => type, "object" => %{"type" => object_type}} = message) + when type in ~w{Create Update} and object_type in ~w{Note Article} do reject_threshold = Pleroma.Config.get( [:mrf_hellthread, :reject_threshold], diff --git a/lib/pleroma/web/activity_pub/mrf/mention_policy.ex b/lib/pleroma/web/activity_pub/mrf/mention_policy.ex index 05b28e4f5..11e9bd478 100644 --- a/lib/pleroma/web/activity_pub/mrf/mention_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/mention_policy.ex @@ -8,7 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MentionPolicy do @behaviour Pleroma.Web.ActivityPub.MRF.Policy @impl true - def filter(%{"type" => "Create"} = message) do + def filter(%{"type" => type} = message) when type in ["Create", "Update"] do reject_actors = Pleroma.Config.get([:mrf_mention, :actors], []) recipients = (message["to"] || []) ++ (message["cc"] || []) diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index 415c5d2dd..a59212db4 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -40,9 +40,9 @@ defp check_reject(%{host: actor_host} = _actor_info, object) do defp check_media_removal( %{host: actor_host} = _actor_info, - %{"type" => "Create", "object" => %{"attachment" => child_attachment}} = object + %{"type" => type, "object" => %{"attachment" => child_attachment}} = object ) - when length(child_attachment) > 0 do + when type in ["Create", "Update"] and length(child_attachment) > 0 do media_removal = instance_list(:media_removal) |> MRF.subdomains_regex() @@ -63,10 +63,11 @@ defp check_media_removal(_actor_info, object), do: {:ok, object} defp check_media_nsfw( %{host: actor_host} = _actor_info, %{ - "type" => "Create", + "type" => type, "object" => %{} = _child_object } = object - ) do + ) + when type in ["Create", "Update"] do media_nsfw = instance_list(:media_nsfw) |> MRF.subdomains_regex() diff --git a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex index 65a358c59..634b6a62f 100644 --- a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex @@ -58,7 +58,8 @@ defp process_tag( "actor" => actor, "object" => object } = message - ) when type in ["Create", "Update"] do + ) + when type in ["Create", "Update"] do user = User.get_cached_by_ap_id(actor) if Enum.member?(to, Pleroma.Constants.as_public()) do @@ -91,7 +92,8 @@ defp process_tag( "actor" => actor, "object" => object } = message - ) when type in ["Create", "Update"] do + ) + when type in ["Create", "Update"] do user = User.get_cached_by_ap_id(actor) if Enum.member?(to, Pleroma.Constants.as_public()) or diff --git a/test/pleroma/web/activity_pub/mrf/activity_expiration_policy_test.exs b/test/pleroma/web/activity_pub/mrf/activity_expiration_policy_test.exs index 47b07fdd9..a3c23a85c 100644 --- a/test/pleroma/web/activity_pub/mrf/activity_expiration_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/activity_expiration_policy_test.exs @@ -19,6 +19,16 @@ test "adds `expires_at` property" do }) assert Timex.diff(expires_at, DateTime.utc_now(), :days) == 364 + + assert {:ok, %{"type" => "Update", "expires_at" => expires_at}} = + ActivityExpirationPolicy.filter(%{ + "id" => @id, + "actor" => @local_actor, + "type" => "Update", + "object" => %{"type" => "Note"} + }) + + assert Timex.diff(expires_at, DateTime.utc_now(), :days) == 364 end test "keeps existing `expires_at` if it less than the config setting" do @@ -32,6 +42,15 @@ test "keeps existing `expires_at` if it less than the config setting" do "expires_at" => expires_at, "object" => %{"type" => "Note"} }) + + assert {:ok, %{"type" => "Update", "expires_at" => ^expires_at}} = + ActivityExpirationPolicy.filter(%{ + "id" => @id, + "actor" => @local_actor, + "type" => "Update", + "expires_at" => expires_at, + "object" => %{"type" => "Note"} + }) end test "overwrites existing `expires_at` if it greater than the config setting" do @@ -47,6 +66,17 @@ test "overwrites existing `expires_at` if it greater than the config setting" do }) assert Timex.diff(expires_at, DateTime.utc_now(), :days) == 364 + + assert {:ok, %{"type" => "Update", "expires_at" => expires_at}} = + ActivityExpirationPolicy.filter(%{ + "id" => @id, + "actor" => @local_actor, + "type" => "Update", + "expires_at" => too_distant_future, + "object" => %{"type" => "Note"} + }) + + assert Timex.diff(expires_at, DateTime.utc_now(), :days) == 364 end test "ignores remote activities" do @@ -59,9 +89,19 @@ test "ignores remote activities" do }) refute Map.has_key?(activity, "expires_at") + + assert {:ok, activity} = + ActivityExpirationPolicy.filter(%{ + "id" => "https://example.com/123", + "actor" => "https://example.com/users/cofe", + "type" => "Update", + "object" => %{"type" => "Note"} + }) + + refute Map.has_key?(activity, "expires_at") end - test "ignores non-Create/Note activities" do + test "ignores non-Create/Update/Note activities" do assert {:ok, activity} = ActivityExpirationPolicy.filter(%{ "id" => "https://example.com/123", diff --git a/test/pleroma/web/activity_pub/mrf/anti_link_spam_policy_test.exs b/test/pleroma/web/activity_pub/mrf/anti_link_spam_policy_test.exs index c3ee03a05..6182e9717 100644 --- a/test/pleroma/web/activity_pub/mrf/anti_link_spam_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/anti_link_spam_policy_test.exs @@ -32,6 +32,28 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do } } + @linkless_update_message %{ + "type" => "Update", + "object" => %{ + "content" => "hi world!" + } + } + + @linkful_update_message %{ + "type" => "Update", + "object" => %{ + "content" => "hi world!" + } + } + + @response_update_message %{ + "type" => "Update", + "object" => %{ + "name" => "yes", + "type" => "Answer" + } + } + describe "with new user" do test "it allows posts without links" do user = insert(:user, local: false) @@ -42,7 +64,12 @@ test "it allows posts without links" do @linkless_message |> Map.put("actor", user.ap_id) + update_message = + @linkless_update_message + |> Map.put("actor", user.ap_id) + {:ok, _message} = AntiLinkSpamPolicy.filter(message) + {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message) end test "it disallows posts with links" do @@ -66,7 +93,24 @@ test "it disallows posts with links" do } } + update_message = %{ + "type" => "Update", + "actor" => user.ap_id, + "object" => %{ + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [ + %{ + "content" => "hi world!" + } + ] + }, + "content" => "mew" + } + } + {:reject, _} = MRF.filter_one(AntiLinkSpamPolicy, message) + {:reject, _} = MRF.filter_one(AntiLinkSpamPolicy, update_message) end test "it allows posts with links for local users" do @@ -78,7 +122,12 @@ test "it allows posts with links for local users" do @linkful_message |> Map.put("actor", user.ap_id) + update_message = + @linkful_update_message + |> Map.put("actor", user.ap_id) + {:ok, _message} = AntiLinkSpamPolicy.filter(message) + {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message) end test "it disallows posts with links in history" do @@ -90,7 +139,12 @@ test "it disallows posts with links in history" do @linkful_message |> Map.put("actor", user.ap_id) + update_message = + @linkful_update_message + |> Map.put("actor", user.ap_id) + {:reject, _} = AntiLinkSpamPolicy.filter(message) + {:reject, _} = AntiLinkSpamPolicy.filter(update_message) end end @@ -104,7 +158,12 @@ test "it allows posts without links" do @linkless_message |> Map.put("actor", user.ap_id) + update_message = + @linkless_update_message + |> Map.put("actor", user.ap_id) + {:ok, _message} = AntiLinkSpamPolicy.filter(message) + {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message) end test "it allows posts with links" do @@ -116,7 +175,12 @@ test "it allows posts with links" do @linkful_message |> Map.put("actor", user.ap_id) + update_message = + @linkful_update_message + |> Map.put("actor", user.ap_id) + {:ok, _message} = AntiLinkSpamPolicy.filter(message) + {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message) end end @@ -130,7 +194,12 @@ test "it allows posts without links" do @linkless_message |> Map.put("actor", user.ap_id) + update_message = + @linkless_update_message + |> Map.put("actor", user.ap_id) + {:ok, _message} = AntiLinkSpamPolicy.filter(message) + {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message) end test "it allows posts with links" do @@ -142,7 +211,12 @@ test "it allows posts with links" do @linkful_message |> Map.put("actor", user.ap_id) + update_message = + @linkful_update_message + |> Map.put("actor", user.ap_id) + {:ok, _message} = AntiLinkSpamPolicy.filter(message) + {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message) end end @@ -161,9 +235,17 @@ test "it rejects posts without links" do @linkless_message |> Map.put("actor", "http://invalid.actor") + update_message = + @linkless_update_message + |> Map.put("actor", "http://invalid.actor") + assert capture_log(fn -> {:reject, _} = AntiLinkSpamPolicy.filter(message) end) =~ "[error] Could not decode user at fetch http://invalid.actor" + + assert capture_log(fn -> + {:reject, _} = AntiLinkSpamPolicy.filter(update_message) + end) =~ "[error] Could not decode user at fetch http://invalid.actor" end test "it rejects posts with links" do @@ -171,9 +253,17 @@ test "it rejects posts with links" do @linkful_message |> Map.put("actor", "http://invalid.actor") + update_message = + @linkful_update_message + |> Map.put("actor", "http://invalid.actor") + assert capture_log(fn -> {:reject, _} = AntiLinkSpamPolicy.filter(message) end) =~ "[error] Could not decode user at fetch http://invalid.actor" + + assert capture_log(fn -> + {:reject, _} = AntiLinkSpamPolicy.filter(update_message) + end) =~ "[error] Could not decode user at fetch http://invalid.actor" end end @@ -185,7 +275,12 @@ test "it does not reject them or error out" do @response_message |> Map.put("actor", user.ap_id) + update_message = + @response_update_message + |> Map.put("actor", user.ap_id) + {:ok, _message} = AntiLinkSpamPolicy.filter(message) + {:ok, _update_message} = AntiLinkSpamPolicy.filter(update_message) end end end diff --git a/test/pleroma/web/activity_pub/mrf/force_bot_unlisted_policy_test.exs b/test/pleroma/web/activity_pub/mrf/force_bot_unlisted_policy_test.exs index e3325d144..aa88f2f93 100644 --- a/test/pleroma/web/activity_pub/mrf/force_bot_unlisted_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/force_bot_unlisted_policy_test.exs @@ -26,35 +26,60 @@ defp generate_messages(actor) do }} end + defp generate_update_messages(actor) do + {%{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{}, + "to" => [@public, "f"], + "cc" => [actor.follower_address, "d"] + }, + %{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{"to" => ["f", actor.follower_address], "cc" => ["d", @public]}, + "to" => ["f", actor.follower_address], + "cc" => ["d", @public] + }} + end + test "removes from the federated timeline by nickname heuristics 1" do actor = insert(:user, %{nickname: "annoying_ebooks@example.com"}) {message, except_message} = generate_messages(actor) + {update_message, except_update_message} = generate_update_messages(actor) assert ForceBotUnlistedPolicy.filter(message) == {:ok, except_message} + assert ForceBotUnlistedPolicy.filter(update_message) == {:ok, except_update_message} end test "removes from the federated timeline by nickname heuristics 2" do actor = insert(:user, %{nickname: "cirnonewsnetworkbot@meow.cat"}) {message, except_message} = generate_messages(actor) + {update_message, except_update_message} = generate_update_messages(actor) assert ForceBotUnlistedPolicy.filter(message) == {:ok, except_message} + assert ForceBotUnlistedPolicy.filter(update_message) == {:ok, except_update_message} end test "removes from the federated timeline by actor type Application" do actor = insert(:user, %{actor_type: "Application"}) {message, except_message} = generate_messages(actor) + {update_message, except_update_message} = generate_update_messages(actor) assert ForceBotUnlistedPolicy.filter(message) == {:ok, except_message} + assert ForceBotUnlistedPolicy.filter(update_message) == {:ok, except_update_message} end test "removes from the federated timeline by actor type Service" do actor = insert(:user, %{actor_type: "Service"}) {message, except_message} = generate_messages(actor) + {update_message, except_update_message} = generate_update_messages(actor) assert ForceBotUnlistedPolicy.filter(message) == {:ok, except_message} + assert ForceBotUnlistedPolicy.filter(update_message) == {:ok, except_update_message} end end diff --git a/test/pleroma/web/activity_pub/mrf/hellthread_policy_test.exs b/test/pleroma/web/activity_pub/mrf/hellthread_policy_test.exs index a88e1fa2e..2bcf49bc5 100644 --- a/test/pleroma/web/activity_pub/mrf/hellthread_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/hellthread_policy_test.exs @@ -26,54 +26,86 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do } } - [user: user, message: message] + update_message = %{ + "actor" => user.ap_id, + "cc" => [user.follower_address], + "type" => "Update", + "to" => [ + "https://www.w3.org/ns/activitystreams#Public", + "https://instance.tld/users/user1", + "https://instance.tld/users/user2", + "https://instance.tld/users/user3" + ], + "object" => %{ + "type" => "Note" + } + } + + [user: user, message: message, update_message: update_message] end setup do: clear_config(:mrf_hellthread) describe "reject" do test "rejects the message if the recipient count is above reject_threshold", %{ - message: message + message: message, + update_message: update_message } do clear_config([:mrf_hellthread], %{delist_threshold: 0, reject_threshold: 2}) assert {:reject, "[HellthreadPolicy] 3 recipients is over the limit of 2"} == filter(message) + + assert {:reject, "[HellthreadPolicy] 3 recipients is over the limit of 2"} == + filter(update_message) end test "does not reject the message if the recipient count is below reject_threshold", %{ - message: message + message: message, + update_message: update_message } do clear_config([:mrf_hellthread], %{delist_threshold: 0, reject_threshold: 3}) assert {:ok, ^message} = filter(message) + assert {:ok, ^update_message} = filter(update_message) end end describe "delist" do test "delists the message if the recipient count is above delist_threshold", %{ user: user, - message: message + message: message, + update_message: update_message } do clear_config([:mrf_hellthread], %{delist_threshold: 2, reject_threshold: 0}) {:ok, message} = filter(message) assert user.follower_address in message["to"] assert "https://www.w3.org/ns/activitystreams#Public" in message["cc"] + + {:ok, update_message} = filter(update_message) + assert user.follower_address in update_message["to"] + assert "https://www.w3.org/ns/activitystreams#Public" in update_message["cc"] end test "does not delist the message if the recipient count is below delist_threshold", %{ - message: message + message: message, + update_message: update_message } do clear_config([:mrf_hellthread], %{delist_threshold: 4, reject_threshold: 0}) assert {:ok, ^message} = filter(message) + assert {:ok, ^update_message} = filter(update_message) end end - test "excludes follower collection and public URI from threshold count", %{message: message} do + test "excludes follower collection and public URI from threshold count", %{ + message: message, + update_message: update_message + } do clear_config([:mrf_hellthread], %{delist_threshold: 0, reject_threshold: 3}) assert {:ok, ^message} = filter(message) + assert {:ok, ^update_message} = filter(update_message) end end diff --git a/test/pleroma/web/activity_pub/mrf/mention_policy_test.exs b/test/pleroma/web/activity_pub/mrf/mention_policy_test.exs index 80ddcacbe..8aef8bb1a 100644 --- a/test/pleroma/web/activity_pub/mrf/mention_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/mention_policy_test.exs @@ -18,7 +18,14 @@ test "pass filter if allow list is empty" do "cc" => ["https://example.com/blocked"] } + update_message = %{ + "type" => "Update", + "to" => ["https://example.com/ok"], + "cc" => ["https://example.com/blocked"] + } + assert MentionPolicy.filter(message) == {:ok, message} + assert MentionPolicy.filter(update_message) == {:ok, update_message} end describe "allow" do @@ -29,7 +36,12 @@ test "empty" do "type" => "Create" } + update_message = %{ + "type" => "Update" + } + assert MentionPolicy.filter(message) == {:ok, message} + assert MentionPolicy.filter(update_message) == {:ok, update_message} end test "to" do @@ -40,7 +52,13 @@ test "to" do "to" => ["https://example.com/ok"] } + update_message = %{ + "type" => "Update", + "to" => ["https://example.com/ok"] + } + assert MentionPolicy.filter(message) == {:ok, message} + assert MentionPolicy.filter(update_message) == {:ok, update_message} end test "cc" do @@ -51,7 +69,13 @@ test "cc" do "cc" => ["https://example.com/ok"] } + update_message = %{ + "type" => "Update", + "cc" => ["https://example.com/ok"] + } + assert MentionPolicy.filter(message) == {:ok, message} + assert MentionPolicy.filter(update_message) == {:ok, update_message} end test "both" do @@ -63,7 +87,14 @@ test "both" do "cc" => ["https://example.com/ok2"] } + update_message = %{ + "type" => "Update", + "to" => ["https://example.com/ok"], + "cc" => ["https://example.com/ok2"] + } + assert MentionPolicy.filter(message) == {:ok, message} + assert MentionPolicy.filter(update_message) == {:ok, update_message} end end @@ -76,8 +107,16 @@ test "to" do "to" => ["https://example.com/blocked"] } + update_message = %{ + "type" => "Update", + "to" => ["https://example.com/blocked"] + } + assert MentionPolicy.filter(message) == {:reject, "[MentionPolicy] Rejected for mention of https://example.com/blocked"} + + assert MentionPolicy.filter(update_message) == + {:reject, "[MentionPolicy] Rejected for mention of https://example.com/blocked"} end test "cc" do @@ -89,8 +128,17 @@ test "cc" do "cc" => ["https://example.com/blocked"] } + update_message = %{ + "type" => "Update", + "to" => ["https://example.com/ok"], + "cc" => ["https://example.com/blocked"] + } + assert MentionPolicy.filter(message) == {:reject, "[MentionPolicy] Rejected for mention of https://example.com/blocked"} + + assert MentionPolicy.filter(update_message) == + {:reject, "[MentionPolicy] Rejected for mention of https://example.com/blocked"} end end end diff --git a/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs b/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs index 0569bfed3..036573171 100644 --- a/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs @@ -26,15 +26,18 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do test "is empty" do clear_config([:mrf_simple, :media_removal], []) media_message = build_media_message() + media_update_message = build_media_update_message() local_message = build_local_message() assert SimplePolicy.filter(media_message) == {:ok, media_message} + assert SimplePolicy.filter(media_update_message) == {:ok, media_update_message} assert SimplePolicy.filter(local_message) == {:ok, local_message} end test "has a matching host" do clear_config([:mrf_simple, :media_removal], [{"remote.instance", "Some reason"}]) media_message = build_media_message() + media_update_message = build_media_update_message() local_message = build_local_message() assert SimplePolicy.filter(media_message) == @@ -42,12 +45,18 @@ test "has a matching host" do media_message |> Map.put("object", Map.delete(media_message["object"], "attachment"))} + assert SimplePolicy.filter(media_update_message) == + {:ok, + media_update_message + |> Map.put("object", Map.delete(media_update_message["object"], "attachment"))} + assert SimplePolicy.filter(local_message) == {:ok, local_message} end test "match with wildcard domain" do clear_config([:mrf_simple, :media_removal], [{"*.remote.instance", "Whatever reason"}]) media_message = build_media_message() + media_update_message = build_media_update_message() local_message = build_local_message() assert SimplePolicy.filter(media_message) == @@ -55,6 +64,11 @@ test "match with wildcard domain" do media_message |> Map.put("object", Map.delete(media_message["object"], "attachment"))} + assert SimplePolicy.filter(media_update_message) == + {:ok, + media_update_message + |> Map.put("object", Map.delete(media_update_message["object"], "attachment"))} + assert SimplePolicy.filter(local_message) == {:ok, local_message} end end @@ -63,31 +77,41 @@ test "match with wildcard domain" do test "is empty" do clear_config([:mrf_simple, :media_nsfw], []) media_message = build_media_message() + media_update_message = build_media_update_message() local_message = build_local_message() assert SimplePolicy.filter(media_message) == {:ok, media_message} + assert SimplePolicy.filter(media_update_message) == {:ok, media_update_message} assert SimplePolicy.filter(local_message) == {:ok, local_message} end test "has a matching host" do clear_config([:mrf_simple, :media_nsfw], [{"remote.instance", "Whetever"}]) media_message = build_media_message() + media_update_message = build_media_update_message() local_message = build_local_message() assert SimplePolicy.filter(media_message) == {:ok, put_in(media_message, ["object", "sensitive"], true)} + assert SimplePolicy.filter(media_update_message) == + {:ok, put_in(media_update_message, ["object", "sensitive"], true)} + assert SimplePolicy.filter(local_message) == {:ok, local_message} end test "match with wildcard domain" do clear_config([:mrf_simple, :media_nsfw], [{"*.remote.instance", "yeah yeah"}]) media_message = build_media_message() + media_update_message = build_media_update_message() local_message = build_local_message() assert SimplePolicy.filter(media_message) == {:ok, put_in(media_message, ["object", "sensitive"], true)} + assert SimplePolicy.filter(media_update_message) == + {:ok, put_in(media_update_message, ["object", "sensitive"], true)} + assert SimplePolicy.filter(local_message) == {:ok, local_message} end end @@ -104,6 +128,18 @@ defp build_media_message do } end + defp build_media_update_message do + %{ + "actor" => "https://remote.instance/users/bob", + "type" => "Update", + "object" => %{ + "attachment" => [%{}], + "tag" => ["foo"], + "sensitive" => false + } + } + end + describe "when :report_removal" do test "is empty" do clear_config([:mrf_simple, :report_removal], []) -- 2.43.0 From 0eaec57d3f097b915ef5b4e88bd96069145d7184 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Fri, 9 Dec 2022 10:24:38 +0000 Subject: [PATCH 3/3] mix format --- config/description.exs | 8 +++++++- lib/pleroma/web/static_fe/static_fe_controller.ex | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/config/description.exs b/config/description.exs index a73d2a06b..a6b7231d0 100644 --- a/config/description.exs +++ b/config/description.exs @@ -1295,7 +1295,13 @@ label: "Post Content Type", type: {:dropdown, :atom}, description: "Default post formatting option", - suggestions: ["text/plain", "text/html", "text/markdown", "text/bbcode", "text/x.misskeymarkdown"] + suggestions: [ + "text/plain", + "text/html", + "text/markdown", + "text/bbcode", + "text/x.misskeymarkdown" + ] }, %{ key: :redirectRootNoLogin, diff --git a/lib/pleroma/web/static_fe/static_fe_controller.ex b/lib/pleroma/web/static_fe/static_fe_controller.ex index 0a4327a56..8e454f7a0 100644 --- a/lib/pleroma/web/static_fe/static_fe_controller.ex +++ b/lib/pleroma/web/static_fe/static_fe_controller.ex @@ -209,7 +209,8 @@ defp represent(%Activity{object: %Object{data: data}} = activity, selected) do } end - defp in_reply_to_user(%Activity{object: %Object{data: %{"inReplyTo" => inReplyTo}}} = activity) when is_binary(inReplyTo) do + defp in_reply_to_user(%Activity{object: %Object{data: %{"inReplyTo" => inReplyTo}}} = activity) + when is_binary(inReplyTo) do in_reply_to_activity = Activity.get_in_reply_to_activity(activity) if in_reply_to_activity do -- 2.43.0