aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkaniini <nenolod@gmail.com>2018-10-26 06:45:38 +0000
committerkaniini <nenolod@gmail.com>2018-10-26 06:45:38 +0000
commit44762daf5193fd8c4919ebb00214316dfd9d6f5c (patch)
treeba03da29d6805b09b328c5030a2942728455b635
parent9b39670683af82e120689753e20c5fb39ed51ba0 (diff)
parent2ac13061afe4c360bb98ba8f05bc540b2cf27e74 (diff)
downloadpleroma-44762daf5193fd8c4919ebb00214316dfd9d6f5c.tar.gz
Merge branch 'feature/broken-thread-filtering' into 'develop'
broken thread filtering, part 1 See merge request pleroma/pleroma!394
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex33
-rw-r--r--lib/pleroma/web/mastodon_api/mastodon_api_controller.ex1
-rw-r--r--lib/pleroma/web/twitter_api/twitter_api_controller.ex4
-rw-r--r--test/web/activity_pub/activity_pub_test.exs48
4 files changed, 85 insertions, 1 deletions
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index fc191addf..173ca688d 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -787,4 +787,37 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
y = activity.data["to"] ++ (activity.data["cc"] || [])
visible_for_user?(activity, nil) || Enum.any?(x, &(&1 in y))
end
+
+ # guard
+ def entire_thread_visible_for_user?(nil, user), do: false
+
+ # child
+ def entire_thread_visible_for_user?(
+ %Activity{data: %{"object" => %{"inReplyTo" => _parent_id}}} = tail,
+ user
+ ) do
+ parent = Activity.get_in_reply_to_activity(tail)
+ visible_for_user?(tail, user) && entire_thread_visible_for_user?(parent, user)
+ end
+
+ # root
+ def entire_thread_visible_for_user?(tail, user), do: visible_for_user?(tail, user)
+
+ # filter out broken threads
+ def contain_broken_threads(%Activity{} = activity, %User{} = user) do
+ entire_thread_visible_for_user?(activity, user)
+ end
+
+ # do post-processing on a specific activity
+ def contain_activity(%Activity{} = activity, %User{} = user) do
+ 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)
+ end
end
diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
index 751698ca8..bc7558cb8 100644
--- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
+++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
@@ -223,6 +223,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
activities =
ActivityPub.fetch_activities([user.ap_id | user.following], params)
+ |> ActivityPub.contain_timeline(user)
|> Enum.reverse()
conn
diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
index c6637e38d..4fc32b50c 100644
--- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
@@ -79,7 +79,9 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
|> Map.put("blocking_user", user)
|> Map.put("user", user)
- activities = ActivityPub.fetch_activities([user.ap_id | user.following], params)
+ activities =
+ ActivityPub.fetch_activities([user.ap_id | user.following], params)
+ |> ActivityPub.contain_timeline(user)
conn
|> render(ActivityView, "index.json", %{activities: activities, for: user})
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs
index 1cf7d6bbc..35c381ac3 100644
--- a/test/web/activity_pub/activity_pub_test.exs
+++ b/test/web/activity_pub/activity_pub_test.exs
@@ -476,6 +476,54 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
end
+ describe "timeline post-processing" do
+ test "it filters broken threads" do
+ user1 = insert(:user)
+ user2 = insert(:user)
+ user3 = insert(:user)
+
+ {:ok, user1} = User.follow(user1, user3)
+ assert User.following?(user1, user3)
+
+ {:ok, user2} = User.follow(user2, user3)
+ assert User.following?(user2, user3)
+
+ {:ok, user3} = User.follow(user3, user2)
+ assert User.following?(user3, user2)
+
+ {:ok, public_activity} = CommonAPI.post(user3, %{"status" => "hi 1"})
+
+ {:ok, private_activity_1} =
+ CommonAPI.post(user3, %{"status" => "hi 2", "visibility" => "private"})
+
+ {:ok, private_activity_2} =
+ CommonAPI.post(user2, %{
+ "status" => "hi 3",
+ "visibility" => "private",
+ "in_reply_to_status_id" => private_activity_1.id
+ })
+
+ {:ok, private_activity_3} =
+ CommonAPI.post(user3, %{
+ "status" => "hi 4",
+ "visibility" => "private",
+ "in_reply_to_status_id" => private_activity_2.id
+ })
+
+ assert user1.following == [user3.ap_id <> "/followers", user1.ap_id]
+
+ activities = ActivityPub.fetch_activities([user1.ap_id | user1.following])
+
+ assert [public_activity, private_activity_1, private_activity_3] == activities
+ assert length(activities) == 3
+
+ activities = ActivityPub.contain_timeline(activities, user1)
+
+ assert [public_activity, private_activity_1] == activities
+ assert length(activities) == 2
+ end
+ end
+
test "it can fetch plume articles" do
{:ok, object} =
ActivityPub.fetch_object_from_id(