From 9e06873d58e031a0f90c6a4d436a6abb5f1ebbae Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Thu, 11 Jul 2019 19:29:24 +0700 Subject: [PATCH] Add `list` to Visibility --- lib/pleroma/list.ex | 6 ++ lib/pleroma/web/activity_pub/visibility.ex | 16 +++++ test/list_test.exs | 11 ++++ test/web/activity_pub/visibilty_test.exs | 72 +++++++++++++++++++--- 4 files changed, 98 insertions(+), 7 deletions(-) diff --git a/lib/pleroma/list.ex b/lib/pleroma/list.ex index 16955b3b5..1d320206e 100644 --- a/lib/pleroma/list.ex +++ b/lib/pleroma/list.ex @@ -146,4 +146,10 @@ def memberships(%User{follower_address: follower_address}) do end def memberships(_), do: [] + + def member?(%Pleroma.List{following: following}, %User{follower_address: follower_address}) do + Enum.member?(following, follower_address) + end + + def member?(_, _), do: false end diff --git a/lib/pleroma/web/activity_pub/visibility.ex b/lib/pleroma/web/activity_pub/visibility.ex index 9908a2e75..e0282d758 100644 --- a/lib/pleroma/web/activity_pub/visibility.ex +++ b/lib/pleroma/web/activity_pub/visibility.ex @@ -34,6 +34,19 @@ def is_direct?(activity) do !is_public?(activity) && !is_private?(activity) end + def is_list?(%{data: %{"listMessage" => _}}), do: true + def is_list?(_), do: false + + def visible_for_user?(%{actor: ap_id}, %User{ap_id: ap_id}), do: true + + def visible_for_user?(%{data: %{"listMessage" => list_ap_id}}, %User{} = user) do + list_ap_id + |> Pleroma.List.get_by_ap_id() + |> Pleroma.List.member?(user) + end + + def visible_for_user?(%{data: %{"listMessage" => _}}, nil), do: false + def visible_for_user?(activity, nil) do is_public?(activity) end @@ -73,6 +86,9 @@ def get_visibility(object) do object.data["directMessage"] == true -> "direct" + is_binary(object.data["listMessage"]) -> + "list" + length(cc) > 0 -> "private" diff --git a/test/list_test.exs b/test/list_test.exs index 6c5c6b197..f39033d02 100644 --- a/test/list_test.exs +++ b/test/list_test.exs @@ -128,4 +128,15 @@ test "memberships" do assert Pleroma.List.memberships(member) == [list.ap_id] end + + test "member?" do + user = insert(:user) + member = insert(:user) + + {:ok, list} = Pleroma.List.create("foo", user) + {:ok, list} = Pleroma.List.follow(list, member) + + assert Pleroma.List.member?(list, member) + refute Pleroma.List.member?(list, user) + end end diff --git a/test/web/activity_pub/visibilty_test.exs b/test/web/activity_pub/visibilty_test.exs index 4d5c07da4..2ce6928c4 100644 --- a/test/web/activity_pub/visibilty_test.exs +++ b/test/web/activity_pub/visibilty_test.exs @@ -16,6 +16,9 @@ defmodule Pleroma.Web.ActivityPub.VisibilityTest do following = insert(:user) unrelated = insert(:user) {:ok, following} = Pleroma.User.follow(following, user) + {:ok, list} = Pleroma.List.create("foo", user) + + Pleroma.List.follow(list, unrelated) {:ok, public} = CommonAPI.post(user, %{"status" => "@#{mentioned.nickname}", "visibility" => "public"}) @@ -29,6 +32,12 @@ defmodule Pleroma.Web.ActivityPub.VisibilityTest do {:ok, unlisted} = CommonAPI.post(user, %{"status" => "@#{mentioned.nickname}", "visibility" => "unlisted"}) + {:ok, list} = + CommonAPI.post(user, %{ + "status" => "@#{mentioned.nickname}", + "visibility" => "list:#{list.id}" + }) + %{ public: public, private: private, @@ -37,29 +46,65 @@ defmodule Pleroma.Web.ActivityPub.VisibilityTest do user: user, mentioned: mentioned, following: following, - unrelated: unrelated + unrelated: unrelated, + list: list } end - test "is_direct?", %{public: public, private: private, direct: direct, unlisted: unlisted} do + test "is_direct?", %{ + public: public, + private: private, + direct: direct, + unlisted: unlisted, + list: list + } do assert Visibility.is_direct?(direct) refute Visibility.is_direct?(public) refute Visibility.is_direct?(private) refute Visibility.is_direct?(unlisted) + assert Visibility.is_direct?(list) end - test "is_public?", %{public: public, private: private, direct: direct, unlisted: unlisted} do + test "is_public?", %{ + public: public, + private: private, + direct: direct, + unlisted: unlisted, + list: list + } do refute Visibility.is_public?(direct) assert Visibility.is_public?(public) refute Visibility.is_public?(private) assert Visibility.is_public?(unlisted) + refute Visibility.is_public?(list) end - test "is_private?", %{public: public, private: private, direct: direct, unlisted: unlisted} do + test "is_private?", %{ + public: public, + private: private, + direct: direct, + unlisted: unlisted, + list: list + } do refute Visibility.is_private?(direct) refute Visibility.is_private?(public) assert Visibility.is_private?(private) refute Visibility.is_private?(unlisted) + refute Visibility.is_private?(list) + end + + test "is_list?", %{ + public: public, + private: private, + direct: direct, + unlisted: unlisted, + list: list + } do + refute Visibility.is_list?(direct) + refute Visibility.is_list?(public) + refute Visibility.is_list?(private) + refute Visibility.is_list?(unlisted) + assert Visibility.is_list?(list) end test "visible_for_user?", %{ @@ -70,7 +115,8 @@ test "visible_for_user?", %{ user: user, mentioned: mentioned, following: following, - unrelated: unrelated + unrelated: unrelated, + list: list } do # All visible to author @@ -78,13 +124,15 @@ test "visible_for_user?", %{ assert Visibility.visible_for_user?(private, user) assert Visibility.visible_for_user?(unlisted, user) assert Visibility.visible_for_user?(direct, user) + assert Visibility.visible_for_user?(list, user) - # All visible to a mentioned user + # All visible to a mentioned user, except when it's a list activity assert Visibility.visible_for_user?(public, mentioned) assert Visibility.visible_for_user?(private, mentioned) assert Visibility.visible_for_user?(unlisted, mentioned) assert Visibility.visible_for_user?(direct, mentioned) + refute(Visibility.visible_for_user?(list, mentioned)) # DM not visible for just follower @@ -92,6 +140,7 @@ test "visible_for_user?", %{ assert Visibility.visible_for_user?(private, following) assert Visibility.visible_for_user?(unlisted, following) refute Visibility.visible_for_user?(direct, following) + refute Visibility.visible_for_user?(list, following) # Public and unlisted visible for unrelated user @@ -99,6 +148,9 @@ test "visible_for_user?", %{ assert Visibility.visible_for_user?(unlisted, unrelated) refute Visibility.visible_for_user?(private, unrelated) refute Visibility.visible_for_user?(direct, unrelated) + + # Visible for a list member + assert Visibility.visible_for_user?(list, unrelated) end test "doesn't die when the user doesn't exist", @@ -115,18 +167,24 @@ test "get_visibility", %{ public: public, private: private, direct: direct, - unlisted: unlisted + unlisted: unlisted, + list: list } do assert Visibility.get_visibility(public) == "public" assert Visibility.get_visibility(private) == "private" assert Visibility.get_visibility(direct) == "direct" assert Visibility.get_visibility(unlisted) == "unlisted" + assert Visibility.get_visibility(list) == "list" end test "get_visibility with directMessage flag" do assert Visibility.get_visibility(%{data: %{"directMessage" => true}}) == "direct" end + test "get_visibility with listMessage flag" do + assert Visibility.get_visibility(%{data: %{"listMessage" => ""}}) == "list" + end + describe "entire_thread_visible_for_user?/2" do test "returns false if not found activity", %{user: user} do refute Visibility.entire_thread_visible_for_user?(%Activity{}, user)