Make outbound transmogrifier aware of edit history

This commit is contained in:
Tusooa Zhu 2022-06-25 11:20:46 -04:00
parent 5321fd0012
commit 014096aeef
No known key found for this signature in database
GPG Key ID: 7B467EDE43A08224
5 changed files with 109 additions and 54 deletions

View File

@ -42,6 +42,18 @@ defmodule Pleroma.Constants do
] ]
) )
const(updatable_object_types,
do: [
"Note",
"Question",
"Audio",
"Video",
"Event",
"Article",
"Page"
]
)
const(actor_types, const(actor_types,
do: [ do: [
"Application", "Application",

View File

@ -411,7 +411,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
{:ok, object, meta} {:ok, object, meta}
end end
@updatable_object_types ["Note", "Question"]
defp handle_update_object( defp handle_update_object(
%{data: %{"type" => "Update", "object" => updated_object}} = object, %{data: %{"type" => "Update", "object" => updated_object}} = object,
meta meta
@ -429,7 +428,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
meta[:object_data] meta[:object_data]
end end
if orig_object_data["type"] in @updatable_object_types do if orig_object_data["type"] in Pleroma.Constants.updatable_object_types() do
%{ %{
updated_data: updated_object_data, updated_data: updated_object_data,
updated: updated, updated: updated,

View File

@ -687,6 +687,24 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> strip_internal_fields |> strip_internal_fields
|> strip_internal_tags |> strip_internal_tags
|> set_type |> set_type
|> maybe_process_history
end
defp maybe_process_history(%{"formerRepresentations" => %{"orderedItems" => history}} = object) do
processed_history =
Enum.map(
history,
fn
item when is_map(item) -> prepare_object(item)
item -> item
end
)
put_in(object, ["formerRepresentations", "orderedItems"], processed_history)
end
defp maybe_process_history(object) do
object
end end
# @doc # @doc
@ -711,6 +729,21 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
{:ok, data} {:ok, data}
end end
def prepare_outgoing(%{"type" => "Update", "object" => %{"type" => objtype} = object} = data)
when objtype in Pleroma.Constants.updatable_object_types() do
object =
object
|> prepare_object
data =
data
|> Map.put("object", object)
|> Map.merge(Utils.make_json_ld_header())
|> Map.delete("bcc")
{:ok, data}
end
def prepare_outgoing(%{"type" => "Announce", "actor" => ap_id, "object" => object_id} = data) do def prepare_outgoing(%{"type" => "Announce", "actor" => ap_id, "object" => object_id} = data) do
object = object =
object_id object_id
@ -902,24 +935,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end end
def strip_internal_fields(object) do def strip_internal_fields(object) do
outer = Map.drop(object, Pleroma.Constants.object_internal_fields()) Map.drop(object, Pleroma.Constants.object_internal_fields())
case outer do
%{"formerRepresentations" => %{"orderedItems" => list}} when is_list(list) ->
update_in(
outer["formerRepresentations"]["orderedItems"],
&Enum.map(
&1,
fn
item when is_map(item) -> Map.drop(item, Pleroma.Constants.object_internal_fields())
item -> item
end
)
)
_ ->
outer
end
end end
defp strip_internal_tags(%{"tag" => tags} = object) do defp strip_internal_tags(%{"tag" => tags} = object) do

View File

@ -312,6 +312,28 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert url == "http://localhost:4001/emoji/dino%20walking.gif" assert url == "http://localhost:4001/emoji/dino%20walking.gif"
end end
test "Updates of Notes are handled" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "everybody do the dinosaur :dinosaur:"})
{:ok, update} = CommonAPI.update(user, activity, %{status: "mew mew :blank:"})
{:ok, prepared} = Transmogrifier.prepare_outgoing(update.data)
assert %{
"content" => "mew mew :blank:",
"tag" => [%{"name" => ":blank:", "type" => "Emoji"}],
"formerRepresentations" => %{
"orderedItems" => [
%{
"content" => "everybody do the dinosaur :dinosaur:",
"tag" => [%{"name" => ":dinosaur:", "type" => "Emoji"}]
}
]
}
} = prepared["object"]
end
end end
describe "user upgrade" do describe "user upgrade" do
@ -576,57 +598,42 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
end end
end end
describe "strip_internal_fields/1" do describe "prepare_object/1" do
test "it strips internal fields in formerRepresentations" do test "it processes history" do
original = %{ original = %{
"formerRepresentations" => %{ "formerRepresentations" => %{
"orderedItems" => [ "orderedItems" => [
%{"generator" => %{}} %{
"generator" => %{},
"emoji" => %{"blobcat" => "http://localhost:4001/emoji/blobcat.png"}
}
] ]
} }
} }
stripped = Transmogrifier.strip_internal_fields(original) processed = Transmogrifier.prepare_object(original)
refute Map.has_key?( history_item = Enum.at(processed["formerRepresentations"]["orderedItems"], 0)
Enum.at(stripped["formerRepresentations"]["orderedItems"], 0),
"generator" refute Map.has_key?(history_item, "generator")
)
assert [%{"name" => ":blobcat:"}] = history_item["tag"]
end end
test "it strips internal fields in maybe badly-formed formerRepresentations" do test "it works when there is no or bad history" do
original = %{
"formerRepresentations" => %{
"orderedItems" => [
%{"generator" => %{}},
"https://example.com/1"
]
}
}
stripped = Transmogrifier.strip_internal_fields(original)
refute Map.has_key?(
Enum.at(stripped["formerRepresentations"]["orderedItems"], 0),
"generator"
)
assert Enum.at(stripped["formerRepresentations"]["orderedItems"], 1) ==
"https://example.com/1"
end
test "it ignores if formerRepresentations does not look like an OrderedCollection" do
original = %{ original = %{
"formerRepresentations" => %{ "formerRepresentations" => %{
"items" => [ "items" => [
%{"generator" => %{}} %{
"generator" => %{},
"emoji" => %{"blobcat" => "http://localhost:4001/emoji/blobcat.png"}
}
] ]
} }
} }
stripped = Transmogrifier.strip_internal_fields(original) processed = Transmogrifier.prepare_object(original)
assert processed["formerRepresentations"] == original["formerRepresentations"]
assert Map.has_key?(Enum.at(stripped["formerRepresentations"]["items"], 0), "generator")
end end
end end
end end

View File

@ -1584,5 +1584,26 @@ defmodule Pleroma.Web.CommonAPITest do
assert updated_object.data["content"] == "updated 2 :#{emoji2}:" assert updated_object.data["content"] == "updated 2 :#{emoji2}:"
assert %{^emoji2 => _} = updated_object.data["emoji"] assert %{^emoji2 => _} = updated_object.data["emoji"]
end end
test "updates a post with emoji and federate properly" do
[{emoji1, _}, {emoji2, _} | _] = Pleroma.Emoji.get_all()
user = insert(:user)
{:ok, activity} =
CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1 :#{emoji1}:"})
clear_config([:instance, :federating], true)
with_mock Pleroma.Web.Federator,
publish: fn p -> nil end do
{:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2 :#{emoji2}:"})
assert updated.data["object"]["content"] == "updated 2 :#{emoji2}:"
assert %{^emoji2 => _} = updated.data["object"]["emoji"]
assert called(Pleroma.Web.Federator.publish(updated))
end
end
end end
end end