aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/pleroma/web/activity_pub/side_effects.ex82
-rw-r--r--test/pleroma/web/activity_pub/side_effects_test.exs23
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)