ForceMentionsInContent: fix double mentions for Mastodon/Misskey posts

The code checked for duplicates using "ap_id", but in Mastodon and Misskey the look like that:
Mastodon: https://mastodon.example.com/users/roger
Misskey: https:///misskey.example.com/users/104ab42f11

The fix is to also check for "uri", which is what will be in the "explicitly_mentioned_uris" list:
Mastodon: https://mastodon.example.com/@roger
Misskey: https://misskey.example.com/@roger
This commit is contained in:
Zero 2023-05-25 12:36:05 -04:00
parent 5433742faf
commit 279fd47b48
3 changed files with 55 additions and 3 deletions

1
changelog.d/3888.fix Normal file
View file

@ -0,0 +1 @@
ForceMentionsInContent: fix double mentions for Mastodon/Misskey posts

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server # Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent do defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent do
@ -98,8 +98,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent do
explicitly_mentioned_uris = extract_mention_uris_from_content(content) explicitly_mentioned_uris = extract_mention_uris_from_content(content)
added_mentions = added_mentions =
Enum.reduce(mention_users, "", fn %User{ap_id: uri} = user, acc -> Enum.reduce(mention_users, "", fn %User{ap_id: api_id, uri: uri} = user, acc ->
unless uri in explicitly_mentioned_uris do unless Enum.any?([api_id, uri], fn u -> u in explicitly_mentioned_uris end) do
acc <> Formatter.mention_from_user(user, %{mentions_format: :compact}) <> " " acc <> Formatter.mention_from_user(user, %{mentions_format: :compact}) <> " "
else else
acc acc

View file

@ -256,4 +256,55 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do
} }
}} = MRF.filter_one(ForceMentionsInContent, activity) }} = MRF.filter_one(ForceMentionsInContent, activity)
end end
test "don't add duplicate mentions for mastodon or misskey posts" do
[zero, rogerick, greg] = [
insert(:user,
ap_id: "https://pleroma.example.com/users/zero",
uri: "https://pleroma.example.com/users/zero",
nickname: "zero@pleroma.example.com",
local: false
),
insert(:user,
ap_id: "https://misskey.example.com/users/104ab42f11",
uri: "https://misskey.example.com/@rogerick",
nickname: "rogerick@misskey.example.com",
local: false
),
insert(:user,
ap_id: "https://mastodon.example.com/users/greg",
uri: "https://mastodon.example.com/@greg",
nickname: "greg@mastodon.example.com",
local: false
)
]
{:ok, post} = CommonAPI.post(rogerick, %{status: "eugh"})
inline_mentions = [
"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{rogerick.id}\" href=\"#{rogerick.uri}\" rel=\"ugc\">@<span>rogerick</span></a></span>",
"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{greg.id}\" href=\"#{greg.uri}\" rel=\"ugc\">@<span>greg</span></a></span>"
]
activity = %{
"type" => "Create",
"actor" => zero.ap_id,
"object" => %{
"type" => "Note",
"actor" => zero.ap_id,
"content" => "#{Enum.at(inline_mentions, 0)} #{Enum.at(inline_mentions, 1)} erm",
"to" => [
rogerick.ap_id,
greg.ap_id,
Constants.as_public()
],
"inReplyTo" => Object.normalize(post).data["id"]
}
}
{:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
assert filtered ==
"#{Enum.at(inline_mentions, 0)} #{Enum.at(inline_mentions, 1)} erm"
end
end end