MastoAPI: Don't break on missing users.
authorlain <lain@soykaf.club>
Wed, 16 Jan 2019 14:13:09 +0000 (15:13 +0100)
committerlain <lain@soykaf.club>
Wed, 16 Jan 2019 14:13:09 +0000 (15:13 +0100)
lib/pleroma/user.ex
lib/pleroma/web/mastodon_api/views/status_view.ex
lib/pleroma/web/twitter_api/views/activity_view.ex
test/web/mastodon_api/status_view_test.exs

index 68128053903e5f070b3a88413f3010e8a2f9ab7f..a52e536d3397f1e96e43ae46fb4b31128894e981 100644 (file)
@@ -1040,4 +1040,14 @@ defmodule Pleroma.User 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
index db543ffe57a88e40479ee74ba981d694526a1c85..7f5a52ea3e094339a1a32919b0ee96cef7e531fc 100644 (file)
@@ -32,6 +32,19 @@ defmodule Pleroma.Web.MastodonAPI.StatusView 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 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
         "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 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
   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 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
     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
index 108e7bfc5208d3d19def3aefc4c525c1a3669b6b..03708d84cd75e806a8c7a9d5874029854e80e744 100644 (file)
@@ -101,20 +101,10 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView 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)
index 1076b500252455068be3f2036d7ae5ffccc7743c..d30ae61495214955471940ef490f334f73fc727f 100644 (file)
@@ -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)