Merge branch 'recipients-experiments' into 'develop'
ActivityPub: Don't show announces of your own objects in timeline. See merge request pleroma/pleroma!2637
This commit is contained in:
commit
4115701f71
|
@ -32,25 +32,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
||||||
require Logger
|
require Logger
|
||||||
require Pleroma.Constants
|
require Pleroma.Constants
|
||||||
|
|
||||||
# For Announce activities, we filter the recipients based on following status for any actors
|
|
||||||
# that match actual users. See issue #164 for more information about why this is necessary.
|
|
||||||
defp get_recipients(%{"type" => "Announce"} = data) do
|
|
||||||
to = Map.get(data, "to", [])
|
|
||||||
cc = Map.get(data, "cc", [])
|
|
||||||
bcc = Map.get(data, "bcc", [])
|
|
||||||
actor = User.get_cached_by_ap_id(data["actor"])
|
|
||||||
|
|
||||||
recipients =
|
|
||||||
Enum.filter(Enum.concat([to, cc, bcc]), fn recipient ->
|
|
||||||
case User.get_cached_by_ap_id(recipient) do
|
|
||||||
nil -> true
|
|
||||||
user -> User.following?(user, actor)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
{recipients, to, cc}
|
|
||||||
end
|
|
||||||
|
|
||||||
defp get_recipients(%{"type" => "Create"} = data) do
|
defp get_recipients(%{"type" => "Create"} = data) do
|
||||||
to = Map.get(data, "to", [])
|
to = Map.get(data, "to", [])
|
||||||
cc = Map.get(data, "cc", [])
|
cc = Map.get(data, "cc", [])
|
||||||
|
@ -721,6 +702,26 @@ defp user_activities_recipients(%{reading_user: reading_user}) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp restrict_announce_object_actor(_query, %{announce_filtering_user: _, skip_preload: true}) do
|
||||||
|
raise "Can't use the child object without preloading!"
|
||||||
|
end
|
||||||
|
|
||||||
|
defp restrict_announce_object_actor(query, %{announce_filtering_user: %{ap_id: actor}}) do
|
||||||
|
from(
|
||||||
|
[activity, object] in query,
|
||||||
|
where:
|
||||||
|
fragment(
|
||||||
|
"?->>'type' != ? or ?->>'actor' != ?",
|
||||||
|
activity.data,
|
||||||
|
"Announce",
|
||||||
|
object.data,
|
||||||
|
^actor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp restrict_announce_object_actor(query, _), do: query
|
||||||
|
|
||||||
defp restrict_since(query, %{since_id: ""}), do: query
|
defp restrict_since(query, %{since_id: ""}), do: query
|
||||||
|
|
||||||
defp restrict_since(query, %{since_id: since_id}) do
|
defp restrict_since(query, %{since_id: since_id}) do
|
||||||
|
@ -1144,6 +1145,7 @@ def fetch_activities_query(recipients, opts \\ %{}) do
|
||||||
|> restrict_pinned(opts)
|
|> restrict_pinned(opts)
|
||||||
|> restrict_muted_reblogs(restrict_muted_reblogs_opts)
|
|> restrict_muted_reblogs(restrict_muted_reblogs_opts)
|
||||||
|> restrict_instance(opts)
|
|> restrict_instance(opts)
|
||||||
|
|> restrict_announce_object_actor(opts)
|
||||||
|> Activity.restrict_deactivated_users()
|
|> Activity.restrict_deactivated_users()
|
||||||
|> exclude_poll_votes(opts)
|
|> exclude_poll_votes(opts)
|
||||||
|> exclude_chat_messages(opts)
|
|> exclude_chat_messages(opts)
|
||||||
|
|
|
@ -48,6 +48,7 @@ def home(%{assigns: %{user: user}} = conn, params) do
|
||||||
|> Map.put(:blocking_user, user)
|
|> Map.put(:blocking_user, user)
|
||||||
|> Map.put(:muting_user, user)
|
|> Map.put(:muting_user, user)
|
||||||
|> Map.put(:reply_filtering_user, user)
|
|> Map.put(:reply_filtering_user, user)
|
||||||
|
|> Map.put(:announce_filtering_user, user)
|
||||||
|> Map.put(:user, user)
|
|> Map.put(:user, user)
|
||||||
|
|
||||||
activities =
|
activities =
|
||||||
|
|
|
@ -574,7 +574,7 @@ test "doesn't return transitive interactions concerning blocked users" do
|
||||||
refute Enum.member?(activities, activity_four)
|
refute Enum.member?(activities, activity_four)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "doesn't return announce activities concerning blocked users" do
|
test "doesn't return announce activities with blocked users in 'to'" do
|
||||||
blocker = insert(:user)
|
blocker = insert(:user)
|
||||||
blockee = insert(:user)
|
blockee = insert(:user)
|
||||||
friend = insert(:user)
|
friend = insert(:user)
|
||||||
|
@ -596,6 +596,39 @@ test "doesn't return announce activities concerning blocked users" do
|
||||||
refute Enum.member?(activities, activity_three.id)
|
refute Enum.member?(activities, activity_three.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "doesn't return announce activities with blocked users in 'cc'" do
|
||||||
|
blocker = insert(:user)
|
||||||
|
blockee = insert(:user)
|
||||||
|
friend = insert(:user)
|
||||||
|
|
||||||
|
{:ok, _user_relationship} = User.block(blocker, blockee)
|
||||||
|
|
||||||
|
{:ok, activity_one} = CommonAPI.post(friend, %{status: "hey!"})
|
||||||
|
|
||||||
|
{:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
|
||||||
|
|
||||||
|
assert object = Pleroma.Object.normalize(activity_two)
|
||||||
|
|
||||||
|
data = %{
|
||||||
|
"actor" => friend.ap_id,
|
||||||
|
"object" => object.data["id"],
|
||||||
|
"context" => object.data["context"],
|
||||||
|
"type" => "Announce",
|
||||||
|
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
||||||
|
"cc" => [blockee.ap_id]
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {:ok, activity_three} = ActivityPub.insert(data)
|
||||||
|
|
||||||
|
activities =
|
||||||
|
ActivityPub.fetch_activities([], %{blocking_user: blocker})
|
||||||
|
|> Enum.map(fn act -> act.id end)
|
||||||
|
|
||||||
|
assert Enum.member?(activities, activity_one.id)
|
||||||
|
refute Enum.member?(activities, activity_two.id)
|
||||||
|
refute Enum.member?(activities, activity_three.id)
|
||||||
|
end
|
||||||
|
|
||||||
test "doesn't return activities from blocked domains" do
|
test "doesn't return activities from blocked domains" do
|
||||||
domain = "dogwhistle.zone"
|
domain = "dogwhistle.zone"
|
||||||
domain_user = insert(:user, %{ap_id: "https://#{domain}/@pundit"})
|
domain_user = insert(:user, %{ap_id: "https://#{domain}/@pundit"})
|
||||||
|
@ -1643,6 +1676,40 @@ test "home timeline with reply_visibility `self`", %{
|
||||||
|
|
||||||
assert Enum.all?(visible_ids, &(&1 in activities_ids))
|
assert Enum.all?(visible_ids, &(&1 in activities_ids))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "filtering out announces where the user is the actor of the announced message" do
|
||||||
|
user = insert(:user)
|
||||||
|
other_user = insert(:user)
|
||||||
|
third_user = insert(:user)
|
||||||
|
User.follow(user, other_user)
|
||||||
|
|
||||||
|
{:ok, post} = CommonAPI.post(user, %{status: "yo"})
|
||||||
|
{:ok, other_post} = CommonAPI.post(third_user, %{status: "yo"})
|
||||||
|
{:ok, _announce} = CommonAPI.repeat(post.id, other_user)
|
||||||
|
{:ok, _announce} = CommonAPI.repeat(post.id, third_user)
|
||||||
|
{:ok, announce} = CommonAPI.repeat(other_post.id, other_user)
|
||||||
|
|
||||||
|
params = %{
|
||||||
|
type: ["Announce"]
|
||||||
|
}
|
||||||
|
|
||||||
|
results =
|
||||||
|
[user.ap_id | User.following(user)]
|
||||||
|
|> ActivityPub.fetch_activities(params)
|
||||||
|
|
||||||
|
assert length(results) == 3
|
||||||
|
|
||||||
|
params = %{
|
||||||
|
type: ["Announce"],
|
||||||
|
announce_filtering_user: user
|
||||||
|
}
|
||||||
|
|
||||||
|
[result] =
|
||||||
|
[user.ap_id | User.following(user)]
|
||||||
|
|> ActivityPub.fetch_activities(params)
|
||||||
|
|
||||||
|
assert result.id == announce.id
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "replies filtering with private messages" do
|
describe "replies filtering with private messages" do
|
||||||
|
|
Loading…
Reference in New Issue