MRF.FODirectReply: use Visibility module to verify the scope

This commit is contained in:
Mark Felder 2024-08-12 20:17:35 -04:00
parent 8c978727c2
commit b0c64945c2
3 changed files with 35 additions and 17 deletions

View file

@ -1 +1 @@
Added MRF.FODirectReply which changes replies to followers-only posts to be direct
Added MRF.FODirectReply which changes replies to followers-only posts to be direct.

View file

@ -7,7 +7,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.FODirectReply do
FODirectReply alters the scope of replies to activities which are Followers Only to be Direct. The purpose of this policy is to prevent broken threads for followers of the reply author because their response was to a user that they are not also following.
"""
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Visibility
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
@ -25,7 +27,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.FODirectReply do
) do
with true <- is_binary(in_reply_to),
%User{follower_address: followers_collection, local: true} <- User.get_by_ap_id(actor),
true <- followers_only?(in_reply_to) do
%Object{} = in_reply_to_object <- Object.get_by_ap_id(in_reply_to),
"private" <- Visibility.get_visibility(in_reply_to_object) do
direct_to = to -- [followers_collection]
updated_activity =
@ -47,19 +50,4 @@ defmodule Pleroma.Web.ActivityPub.MRF.FODirectReply do
@impl true
def describe, do: {:ok, %{}}
defp followers_only?(parent_ap_id) do
with %Pleroma.Object{} = object <- Pleroma.Object.get_by_ap_id(parent_ap_id),
object_data <- Map.get(object, :data),
%Pleroma.User{} = user <- User.get_cached_by_ap_id(object_data["actor"]) do
if user.follower_address in object_data["to"] do
true
else
false
end
else
_ ->
false
end
end
end

View file

@ -48,6 +48,36 @@ defmodule Pleroma.Web.ActivityPub.MRF.FODirectReplyTest do
assert expected_cc == filtered["object"]["cc"]
end
test "replies to unlisted posts are unmodified" do
batman = insert(:user, nickname: "batman")
robin = insert(:user, nickname: "robin")
{:ok, post} =
CommonAPI.post(batman, %{
status: "Has anyone seen Selina Kyle's latest selfies?",
visibility: "unlisted"
})
reply = %{
"type" => "Create",
"actor" => robin.ap_id,
"to" => [batman.ap_id, robin.follower_address],
"cc" => [],
"object" => %{
"type" => "Note",
"actor" => robin.ap_id,
"content" => "@batman 🤤 ❤️ 🐈<200d>⬛",
"to" => [batman.ap_id, robin.follower_address],
"cc" => [],
"inReplyTo" => Object.normalize(post).data["id"]
}
}
assert {:ok, filtered} = FODirectReply.filter(reply)
assert match?(^filtered, reply)
end
test "replies to public posts are unmodified" do
batman = insert(:user, nickname: "batman")
robin = insert(:user, nickname: "robin")