diff options
author | Alex Gleason <alex@alexgleason.me> | 2022-01-30 10:50:35 -0600 |
---|---|---|
committer | Alex Gleason <alex@alexgleason.me> | 2022-01-30 10:50:35 -0600 |
commit | deff42f0345c5e456b8ca0c6fd341aa3d553bd6c (patch) | |
tree | 846f5c1b00a477960535f5a02cd470bc18a811b5 | |
parent | 4883b996adbbe89b2dc9e95d6dea724c1733ed82 (diff) | |
parent | 64944c164f8730c59c3a55e6c2e4b9e444254a9d (diff) | |
download | pleroma-deff42f0345c5e456b8ca0c6fd341aa3d553bd6c.tar.gz |
Merge remote-tracking branch 'origin/develop' into quote-post
3 files changed, 115 insertions, 7 deletions
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..b10b27f06 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 @@ -10,7 +10,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceBotUnlistedPolicy do require Pleroma.Constants defp check_by_actor_type(user), do: user.actor_type in ["Application", "Service"] - defp check_by_nickname(user), do: Regex.match?(~r/bot@|ebooks@/i, user.nickname) + defp check_by_nickname(user), do: Regex.match?(~r/.bot@|ebooks@/i, user.nickname) defp check_if_bot(user), do: check_by_actor_type(user) or check_by_nickname(user) diff --git a/lib/pleroma/web/activity_pub/mrf/force_mentions_in_content.ex b/lib/pleroma/web/activity_pub/mrf/force_mentions_in_content.ex index c9b022cf8..255910b2f 100644 --- a/lib/pleroma/web/activity_pub/mrf/force_mentions_in_content.ex +++ b/lib/pleroma/web/activity_pub/mrf/force_mentions_in_content.ex @@ -3,6 +3,8 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent do + require Pleroma.Constants + alias Pleroma.Formatter alias Pleroma.Object alias Pleroma.User @@ -58,9 +60,25 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent do defp sort_replied_user(users, _), do: users + # Drop constants and the actor's own AP ID + defp clean_recipients(recipients, object) do + Enum.reject(recipients, fn ap_id -> + ap_id in [ + object["object"]["actor"], + Pleroma.Constants.as_public(), + Pleroma.Web.ActivityPub.Utils.as_local_public() + ] + end) + end + @impl true - def filter(%{"type" => "Create", "object" => %{"type" => "Note", "to" => to}} = object) - when is_list(to) do + def filter( + %{ + "type" => "Create", + "object" => %{"type" => "Note", "to" => to, "inReplyTo" => in_reply_to} + } = object + ) + when is_list(to) and is_binary(in_reply_to) do # image-only posts from pleroma apparently reach this MRF without the content field content = object["object"]["content"] || "" @@ -69,6 +87,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent do mention_users = to + |> clean_recipients(object) |> Enum.map(&User.get_cached_by_ap_id/1) |> Enum.reject(&is_nil/1) |> sort_replied_user(replied_to_user) @@ -84,10 +103,23 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent do end end) - content = + recipients_inline = if added_mentions != "", - do: "<span class=\"recipients-inline\">#{added_mentions}</span>" <> content, - else: content + do: "<span class=\"recipients-inline\">#{added_mentions}</span>", + else: "" + + content = + cond do + # For Markdown posts, insert the mentions inside the first <p> tag + recipients_inline != "" && String.starts_with?(content, "<p>") -> + "<p>" <> recipients_inline <> String.trim_leading(content, "<p>") + + recipients_inline != "" -> + recipients_inline <> content + + true -> + content + end {:ok, put_in(object["object"]["content"], content)} end diff --git a/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs b/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs index 3bc07be94..669ec5251 100644 --- a/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs +++ b/test/pleroma/web/activity_pub/mrf/force_mentions_in_content_test.exs @@ -49,7 +49,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity) assert filtered == - "<span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{dielan.id}\" href=\"https://shitposter.club/users/dielan\" rel=\"ugc\">@<span>dielan</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{coolboymew.id}\" href=\"https://shitposter.club/users/coolboymew\" rel=\"ugc\">@<span>coolboymew</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{fence.id}\" href=\"https://xyzzy.link/users/fence\" rel=\"ugc\">@<span>fence</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{hakui.id}\" href=\"https://tuusin.misono-ya.info/users/hakui\" rel=\"ugc\">@<span>hakui</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{lain.id}\" href=\"https://lain.com/users/lain\" rel=\"ugc\">@<span>lain</span></a></span> </span><p>Haha yeah, you can control who you reply to.</p>" + "<p><span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{dielan.id}\" href=\"https://shitposter.club/users/dielan\" rel=\"ugc\">@<span>dielan</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{coolboymew.id}\" href=\"https://shitposter.club/users/coolboymew\" rel=\"ugc\">@<span>coolboymew</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{fence.id}\" href=\"https://xyzzy.link/users/fence\" rel=\"ugc\">@<span>fence</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{hakui.id}\" href=\"https://tuusin.misono-ya.info/users/hakui\" rel=\"ugc\">@<span>hakui</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{lain.id}\" href=\"https://lain.com/users/lain\" rel=\"ugc\">@<span>lain</span></a></span> </span>Haha yeah, you can control who you reply to.</p>" end test "the replied-to user is sorted to the left" do @@ -85,4 +85,80 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do assert filtered == "<span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{luigi.id}\" href=\"#{luigi.ap_id}\" rel=\"ugc\">@<span>luigi</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{mario.id}\" href=\"#{mario.ap_id}\" rel=\"ugc\">@<span>mario</span></a></span> </span>WHA-HA!" end + + test "don't mention self" do + mario = insert(:user, nickname: "mario") + + {:ok, post} = CommonAPI.post(mario, %{status: "Mama mia"}) + + activity = %{ + "type" => "Create", + "actor" => mario.ap_id, + "object" => %{ + "type" => "Note", + "actor" => mario.ap_id, + "content" => "I'ma tired...", + "to" => [ + mario.ap_id, + Constants.as_public() + ], + "inReplyTo" => Object.normalize(post).data["id"] + } + } + + {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity) + assert filtered == "I'ma tired..." + end + + test "don't mention in top-level posts" do + mario = insert(:user, nickname: "mario") + luigi = insert(:user, nickname: "luigi") + + {:ok, post} = CommonAPI.post(mario, %{status: "Letsa go"}) + + activity = %{ + "type" => "Create", + "actor" => mario.ap_id, + "object" => %{ + "type" => "Note", + "actor" => mario.ap_id, + "content" => "Mama mia!", + "to" => [ + luigi.ap_id, + Constants.as_public() + ], + "quoteUrl" => Object.normalize(post).data["id"] + } + } + + {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity) + assert filtered == "Mama mia!" + end + + test "with markdown formatting" do + mario = insert(:user, nickname: "mario") + luigi = insert(:user, nickname: "luigi") + + {:ok, post} = CommonAPI.post(luigi, %{status: "Mama mia"}) + + activity = %{ + "type" => "Create", + "actor" => mario.ap_id, + "object" => %{ + "type" => "Note", + "actor" => mario.ap_id, + "content" => "<p>I'ma tired...</p>", + "to" => [ + luigi.ap_id, + Constants.as_public() + ], + "inReplyTo" => Object.normalize(post).data["id"] + } + } + + {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity) + + assert filtered == + "<p><span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{luigi.id}\" href=\"#{luigi.ap_id}\" rel=\"ugc\">@<span>luigi</span></a></span> </span>I'ma tired...</p>" + end end |