Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
5 KB
Referenced Files
None
Subscribers
None
diff --git a/changelog.d/mention-notify-access.security b/changelog.d/mention-notify-access.security
new file mode 100644
index 000000000..2f1830079
--- /dev/null
+++ b/changelog.d/mention-notify-access.security
@@ -0,0 +1 @@
+Do not notify tagged users who cannot see the post
diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex
index 255803c14..b66e0ace6 100644
--- a/lib/pleroma/web/common_api/utils.ex
+++ b/lib/pleroma/web/common_api/utils.ex
@@ -435,13 +435,56 @@ defmodule Pleroma.Web.CommonAPI.Utils do
%{}
end
- tagged_mentions = maybe_extract_mentions(object_data)
+ tagged_mentions =
+ maybe_extract_mentions(object_data)
+ |> filter_tags_to_qualified(activity)
recipients ++ tagged_mentions
end
def maybe_notify_mentioned_recipients(recipients, _), do: recipients
+ # Filter tagged mentions to ensure they can actually access the status
+ defp filter_tags_to_qualified(tagged_mentions, %Activity{
+ recipients: recipients,
+ data: data,
+ actor: actor
+ }) do
+ recipients =
+ if recipients && recipients != [],
+ do: recipients,
+ else:
+ (data["to"] || []) ++ (data["cc"] || []) ++ (data["bto"] || []) ++ (data["bcc"] || [])
+
+ cond do
+ recipients == [] ->
+ []
+
+ Pleroma.Constants.as_public() in recipients ->
+ tagged_mentions
+
+ true ->
+ author = User.get_cached_by_ap_id(actor)
+ to_followers = match?(%User{}, author) and author.follower_address in recipients
+
+ Enum.filter(tagged_mentions, fn tagged ->
+ cond do
+ tagged in recipients ->
+ true
+
+ to_followers ->
+ case User.get_cached_by_ap_id(tagged) do
+ %User{} = tagged_user -> User.following?(tagged_user, author)
+ _ -> false
+ end
+
+ true ->
+ false
+ end
+ end)
+ end
+ end
+
def maybe_notify_followers(recipients, %Activity{data: %{"type" => "Move"}} = activity) do
with %User{} = user <- User.get_cached_by_ap_id(activity.actor) do
user
diff --git a/test/pleroma/notification_test.exs b/test/pleroma/notification_test.exs
index 1ff014a8d..091b9affc 100644
--- a/test/pleroma/notification_test.exs
+++ b/test/pleroma/notification_test.exs
@@ -7,6 +7,8 @@ defmodule Pleroma.NotificationTest do
import Pleroma.Factory
+ require Pleroma.Constants
+
alias Pleroma.FollowingRelationship
alias Pleroma.Notification
alias Pleroma.Object
@@ -628,6 +630,102 @@ defmodule Pleroma.NotificationTest do
assert other_user in enabled_receivers
end
+ defp incoming_note_tagging(author, to, tagged_ap_ids) do
+ tags = Enum.map(tagged_ap_ids, &%{"type" => "Mention", "href" => &1, "name" => &1})
+
+ {:ok, activity} =
+ Transmogrifier.handle_incoming(%{
+ "@context" => "https://www.w3.org/ns/activitystreams",
+ "type" => "Create",
+ "to" => to,
+ "actor" => author.ap_id,
+ "object" => %{
+ "type" => "Note",
+ "id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(),
+ "to" => to,
+ "content" => "tagged",
+ "tag" => tags,
+ "attributedTo" => author.ap_id
+ }
+ })
+
+ activity
+ end
+
+ defp notified_ap_ids(activity),
+ do: activity |> Notification.get_notified_from_activity() |> Enum.map(& &1.ap_id)
+
+ test "it does not notify tagged users who cannot see a followers-only post" do
+ author = insert(:user)
+ tagged = insert(:user)
+
+ activity = incoming_note_tagging(author, [author.follower_address], [tagged.ap_id])
+
+ refute tagged.ap_id in notified_ap_ids(activity)
+ end
+
+ test "it notifies tagged followers of a followers-only post" do
+ author = insert(:user)
+ tagged = insert(:user)
+ {:ok, _, _} = Pleroma.User.follow(tagged, author)
+
+ activity = incoming_note_tagging(author, [author.follower_address], [tagged.ap_id])
+
+ assert tagged.ap_id in notified_ap_ids(activity)
+ end
+
+ test "it does not notify tagged users who are not addressed by a direct message" do
+ author = insert(:user)
+ addressed = insert(:user)
+ tagged = insert(:user)
+
+ activity = incoming_note_tagging(author, [addressed.ap_id], [tagged.ap_id])
+ receivers = notified_ap_ids(activity)
+
+ assert addressed.ap_id in receivers
+ refute tagged.ap_id in receivers
+ end
+
+ test "it notifies tagged users of a public post even if they are not addressed" do
+ author = insert(:user)
+ tagged = insert(:user)
+
+ activity =
+ incoming_note_tagging(author, [Pleroma.Constants.as_public()], [tagged.ap_id])
+
+ assert tagged.ap_id in notified_ap_ids(activity)
+ end
+
+ test "it does not notify tagged users with a pending follow request" do
+ author = insert(:user, is_locked: true)
+ tagged = insert(:user)
+ {:ok, _, _, _} = CommonAPI.follow(author, tagged)
+
+ activity = incoming_note_tagging(author, [author.follower_address], [tagged.ap_id])
+
+ refute tagged.ap_id in notified_ap_ids(activity)
+ end
+
+ test "it ignores tags of unknown users in a followers-only post" do
+ author = insert(:user)
+ tagged = insert(:user)
+
+ follower = insert(:user)
+ {:ok, _, _} = Pleroma.User.follow(follower, author)
+
+ activity =
+ incoming_note_tagging(author, [author.follower_address], [
+ "https://unknown.example/users/nobody",
+ tagged.ap_id,
+ follower.ap_id
+ ])
+
+ receivers = notified_ap_ids(activity)
+
+ refute tagged.ap_id in receivers
+ assert follower.ap_id in receivers
+ end
+
test "it does not send notifications to users who are only cc in new messages" do
user = insert(:user)
other_user = insert(:user)

File Metadata

Mime Type
text/x-diff
Expires
Thu, Oct 29, 5:38 AM (9 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1797593
Default Alt Text
(5 KB)

Event Timeline