Merge branch 'replies-domain-block' into 'develop'
authorlain <lain@soykaf.club>
Tue, 2 Jun 2020 14:14:23 +0000 (14:14 +0000)
committerlain <lain@soykaf.club>
Tue, 2 Jun 2020 14:14:23 +0000 (14:14 +0000)
Replies domain block

Closes #1650

See merge request pleroma/pleroma!2622

1  2 
lib/pleroma/web/activity_pub/activity_pub.ex
test/web/mastodon_api/controllers/timeline_controller_test.exs

index a38f9a3c8a101baa4c5d6cc5f3e165a852386dd4,673b10b22125b9fde428e1bfb8a5ff8c750b1ff9..958f3e5afd2b7024d2b0581ebcc79977ae62a402
@@@ -936,6 -936,12 +936,12 @@@ defmodule Pleroma.Web.ActivityPub.Activ
        [activity, object: o] in query,
        where: fragment("not (? = ANY(?))", activity.actor, ^blocked_ap_ids),
        where: fragment("not (? && ?)", activity.recipients, ^blocked_ap_ids),
+       where:
+         fragment(
+           "recipients_contain_blocked_domains(?, ?) = false",
+           activity.recipients,
+           ^domain_blocks
+         ),
        where:
          fragment(
            "not (?->>'type' = 'Announce' and ?->'to' \\?| ?)",
      end
    end
  
 +  defp exclude_invisible_actors(query, %{"invisible_actors" => true}), do: query
 +
 +  defp exclude_invisible_actors(query, _opts) do
 +    invisible_ap_ids =
 +      User.Query.build(%{invisible: true, select: [:ap_id]})
 +      |> Repo.all()
 +      |> Enum.map(fn %{ap_id: ap_id} -> ap_id end)
 +
 +    from([activity] in query, where: activity.actor not in ^invisible_ap_ids)
 +  end
 +
    defp exclude_id(query, %{"exclude_id" => id}) when is_binary(id) do
      from(activity in query, where: activity.id != ^id)
    end
      |> restrict_instance(opts)
      |> Activity.restrict_deactivated_users()
      |> exclude_poll_votes(opts)
 +    |> exclude_invisible_actors(opts)
      |> exclude_visibility(opts)
    end
  
index 65b4079fee0ecd1dd52a67eb37aff1535550e0d5,2ad6828adb16fbb3851ff1f57dbcbf05aca1224f..f069390c11aca746b8b0acf11898199cf72e9d68
@@@ -60,9 -60,9 +60,9 @@@ defmodule Pleroma.Web.MastodonAPI.Timel
    describe "public" do
      @tag capture_log: true
      test "the public timeline", %{conn: conn} do
 -      following = insert(:user)
 +      user = insert(:user)
  
 -      {:ok, _activity} = CommonAPI.post(following, %{status: "test"})
 +      {:ok, activity} = CommonAPI.post(user, %{status: "test"})
  
        _activity = insert(:note_activity, local: false)
  
        conn = get(build_conn(), "/api/v1/timelines/public?local=1")
  
        assert [%{"content" => "test"}] = json_response_and_validate_schema(conn, :ok)
 +
 +      # does not contain repeats
 +      {:ok, _} = CommonAPI.repeat(activity.id, user)
 +
 +      conn = get(build_conn(), "/api/v1/timelines/public?local=true")
 +
 +      assert [_] = json_response_and_validate_schema(conn, :ok)
      end
  
      test "the public timeline includes only public statuses for an authenticated user" do
        res_conn = get(conn, "/api/v1/timelines/public")
        assert length(json_response_and_validate_schema(res_conn, 200)) == 1
      end
+     test "doesn't return replies if follower is posting with blocked user" do
+       %{conn: conn, user: blocker} = oauth_access(["read:statuses"])
+       [blockee, friend] = insert_list(2, :user)
+       {:ok, blocker} = User.follow(blocker, friend)
+       {:ok, _} = User.block(blocker, blockee)
+       conn = assign(conn, :user, blocker)
+       {:ok, %{id: activity_id} = activity} = CommonAPI.post(friend, %{status: "hey!"})
+       {:ok, reply_from_blockee} =
+         CommonAPI.post(blockee, %{status: "heya", in_reply_to_status_id: activity})
+       {:ok, _reply_from_friend} =
+         CommonAPI.post(friend, %{status: "status", in_reply_to_status_id: reply_from_blockee})
+       res_conn = get(conn, "/api/v1/timelines/public")
+       [%{"id" => ^activity_id}] = json_response_and_validate_schema(res_conn, 200)
+     end
+     test "doesn't return replies if follow is posting with users from blocked domain" do
+       %{conn: conn, user: blocker} = oauth_access(["read:statuses"])
+       friend = insert(:user)
+       blockee = insert(:user, ap_id: "https://example.com/users/blocked")
+       {:ok, blocker} = User.follow(blocker, friend)
+       {:ok, blocker} = User.block_domain(blocker, "example.com")
+       conn = assign(conn, :user, blocker)
+       {:ok, %{id: activity_id} = activity} = CommonAPI.post(friend, %{status: "hey!"})
+       {:ok, reply_from_blockee} =
+         CommonAPI.post(blockee, %{status: "heya", in_reply_to_status_id: activity})
+       {:ok, _reply_from_friend} =
+         CommonAPI.post(friend, %{status: "status", in_reply_to_status_id: reply_from_blockee})
+       res_conn = get(conn, "/api/v1/timelines/public")
+       activities = json_response_and_validate_schema(res_conn, 200)
+       [%{"id" => ^activity_id}] = activities
+     end
    end
  
    defp local_and_remote_activities do