diff options
| author | Tusooa Zhu <tusooa@kazv.moe> | 2022-05-29 12:54:57 -0400 | 
|---|---|---|
| committer | Tusooa Zhu <tusooa@kazv.moe> | 2022-05-29 12:54:57 -0400 | 
| commit | 0f6a5eb9a299629f295372f4d5ecdd9083a19717 (patch) | |
| tree | 6da1850c98ae3e8a8f3939336edba9b834676acb | |
| parent | 547def67a76854aa4c9c8438eb1ee4dfa36fd8ac (diff) | |
| download | pleroma-0f6a5eb9a299629f295372f4d5ecdd9083a19717.tar.gz pleroma-0f6a5eb9a299629f295372f4d5ecdd9083a19717.zip | |
Handle Note and Question Updates
| -rw-r--r-- | lib/pleroma/web/activity_pub/side_effects.ex | 82 | ||||
| -rw-r--r-- | test/pleroma/web/activity_pub/side_effects_test.exs | 23 | 
2 files changed, 95 insertions, 10 deletions
| diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex index b997c15db..aeddf3ed8 100644 --- a/lib/pleroma/web/activity_pub/side_effects.ex +++ b/lib/pleroma/web/activity_pub/side_effects.ex @@ -153,23 +153,25 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do    # Tasks this handles:    # - Update the user +  # - Update a non-user object (Note, Question, etc.)    #    # For a local user, we also get a changeset with the full information, so we    # can update non-federating, non-activitypub settings as well.    @impl true    def handle(%{data: %{"type" => "Update", "object" => updated_object}} = object, meta) do -    if changeset = Keyword.get(meta, :user_update_changeset) do -      changeset -      |> User.update_and_set_cache() +    updated_object_id = updated_object["id"] + +    with {_, true} <- {:has_id, is_binary(updated_object_id)}, +         {_, user} <- {:user, Pleroma.User.get_by_ap_id(updated_object_id)} do +      if user do +        handle_update_user(object, meta) +      else +        handle_update_object(object, meta) +      end      else -      {:ok, new_user_data} = ActivityPub.user_data_from_user_object(updated_object) - -      User.get_by_ap_id(updated_object["id"]) -      |> User.remote_user_changeset(new_user_data) -      |> User.update_and_set_cache() +      _ -> +        {:ok, object, meta}      end - -    {:ok, object, meta}    end    # Tasks this handles: @@ -390,6 +392,66 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do      {:ok, object, meta}    end +  defp handle_update_user( +         %{data: %{"type" => "Update", "object" => updated_object}} = object, +         meta +       ) do +    if changeset = Keyword.get(meta, :user_update_changeset) do +      changeset +      |> User.update_and_set_cache() +    else +      {:ok, new_user_data} = ActivityPub.user_data_from_user_object(updated_object) + +      User.get_by_ap_id(updated_object["id"]) +      |> User.remote_user_changeset(new_user_data) +      |> User.update_and_set_cache() +    end + +    {:ok, object, meta} +  end + +  @updatable_object_types ["Note", "Question"] +  # We do not allow poll options to be changed, but the poll description can be. +  @updatable_fields [ +    "source", +    "tag", +    "updated", +    "emoji", +    "content", +    "summary", +    "sensitive", +    "attachment", +    "generator" +  ] +  defp handle_update_object( +         %{data: %{"type" => "Update", "object" => updated_object}} = object, +         meta +       ) do +    orig_object = Object.get_by_ap_id(updated_object["id"]) +    orig_object_data = orig_object.data + +    if orig_object_data["type"] in @updatable_object_types do +      updated_object_data = +        @updatable_fields +        |> Enum.reduce( +          orig_object_data, +          fn field, acc -> +            if Map.has_key?(updated_object, field) do +              Map.put(acc, field, updated_object[field]) +            else +              Map.drop(acc, [field]) +            end +          end +        ) + +      orig_object +      |> Object.change(%{data: updated_object_data}) +      |> Object.update_and_set_cache() +    end + +    {:ok, object, meta} +  end +    def handle_object_creation(%{"type" => "ChatMessage"} = object, _activity, meta) do      with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do        actor = User.get_cached_by_ap_id(object.data["actor"]) diff --git a/test/pleroma/web/activity_pub/side_effects_test.exs b/test/pleroma/web/activity_pub/side_effects_test.exs index 64c4a8c14..f72753116 100644 --- a/test/pleroma/web/activity_pub/side_effects_test.exs +++ b/test/pleroma/web/activity_pub/side_effects_test.exs @@ -140,6 +140,29 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do      end    end +  describe "update notes" do +    setup do +      user = insert(:user) +      note = insert(:note, user: user) + +      updated_note = +        note.data +        |> Map.put("summary", "edited summary") +        |> Map.put("content", "edited content") + +      {:ok, update_data, []} = Builder.update(user, updated_note) +      {:ok, update, _meta} = ActivityPub.persist(update_data, local: true) + +      %{user: user, object_id: note.id, update_data: update_data, update: update} +    end + +    test "it updates the note", %{object_id: object_id, update: update} do +      {:ok, _, _} = SideEffects.handle(update) +      new_note = Pleroma.Object.get_by_id(object_id) +      assert %{"summary" => "edited summary", "content" => "edited content"} = new_note.data +    end +  end +    describe "EmojiReact objects" do      setup do        poster = insert(:user) | 
