From 943324b66158d1bd2449894ec41bc544c56058a7 Mon Sep 17 00:00:00 2001 From: lain <lain@soykaf.club> Date: Wed, 16 Jan 2019 15:13:09 +0100 Subject: [PATCH] MastoAPI: Don't break on missing users. --- lib/pleroma/user.ex | 10 +++++++ .../web/mastodon_api/views/status_view.ex | 19 ++++++++++-- .../web/twitter_api/views/activity_view.ex | 12 +------- test/web/mastodon_api/status_view_test.exs | 30 +++++++++++++++++++ 4 files changed, 57 insertions(+), 14 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 681280539..a52e536d3 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1040,4 +1040,14 @@ defp local_nickname_regex() do @strict_local_nickname_regex end end + + def error_user(ap_id) do + %User{ + name: ap_id, + ap_id: ap_id, + info: %User.Info{}, + nickname: "erroruser@example.com", + inserted_at: NaiveDateTime.utc_now() + } + end end diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index db543ffe5..7f5a52ea3 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -32,6 +32,19 @@ defp get_replied_to_activities(activities) do end) end + defp get_user(ap_id) do + cond do + user = User.get_cached_by_ap_id(ap_id) -> + user + + user = User.get_by_guessed_nickname(ap_id) -> + user + + true -> + User.error_user(ap_id) + end + end + def render("index.json", opts) do replied_to_activities = get_replied_to_activities(opts.activities) @@ -48,7 +61,7 @@ def render( "status.json", %{activity: %{data: %{"type" => "Announce", "object" => object}} = activity} = opts ) do - user = User.get_cached_by_ap_id(activity.data["actor"]) + user = get_user(activity.data["actor"]) created_at = Utils.to_masto_date(activity.data["published"]) reblogged = Activity.get_create_activity_by_object_ap_id(object) @@ -93,7 +106,7 @@ def render( end def render("status.json", %{activity: %{data: %{"object" => object}} = activity} = opts) do - user = User.get_cached_by_ap_id(activity.data["actor"]) + user = get_user(activity.data["actor"]) like_count = object["like_count"] || 0 announcement_count = object["announcement_count"] || 0 @@ -116,7 +129,7 @@ def render("status.json", %{activity: %{data: %{"object" => object}} = activity} created_at = Utils.to_masto_date(object["published"]) reply_to = get_reply_to(activity, opts) - reply_to_user = reply_to && User.get_cached_by_ap_id(reply_to.data["actor"]) + reply_to_user = reply_to && get_user(reply_to.data["actor"]) content = object diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex index 108e7bfc5..03708d84c 100644 --- a/lib/pleroma/web/twitter_api/views/activity_view.ex +++ b/lib/pleroma/web/twitter_api/views/activity_view.ex @@ -101,20 +101,10 @@ defp get_user(ap_id, opts) do user true -> - error_user(ap_id) + User.error_user(ap_id) end end - defp error_user(ap_id) do - %User{ - name: ap_id, - ap_id: ap_id, - info: %User.Info{}, - nickname: "erroruser@example.com", - inserted_at: NaiveDateTime.utc_now() - } - end - def render("index.json", opts) do context_ids = collect_context_ids(opts.activities) users = collect_users(opts.activities) diff --git a/test/web/mastodon_api/status_view_test.exs b/test/web/mastodon_api/status_view_test.exs index 1076b5002..d30ae6149 100644 --- a/test/web/mastodon_api/status_view_test.exs +++ b/test/web/mastodon_api/status_view_test.exs @@ -19,6 +19,36 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do :ok end + test "returns a temporary ap_id based user for activities missing db users" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) + + Repo.delete(user) + Cachex.clear(:user_cache) + + %{account: ms_user} = StatusView.render("status.json", activity: activity) + + assert ms_user.acct == "erroruser@example.com" + end + + test "tries to get a user by nickname if fetching by ap_id doesn't work" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) + + {:ok, user} = + user + |> Ecto.Changeset.change(%{ap_id: "#{user.ap_id}/extension/#{user.nickname}"}) + |> Repo.update() + + Cachex.clear(:user_cache) + + result = StatusView.render("status.json", activity: activity) + + assert result[:account][:id] == to_string(user.id) + end + test "a note with null content" do note = insert(:note_activity)