Do not crash when remote user follower and following counters are hidden

This commit is contained in:
Egor Kislitsyn 2019-12-19 19:25:23 +07:00
parent d23a80e691
commit 432b3067d4
No known key found for this signature in database
GPG Key ID: 1B49CB15B71E7805
2 changed files with 54 additions and 24 deletions

View File

@ -1298,28 +1298,26 @@ defp object_to_user_data(data) do
def fetch_follow_information_for_user(user) do def fetch_follow_information_for_user(user) do
with {:ok, following_data} <- with {:ok, following_data} <-
Fetcher.fetch_and_contain_remote_object_from_id(user.following_address), Fetcher.fetch_and_contain_remote_object_from_id(user.following_address),
following_count when is_integer(following_count) <- following_data["totalItems"],
{:ok, hide_follows} <- collection_private(following_data), {:ok, hide_follows} <- collection_private(following_data),
{:ok, followers_data} <- {:ok, followers_data} <-
Fetcher.fetch_and_contain_remote_object_from_id(user.follower_address), Fetcher.fetch_and_contain_remote_object_from_id(user.follower_address),
followers_count when is_integer(followers_count) <- followers_data["totalItems"],
{:ok, hide_followers} <- collection_private(followers_data) do {:ok, hide_followers} <- collection_private(followers_data) do
{:ok, {:ok,
%{ %{
hide_follows: hide_follows, hide_follows: hide_follows,
follower_count: followers_count, follower_count: normalize_counter(followers_data["totalItems"]),
following_count: following_count, following_count: normalize_counter(following_data["totalItems"]),
hide_followers: hide_followers hide_followers: hide_followers
}} }}
else else
{:error, _} = e -> {:error, _} = e -> e
e e -> {:error, e}
e ->
{:error, e}
end end
end end
defp normalize_counter(counter) when is_integer(counter), do: counter
defp normalize_counter(_), do: 0
defp maybe_update_follow_information(data) do defp maybe_update_follow_information(data) do
with {:enabled, true} <- with {:enabled, true} <-
{:enabled, Pleroma.Config.get([:instance, :external_user_synchronization])}, {:enabled, Pleroma.Config.get([:instance, :external_user_synchronization])},
@ -1339,24 +1337,18 @@ defp maybe_update_follow_information(data) do
end end
end end
defp collection_private(%{"first" => %{"type" => type}})
when type in ["CollectionPage", "OrderedCollectionPage"],
do: {:ok, false}
defp collection_private(%{"first" => first}) do defp collection_private(%{"first" => first}) do
if is_map(first) and with {:ok, %{"type" => type}} when type in ["CollectionPage", "OrderedCollectionPage"] <-
first["type"] in ["CollectionPage", "OrderedCollectionPage"] do Fetcher.fetch_and_contain_remote_object_from_id(first) do
{:ok, false} {:ok, false}
else else
with {:ok, %{"type" => type}} when type in ["CollectionPage", "OrderedCollectionPage"] <- {:error, {:ok, %{status: code}}} when code in [401, 403] -> {:ok, true}
Fetcher.fetch_and_contain_remote_object_from_id(first) do {:error, _} = e -> e
{:ok, false} e -> {:error, e}
else
{:error, {:ok, %{status: code}}} when code in [401, 403] ->
{:ok, true}
{:error, _} = e ->
e
e ->
{:error, e}
end
end end
end end

View File

@ -1623,6 +1623,44 @@ test "detects hidden follows/followers for friendica" do
assert follow_info.following_count == 32 assert follow_info.following_count == 32
assert follow_info.hide_follows == true assert follow_info.hide_follows == true
end end
test "doesn't crash when follower and following counters are hidden" do
mock(fn env ->
case env.url do
"http://localhost:4001/users/masto_hidden_counters/following" ->
json(%{
"@context" => "https://www.w3.org/ns/activitystreams",
"id" => "http://localhost:4001/users/masto_hidden_counters/followers"
})
"http://localhost:4001/users/masto_hidden_counters/following?page=1" ->
%Tesla.Env{status: 403, body: ""}
"http://localhost:4001/users/masto_hidden_counters/followers" ->
json(%{
"@context" => "https://www.w3.org/ns/activitystreams",
"id" => "http://localhost:4001/users/masto_hidden_counters/following"
})
"http://localhost:4001/users/masto_hidden_counters/followers?page=1" ->
%Tesla.Env{status: 403, body: ""}
end
end)
user =
insert(:user,
local: false,
follower_address: "http://localhost:4001/users/masto_hidden_counters/followers",
following_address: "http://localhost:4001/users/masto_hidden_counters/following"
)
{:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user)
assert follow_info.hide_followers == true
assert follow_info.follower_count == 0
assert follow_info.hide_follows == true
assert follow_info.following_count == 0
end
end end
describe "fetch_favourites/3" do describe "fetch_favourites/3" do