Make TwAPI UserView more resilient to issues.
authorlain <lain@soykaf.club>
Mon, 7 Jan 2019 11:41:31 +0000 (12:41 +0100)
committerlain <lain@soykaf.club>
Mon, 7 Jan 2019 11:41:31 +0000 (12:41 +0100)
Will work for missing users and badly migrated users.

lib/pleroma/user.ex
lib/pleroma/web/twitter_api/views/activity_view.ex
test/web/twitter_api/views/activity_view_test.exs

index 0e5e2d943e79d5dffd256d9f560df1245b2b7044..85d0f9fce297d8ba6b97c35d3cf7c93615a16b4e 100644 (file)
@@ -367,6 +367,15 @@ defmodule Pleroma.User do
     Repo.get_by(User, ap_id: ap_id)
   end
 
+  # This is mostly an SPC migration fix. This guesses the user nickname (by taking the last part of the ap_id and the domain) and tries to get that user
+  def get_by_guessed_nickname(ap_id) do
+    domain = URI.parse(ap_id).host
+    name = List.last(String.split(ap_id, "/"))
+    nickname = "#{name}@#{domain}"
+
+    get_by_nickname(nickname)
+  end
+
   def update_and_set_cache(changeset) do
     with {:ok, user} <- Repo.update(changeset) do
       Cachex.put(:user_cache, "ap_id:#{user.ap_id}", user)
index ad0cc76edf72adac00a899c19a7f6b052fec5e0d..0bae3d06fb7de1732a781cbedd5304b03cd38b43 100644 (file)
@@ -94,11 +94,25 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
       ap_id == "https://www.w3.org/ns/activitystreams#Public" ->
         nil
 
+      user = User.get_cached_by_ap_id(ap_id) ->
+        user
+
+      user = User.get_by_guessed_nickname(ap_id) ->
+        user
+
       true ->
-        User.get_cached_by_ap_id(ap_id)
+        error_user()
     end
   end
 
+  defp error_user do
+    %User{
+      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 05780a54ada9e4d86793e6e76d01de7843e31948..7f003c2146891f4037e2fcf6f18203ed4f81d10d 100644 (file)
@@ -25,6 +25,34 @@ defmodule Pleroma.Web.TwitterAPI.ActivityViewTest do
 
   import Mock
 
+  test "returns an error user for activities missing users" do
+    user = insert(:user)
+
+    {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"})
+
+    Repo.delete(user)
+    Cachex.clear(:user_cache)
+
+    result = ActivityView.render("activity.json", activity: activity)
+    assert result
+  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 = ActivityView.render("activity.json", activity: activity)
+    assert result["user"]["id"] == user.id
+  end
+
   test "a create activity with a html status" do
     text = """
     #Bike log - Commute Tuesday\nhttps://pla.bike/posts/20181211/\n#cycling #CHScycling #commute\nMVIMG_20181211_054020.jpg