Merge branch 'fix/domain-unblocked-reblogs' into 'develop'
authorfeld <feld@feld.me>
Thu, 16 May 2019 18:57:14 +0000 (18:57 +0000)
committerfeld <feld@feld.me>
Thu, 16 May 2019 18:57:14 +0000 (18:57 +0000)
Fix domain-unblocked reblogs

Closes #892

See merge request pleroma/pleroma!1157

1  2 
lib/pleroma/web/activity_pub/activity_pub.ex
test/web/activity_pub/activity_pub_test.exs

index 92d1fab6ee7b1cd618d7c30360bb878fdcf40d1e,2fd073d3adfb2c775980ad6ff094d3e93d2c90d3..6a186efbfddc5b9ab546e543e61d532cb5ff0b26
@@@ -540,6 -540,8 +540,6 @@@ defmodule Pleroma.Web.ActivityPub.Activ
              )
          )
  
 -      Ecto.Adapters.SQL.to_sql(:all, Repo, query)
 -
        query
      else
        Logger.error("Could not restrict visibility to #{visibility}")
            fragment("activity_visibility(?, ?, ?) = ?", a.actor, a.recipients, a.data, ^visibility)
        )
  
 -    Ecto.Adapters.SQL.to_sql(:all, Repo, query)
 -
      query
    end
  
  
    defp restrict_visibility(query, _visibility), do: query
  
 +  defp restrict_thread_visibility(query, %{"user" => %User{ap_id: ap_id}}) do
 +    query =
 +      from(
 +        a in query,
 +        where: fragment("thread_visibility(?, (?)->>'id') = true", ^ap_id, a.data)
 +      )
 +
 +    query
 +  end
 +
 +  defp restrict_thread_visibility(query, _), do: query
 +
    def fetch_user_activities(user, reading_user, params \\ %{}) do
      params =
        params
      blocks = info.blocks || []
      domain_blocks = info.domain_blocks || []
  
+     query =
+       if has_named_binding?(query, :object), do: query, else: Activity.with_joined_object(query)
      from(
-       activity in query,
+       [activity, object: o] in query,
        where: fragment("not (? = ANY(?))", activity.actor, ^blocks),
        where: fragment("not (? && ?)", activity.recipients, ^blocks),
        where:
            activity.data,
            ^blocks
          ),
-       where: fragment("not (split_part(?, '/', 3) = ANY(?))", activity.actor, ^domain_blocks)
+       where: fragment("not (split_part(?, '/', 3) = ANY(?))", activity.actor, ^domain_blocks),
+       where: fragment("not (split_part(?->>'actor', '/', 3) = ANY(?))", o.data, ^domain_blocks)
      )
    end
  
      |> restrict_muted(opts)
      |> restrict_media(opts)
      |> restrict_visibility(opts)
 +    |> restrict_thread_visibility(opts)
      |> restrict_replies(opts)
      |> restrict_reblogs(opts)
      |> restrict_pinned(opts)
      contain_broken_threads(activity, user)
    end
  
 -  # do post-processing on a timeline
 -  def contain_timeline(timeline, user) do
 -    timeline
 -    |> Enum.filter(fn activity ->
 -      contain_activity(activity, user)
 -    end)
 +  def fetch_direct_messages_query do
 +    Activity
 +    |> restrict_type(%{"type" => "Create"})
 +    |> restrict_visibility(%{visibility: "direct"})
 +    |> order_by([activity], asc: activity.id)
    end
  end
index 34e23b8528b4046c98c2ab94552043cd2c49f9d6,dfee93f67af98932332562c9ca42913f62846cbf..c18e0ab5f4e98fbbe1dfde8f115bcfc8ee227e43
@@@ -462,6 -462,29 +462,29 @@@ defmodule Pleroma.Web.ActivityPub.Activ
      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"})
+     note = insert(:note, %{data: %{"actor" => domain_user.ap_id}})
+     activity = insert(:note_activity, %{note: note})
+     user = insert(:user)
+     {:ok, user} = User.block_domain(user, domain)
+     activities =
+       ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true})
+     refute activity in activities
+     followed_user = insert(:user)
+     ActivityPub.follow(user, followed_user)
+     {:ok, repeat_activity, _} = CommonAPI.repeat(activity.id, followed_user)
+     activities =
+       ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true})
+     refute repeat_activity in activities
+   end
    test "doesn't return muted activities" do
      activity_one = insert(:note_activity)
      activity_two = insert(:note_activity)
            "in_reply_to_status_id" => private_activity_2.id
          })
  
 -      activities = ActivityPub.fetch_activities([user1.ap_id | user1.following])
 +      activities =
 +        ActivityPub.fetch_activities([user1.ap_id | user1.following])
 +        |> Enum.map(fn a -> a.id end)
  
        private_activity_1 = Activity.get_by_ap_id_with_object(private_activity_1.data["id"])
  
 -      assert [public_activity, private_activity_1, private_activity_3] == activities
 +      assert [public_activity.id, private_activity_1.id, private_activity_3.id] == activities
  
        assert length(activities) == 3
  
 -      activities = ActivityPub.contain_timeline(activities, user1)
 +      activities =
 +        ActivityPub.fetch_activities([user1.ap_id | user1.following], %{"user" => user1})
 +        |> Enum.map(fn a -> a.id end)
  
 -      assert [public_activity, private_activity_1] == activities
 +      assert [public_activity.id, private_activity_1.id] == activities
        assert length(activities) == 2
      end
    end