fix(activitypub): harden object normalization
This commit is contained in:
parent
acc44a5b6f
commit
ce5c1b4c15
11 changed files with 315 additions and 65 deletions
|
|
@ -27,6 +27,11 @@ defmodule Pleroma.Object.ContainmentTest do
|
|||
})
|
||||
end
|
||||
|
||||
test "rejects an empty actor list without crashing" do
|
||||
assert :error ==
|
||||
Containment.contain_origin("https://example.com/objects/1", %{"actor" => []})
|
||||
end
|
||||
|
||||
test "contain_origin_from_id() catches obvious spoofing attempts" do
|
||||
data = %{
|
||||
"id" => "http://example.com/~alyssa/activities/1234.json"
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FedidevFunAttachmentsTest do
|
|||
end
|
||||
end
|
||||
|
||||
defp ingest_fixture!(rel_path) do
|
||||
data = rel_path |> File.read!() |> Jason.decode!()
|
||||
defp ingest_data!(data) do
|
||||
ensure_remote_actor!(data["actor"])
|
||||
|
||||
assert {:ok, activity} = Transmogrifier.handle_incoming(data)
|
||||
|
|
@ -46,6 +45,13 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FedidevFunAttachmentsTest do
|
|||
{activity, object}
|
||||
end
|
||||
|
||||
defp ingest_fixture!(rel_path) do
|
||||
rel_path
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|> ingest_data!()
|
||||
end
|
||||
|
||||
test "drops non-http(s) attachment href" do
|
||||
{_activity, object} = ingest_fixture!("test/fixtures/fedidev.fun/attachment_payto_link.json")
|
||||
assert object.data["attachment"] == []
|
||||
|
|
@ -66,4 +72,27 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FedidevFunAttachmentsTest do
|
|||
|
||||
assert href == "https://fedidev.fun/images/007.png"
|
||||
end
|
||||
|
||||
test "drops malformed attachment list entries" do
|
||||
data = File.read!("test/fixtures/fedidev.fun/attachment_url_list.json") |> Jason.decode!()
|
||||
data = update_in(data, ["object", "attachment"], &["malformed" | List.wrap(&1)])
|
||||
|
||||
{_activity, object} = ingest_data!(data)
|
||||
|
||||
assert length(object.data["attachment"]) == 1
|
||||
end
|
||||
|
||||
test "accepts a URI string in an attachment url list" do
|
||||
data = File.read!("test/fixtures/fedidev.fun/attachment_url_list.json") |> Jason.decode!()
|
||||
|
||||
data =
|
||||
put_in(data, ["object", "attachment", "url"], [
|
||||
"https://fedidev.fun/images/007.png"
|
||||
])
|
||||
|
||||
{_activity, object} = ingest_data!(data)
|
||||
|
||||
assert [%{"url" => [%{"href" => "https://fedidev.fun/images/007.png"}]}] =
|
||||
object.data["attachment"]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FedidevFunEmojiTest do
|
|||
end
|
||||
end
|
||||
|
||||
defp ingest_fixture!(rel_path) do
|
||||
data = rel_path |> File.read!() |> Jason.decode!()
|
||||
defp ingest_data!(data) do
|
||||
ensure_remote_actor!(data["actor"])
|
||||
|
||||
assert {:ok, activity} = Transmogrifier.handle_incoming(data)
|
||||
|
|
@ -46,6 +45,13 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FedidevFunEmojiTest do
|
|||
{activity, object}
|
||||
end
|
||||
|
||||
defp ingest_fixture!(rel_path) do
|
||||
rel_path
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|> ingest_data!()
|
||||
end
|
||||
|
||||
test "ingests Emoji tag with string icon" do
|
||||
{_activity, object} = ingest_fixture!("test/fixtures/fedidev.fun/emoji_icon_string.json")
|
||||
assert object.data["emoji"]["cow"] == "https://fedidev.fun/static/cow.png"
|
||||
|
|
@ -62,4 +68,36 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FedidevFunEmojiTest do
|
|||
{_activity, object} = ingest_fixture!("test/fixtures/fedidev.fun/emoji_missing_icon.json")
|
||||
assert object.data["emoji"] == %{}
|
||||
end
|
||||
|
||||
test "ignores Emoji tag missing a string name" do
|
||||
data = File.read!("test/fixtures/fedidev.fun/emoji_icon_string.json") |> Jason.decode!()
|
||||
data = put_in(data, ["object", "tag", Access.at(0), "name"], nil)
|
||||
|
||||
{_activity, object} = ingest_data!(data)
|
||||
|
||||
assert object.data["emoji"] == %{}
|
||||
end
|
||||
|
||||
test "ignores Emoji tag with a non-http icon" do
|
||||
data = File.read!("test/fixtures/fedidev.fun/emoji_icon_string.json") |> Jason.decode!()
|
||||
data = put_in(data, ["object", "tag", Access.at(0), "icon"], "file:///tmp/cow.png")
|
||||
|
||||
{_activity, object} = ingest_data!(data)
|
||||
|
||||
assert object.data["emoji"] == %{}
|
||||
end
|
||||
|
||||
test "normalizes a list-typed Emoji tag before building the emoji map" do
|
||||
data = File.read!("test/fixtures/fedidev.fun/emoji_icon_string.json") |> Jason.decode!()
|
||||
|
||||
data =
|
||||
put_in(data, ["object", "tag", Access.at(0), "type"], [
|
||||
"https://example.com/ns#CustomTag",
|
||||
"Emoji"
|
||||
])
|
||||
|
||||
{_activity, object} = ingest_data!(data)
|
||||
|
||||
assert object.data["emoji"]["cow"] == "https://fedidev.fun/static/cow.png"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -50,4 +50,15 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FedidevFunObjectTypeListTest do
|
|||
{_activity, object} = ingest_fixture!("test/fixtures/fedidev.fun/object_type_list.json")
|
||||
assert object.data["type"] == "Note"
|
||||
end
|
||||
|
||||
test "selects a supported type after an extension type" do
|
||||
data = File.read!("test/fixtures/fedidev.fun/object_type_list.json") |> Jason.decode!()
|
||||
data = put_in(data, ["object", "type"], ["https://example.com/ns#CustomType", "Note"])
|
||||
ensure_remote_actor!(data["actor"])
|
||||
|
||||
assert {:ok, activity} = Transmogrifier.handle_incoming(data)
|
||||
object = Object.normalize(activity.data["object"], fetch: false)
|
||||
|
||||
assert object.data["type"] == "Note"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -62,4 +62,51 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FedidevFunTagInferenceTest do
|
|||
_ -> false
|
||||
end)
|
||||
end
|
||||
|
||||
test "normalizes a list-typed tag type" do
|
||||
data =
|
||||
File.read!("test/fixtures/fedidev.fun/tag_hashtag_missing_type.json") |> Jason.decode!()
|
||||
|
||||
data = put_in(data, ["object", "tag", Access.at(0), "type"], ["Hashtag"])
|
||||
ensure_remote_actor!(data["actor"])
|
||||
|
||||
assert {:ok, activity} = Transmogrifier.handle_incoming(data)
|
||||
object = Object.normalize(activity.data["object"], fetch: false)
|
||||
|
||||
assert "test" in Object.hashtags(object)
|
||||
end
|
||||
|
||||
test "ignores a list-typed Hashtag without a string name" do
|
||||
data =
|
||||
File.read!("test/fixtures/fedidev.fun/tag_hashtag_missing_type.json") |> Jason.decode!()
|
||||
|
||||
data = put_in(data, ["object", "tag", Access.at(0), "type"], ["Hashtag"])
|
||||
data = put_in(data, ["object", "tag", Access.at(0), "name"], nil)
|
||||
ensure_remote_actor!(data["actor"])
|
||||
|
||||
assert {:ok, activity} = Transmogrifier.handle_incoming(data)
|
||||
object = Object.normalize(activity.data["object"], fetch: false)
|
||||
|
||||
assert Object.hashtags(object) == []
|
||||
end
|
||||
|
||||
test "infers a Link before deriving quoteUrl" do
|
||||
data =
|
||||
File.read!("test/fixtures/fedidev.fun/tag_hashtag_missing_type.json") |> Jason.decode!()
|
||||
|
||||
data =
|
||||
put_in(data, ["object", "tag"], [
|
||||
%{
|
||||
"href" => "https://fedidev.fun/assets/note1.jsonap",
|
||||
"mediaType" => "application/activity+json"
|
||||
}
|
||||
])
|
||||
|
||||
ensure_remote_actor!(data["actor"])
|
||||
|
||||
assert {:ok, activity} = Transmogrifier.handle_incoming(data)
|
||||
object = Object.normalize(activity.data["object"], fetch: false)
|
||||
|
||||
assert object.data["quoteUrl"] == "https://fedidev.fun/assets/note1.jsonap"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -671,13 +671,21 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
|
|||
test "returns object with emoji when object contains list tags" do
|
||||
assert Transmogrifier.fix_emoji(%{
|
||||
"tag" => [
|
||||
%{"type" => "Emoji", "name" => ":bib:", "icon" => %{"url" => "/test"}},
|
||||
%{
|
||||
"type" => "Emoji",
|
||||
"name" => ":bib:",
|
||||
"icon" => %{"url" => "https://example.com/test"}
|
||||
},
|
||||
%{"type" => "Hashtag"}
|
||||
]
|
||||
}) == %{
|
||||
"emoji" => %{"bib" => "/test"},
|
||||
"emoji" => %{"bib" => "https://example.com/test"},
|
||||
"tag" => [
|
||||
%{"icon" => %{"url" => "/test"}, "name" => ":bib:", "type" => "Emoji"},
|
||||
%{
|
||||
"icon" => %{"url" => "https://example.com/test"},
|
||||
"name" => ":bib:",
|
||||
"type" => "Emoji"
|
||||
},
|
||||
%{"type" => "Hashtag"}
|
||||
]
|
||||
}
|
||||
|
|
@ -685,10 +693,28 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
|
|||
|
||||
test "returns object with emoji when object contains map tag" do
|
||||
assert Transmogrifier.fix_emoji(%{
|
||||
"tag" => %{"type" => "Emoji", "name" => ":bib:", "icon" => %{"url" => "/test"}}
|
||||
"tag" => %{
|
||||
"type" => "Emoji",
|
||||
"name" => ":bib:",
|
||||
"icon" => %{"url" => "https://example.com/test"}
|
||||
}
|
||||
}) == %{
|
||||
"emoji" => %{"bib" => "/test"},
|
||||
"tag" => %{"icon" => %{"url" => "/test"}, "name" => ":bib:", "type" => "Emoji"}
|
||||
"emoji" => %{"bib" => "https://example.com/test"},
|
||||
"tag" => %{
|
||||
"icon" => %{"url" => "https://example.com/test"},
|
||||
"name" => ":bib:",
|
||||
"type" => "Emoji"
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "fix_tag/1" do
|
||||
test "ignores malformed Hashtag names and tag entries" do
|
||||
tag = %{"type" => "Hashtag", "name" => 123}
|
||||
|
||||
assert Transmogrifier.fix_tag(%{"tag" => [tag, "malformed"]}) == %{
|
||||
"tag" => [tag, "malformed"]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -50,6 +50,25 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.UserUpdateHandlingTest do
|
|||
assert user.bio == "<p>Some bio</p>"
|
||||
end
|
||||
|
||||
test "it selects an actor type after an extension type" do
|
||||
user = insert(:user, local: false)
|
||||
update_data = File.read!("test/fixtures/mastodon-update.json") |> Jason.decode!()
|
||||
|
||||
object =
|
||||
update_data["object"]
|
||||
|> Map.put("actor", user.ap_id)
|
||||
|> Map.put("id", user.ap_id)
|
||||
|> Map.put("type", ["https://example.com/ns#CustomActor", "Person"])
|
||||
|
||||
update_data =
|
||||
update_data
|
||||
|> Map.put("actor", user.ap_id)
|
||||
|> Map.put("object", object)
|
||||
|
||||
assert {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(update_data)
|
||||
assert User.get_cached_by_ap_id(user.ap_id).name == "gargle"
|
||||
end
|
||||
|
||||
test "it works with alsoKnownAs" do
|
||||
%{ap_id: actor} = insert(:user, local: false)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue