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
					
				
					 3 changed files with 90 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -32,25 +32,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 | 
			
		|||
  require Logger
 | 
			
		||||
  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
 | 
			
		||||
    to = Map.get(data, "to", [])
 | 
			
		||||
    cc = Map.get(data, "cc", [])
 | 
			
		||||
| 
						 | 
				
			
			@ -721,6 +702,26 @@ defp user_activities_recipients(%{reading_user: reading_user}) do
 | 
			
		|||
    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: since_id}) do
 | 
			
		||||
| 
						 | 
				
			
			@ -1144,6 +1145,7 @@ def fetch_activities_query(recipients, opts \\ %{}) do
 | 
			
		|||
    |> restrict_pinned(opts)
 | 
			
		||||
    |> restrict_muted_reblogs(restrict_muted_reblogs_opts)
 | 
			
		||||
    |> restrict_instance(opts)
 | 
			
		||||
    |> restrict_announce_object_actor(opts)
 | 
			
		||||
    |> Activity.restrict_deactivated_users()
 | 
			
		||||
    |> exclude_poll_votes(opts)
 | 
			
		||||
    |> exclude_chat_messages(opts)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,7 @@ def home(%{assigns: %{user: user}} = conn, params) do
 | 
			
		|||
      |> Map.put(:blocking_user, user)
 | 
			
		||||
      |> Map.put(:muting_user, user)
 | 
			
		||||
      |> Map.put(:reply_filtering_user, user)
 | 
			
		||||
      |> Map.put(:announce_filtering_user, user)
 | 
			
		||||
      |> Map.put(:user, user)
 | 
			
		||||
 | 
			
		||||
    activities =
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -574,7 +574,7 @@ test "doesn't return transitive interactions concerning blocked users" do
 | 
			
		|||
    refute Enum.member?(activities, activity_four)
 | 
			
		||||
  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)
 | 
			
		||||
    blockee = 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)
 | 
			
		||||
  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
 | 
			
		||||
    domain = "dogwhistle.zone"
 | 
			
		||||
    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))
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
  describe "replies filtering with private messages" do
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue