diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md index 696d10e74..f43cde114 100644 --- a/docs/configuration/cheatsheet.md +++ b/docs/configuration/cheatsheet.md @@ -262,8 +262,8 @@ Notes: * `follower_nickname`: The name of the bot account to use for following newly discovered users. Using `followbot` or similar is strongly suggested. #### :mrf_emoji -* `remove_url`: A list of patterns which result in emoji whose URL matches being removed from the message. This will apply to both statuses and user profiles. Each pattern can be a string or a [regular expression](https://hexdocs.pm/elixir/Regex.html). -* `remove_shortcode`: A list of patterns which result in emoji whose shortcode matches being removed from the message. This will apply to both statuses and user profiles. Each pattern can be a string or a [regular expression](https://hexdocs.pm/elixir/Regex.html). +* `remove_url`: A list of patterns which result in emoji whose URL matches being removed from the message. This will apply to statuses, emoji reactions, and user profiles. Each pattern can be a string or a [regular expression](https://hexdocs.pm/elixir/Regex.html). +* `remove_shortcode`: A list of patterns which result in emoji whose shortcode matches being removed from the message. This will apply to statuses, emoji reactions, and user profiles. Each pattern can be a string or a [regular expression](https://hexdocs.pm/elixir/Regex.html). * `federated_timeline_removal_url`: A list of patterns which result in message with emojis whose URLs match being removed from federated timelines (a.k.a unlisted). This will apply only to statuses. Each pattern can be a string or a [regular expression](https://hexdocs.pm/elixir/Regex.html). * `federated_timeline_removal_shortcode`: A list of patterns which result in message with emojis whose shortcodes match being removed from federated timelines (a.k.a unlisted). This will apply only to statuses. Each pattern can be a string or a [regular expression](https://hexdocs.pm/elixir/Regex.html). diff --git a/lib/pleroma/web/activity_pub/mrf/emoji_policy.ex b/lib/pleroma/web/activity_pub/mrf/emoji_policy.ex index 9a2e8eade..13201ac55 100644 --- a/lib/pleroma/web/activity_pub/mrf/emoji_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/emoji_policy.ex @@ -55,6 +55,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicy do end end + @impl Pleroma.Web.ActivityPub.MRF.Policy + def filter(%{"type" => "EmojiReact"} = object) do + with {:ok, _} <- + matched_emoji_checker(config_remove_url(), config_remove_shortcode()).(object) do + {:ok, object} + else + _ -> + {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} + end + end + @impl Pleroma.Web.ActivityPub.MRF.Policy def filter(message) do {:ok, message} @@ -133,20 +144,24 @@ defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicy do end end - defp maybe_delist(%{"object" => object, "to" => to, "type" => "Create"} = activity) do - check = fn object -> - if any_emoji_match?(object, &url_from_tag/1, &url_from_emoji/1, config_unlist_url()) or + defp matched_emoji_checker(urls, shortcodes) do + fn object -> + if any_emoji_match?(object, &url_from_tag/1, &url_from_emoji/1, urls) or any_emoji_match?( object, &shortcode_from_tag/1, &shortcode_from_emoji/1, - config_unlist_shortcode() + shortcodes ) do - {:should_delist, nil} + {:matched, nil} else {:ok, %{}} end end + end + + defp maybe_delist(%{"object" => object, "to" => to, "type" => "Create"} = activity) do + check = matched_emoji_checker(config_unlist_url(), config_unlist_shortcode()) should_delist? = fn object -> with {:ok, _} <- Pleroma.Object.Updater.do_with_history(object, check) do @@ -173,7 +188,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicy do defp any_emoji_match?(object, extract_from_tag, extract_from_emoji, patterns) do Kernel.||( Enum.any?( - object["tag"], + object["tag"] || [], fn %{"type" => "Emoji"} = tag -> str = extract_from_tag.(tag) @@ -188,7 +203,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicy do false end ), - object["emoji"] + (object["emoji"] || []) |> Enum.any?(fn emoji -> match_any?(extract_from_emoji.(emoji), patterns) end) ) end @@ -227,7 +242,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicy do key: :remove_url, type: {:list, :string}, description: """ - A list of patterns which result in emoji whose URL matches being removed from the message. This will apply to both statuses and user profiles. + A list of patterns which result in emoji whose URL matches being removed from the message. This will apply to statuses, emoji reactions, and user profiles. Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`. """, @@ -237,7 +252,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicy do key: :remove_shortcode, type: {:list, :string}, description: """ - A list of patterns which result in emoji whose shortcode matches being removed from the message. This will apply to both statuses and user profiles. + A list of patterns which result in emoji whose shortcode matches being removed from the message. This will apply to statuses, emoji reactions, and user profiles. Each pattern can be a string or [Regex](https://hexdocs.pm/elixir/Regex.html) in the format of `~r/PATTERN/`. """, diff --git a/test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs b/test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs index 1e1b5c578..ae4c44f1c 100644 --- a/test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs @@ -109,6 +109,30 @@ defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicyTest do "cc" => ["https://example.org/someone"] } + @emoji_react_data %{ + "type" => "EmojiReact", + "tag" => [@emoji_tags |> Enum.at(3)], + "object" => "https://example.org/someobject", + "to" => ["https://example.org/self"], + "cc" => ["https://example.org/someone"] + } + + @emoji_react_data_matching_regex %{ + "type" => "EmojiReact", + "tag" => [@emoji_tags |> Enum.at(1)], + "object" => "https://example.org/someobject", + "to" => ["https://example.org/self"], + "cc" => ["https://example.org/someone"] + } + + @emoji_react_data_matching_nothing %{ + "type" => "EmojiReact", + "tag" => [@emoji_tags |> Enum.at(2)], + "object" => "https://example.org/someobject", + "to" => ["https://example.org/self"], + "cc" => ["https://example.org/someone"] + } + describe "remove_url" do setup do clear_config([:mrf_emoji, :remove_url], [ @@ -183,6 +207,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicyTest do assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item end + + test "processes EmojiReact" do + assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} == + MRF.filter_one(EmojiPolicy, @emoji_react_data) + + assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} == + MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex) + + assert {:ok, @emoji_react_data_matching_nothing} == + MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing) + end end describe "remove_shortcode" do @@ -259,6 +294,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicyTest do assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item end + + test "processes EmojiReact" do + assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} == + MRF.filter_one(EmojiPolicy, @emoji_react_data) + + assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} == + MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex) + + assert {:ok, @emoji_react_data_matching_nothing} == + MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing) + end end describe "federated_timeline_removal_url" do