fix(activitypub): harden object normalization
This commit is contained in:
parent
acc44a5b6f
commit
ce5c1b4c15
11 changed files with 315 additions and 65 deletions
1
changelog.d/fedidev-federation-compat.add
Normal file
1
changelog.d/fedidev-federation-compat.add
Normal file
|
|
@ -0,0 +1 @@
|
|||
Accept more real-world ActivityPub object shapes collected by fedidev.fun
|
||||
|
|
@ -79,9 +79,11 @@ defmodule Pleroma.Object.Containment do
|
|||
|
||||
def contain_origin(id, %{"actor" => _actor} = params) do
|
||||
id_uri = URI.parse(id)
|
||||
actor_uri = URI.parse(get_actor(params))
|
||||
|
||||
compare_uris(actor_uri, id_uri)
|
||||
case get_actor(params) do
|
||||
actor when is_binary(actor) -> compare_uris(URI.parse(actor), id_uri)
|
||||
_ -> :error
|
||||
end
|
||||
end
|
||||
|
||||
def contain_origin(id, %{"attributedTo" => actor} = params),
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
|
|||
require Pleroma.Constants
|
||||
|
||||
@primary_key false
|
||||
@tag_types ~w[Mention Hashtag Emoji Link]
|
||||
|
||||
embedded_schema do
|
||||
# Common
|
||||
field(:type, :string)
|
||||
|
|
@ -49,7 +51,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
|
|||
|> validate_required([:type, :href])
|
||||
end
|
||||
|
||||
def changeset(struct, %{"type" => "Hashtag", "name" => name} = data) do
|
||||
def changeset(struct, %{"type" => "Hashtag", "name" => name} = data) when is_binary(name) do
|
||||
name = String.downcase(name)
|
||||
data = Map.put(data, "name", name)
|
||||
|
||||
|
|
@ -58,7 +60,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
|
|||
|> validate_required([:type, :name])
|
||||
end
|
||||
|
||||
def changeset(struct, %{"type" => "Emoji"} = data) do
|
||||
def changeset(struct, %{"type" => "Hashtag"} = data) do
|
||||
struct
|
||||
|> cast(data, [])
|
||||
|> Map.put(:action, :ignore)
|
||||
end
|
||||
|
||||
def changeset(struct, %{"type" => "Emoji", "name" => name} = data) when is_binary(name) do
|
||||
data =
|
||||
data
|
||||
|> Map.put("name", String.trim(data["name"], ":"))
|
||||
|
|
@ -84,6 +92,12 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
|
|||
end
|
||||
end
|
||||
|
||||
def changeset(struct, %{"type" => "Emoji"} = data) do
|
||||
struct
|
||||
|> cast(data, [])
|
||||
|> Map.put(:action, :ignore)
|
||||
end
|
||||
|
||||
def changeset(struct, %{"type" => "Link"} = data) do
|
||||
struct
|
||||
|> cast(data, [:type, :name, :mediaType, :href])
|
||||
|
|
@ -91,6 +105,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
|
|||
|> validate_required([:type, :href, :mediaType])
|
||||
end
|
||||
|
||||
def changeset(struct, %{"type" => types} = data) when is_list(types) do
|
||||
changeset(struct, infer_type(data))
|
||||
end
|
||||
|
||||
def changeset(struct, %{"type" => _} = data) do
|
||||
struct
|
||||
|> cast(data, [])
|
||||
|
|
@ -98,7 +116,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
|
|||
end
|
||||
|
||||
def changeset(struct, data) when is_map(data) do
|
||||
data = infer_type(data)
|
||||
data = normalize(data)
|
||||
|
||||
if Map.has_key?(data, "type") do
|
||||
changeset(struct, data)
|
||||
|
|
@ -109,6 +127,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
|
|||
end
|
||||
end
|
||||
|
||||
def normalize(data) when is_map(data), do: infer_type(data)
|
||||
|
||||
defp infer_type(%{"type" => types} = data) when is_list(types) do
|
||||
type = Enum.find(types, &(&1 in @tag_types)) || Enum.find(types, &is_binary/1)
|
||||
|
||||
if type, do: Map.put(data, "type", type), else: Map.delete(data, "type")
|
||||
end
|
||||
|
||||
defp infer_type(%{"type" => _} = data), do: data
|
||||
defp infer_type(%{"name" => "#" <> _} = data), do: Map.put(data, "type", "Hashtag")
|
||||
defp infer_type(%{"name" => "@" <> _} = data), do: Map.put(data, "type", "Mention")
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.TagValidator
|
||||
alias Pleroma.Web.ActivityPub.Pipeline
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
alias Pleroma.Web.ActivityPub.Visibility
|
||||
|
|
@ -28,6 +29,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
|
||||
require Pleroma.Constants
|
||||
|
||||
@supported_types Pleroma.Constants.activity_types() ++
|
||||
Pleroma.Constants.object_types() ++ Pleroma.Constants.actor_types()
|
||||
|
||||
@doc """
|
||||
Modifies an incoming AP object (mastodon format) to our internal format.
|
||||
"""
|
||||
|
|
@ -301,58 +305,66 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
|
||||
def fix_attachments(%{"attachment" => attachment} = object) when is_list(attachment) do
|
||||
attachments =
|
||||
Enum.map(attachment, fn data ->
|
||||
url =
|
||||
cond do
|
||||
is_list(data["url"]) -> List.first(data["url"])
|
||||
is_map(data["url"]) -> data["url"]
|
||||
true -> nil
|
||||
end
|
||||
Enum.map(attachment, fn
|
||||
data when is_map(data) ->
|
||||
url =
|
||||
cond do
|
||||
is_list(data["url"]) -> List.first(data["url"])
|
||||
is_map(data["url"]) -> data["url"]
|
||||
true -> nil
|
||||
end
|
||||
|
||||
media_type =
|
||||
cond do
|
||||
is_map(url) && is_bitstring(url["mediaType"]) &&
|
||||
url["mediaType"] =~ Pleroma.Constants.mime_regex() ->
|
||||
url["mediaType"]
|
||||
url_data = if is_map(url), do: url, else: %{}
|
||||
|
||||
is_bitstring(data["mediaType"]) && data["mediaType"] =~ Pleroma.Constants.mime_regex() ->
|
||||
data["mediaType"]
|
||||
media_type =
|
||||
cond do
|
||||
is_bitstring(url_data["mediaType"]) &&
|
||||
url_data["mediaType"] =~ Pleroma.Constants.mime_regex() ->
|
||||
url_data["mediaType"]
|
||||
|
||||
is_bitstring(data["mimeType"]) && data["mimeType"] =~ Pleroma.Constants.mime_regex() ->
|
||||
data["mimeType"]
|
||||
is_bitstring(data["mediaType"]) &&
|
||||
data["mediaType"] =~ Pleroma.Constants.mime_regex() ->
|
||||
data["mediaType"]
|
||||
|
||||
true ->
|
||||
nil
|
||||
end
|
||||
is_bitstring(data["mimeType"]) && data["mimeType"] =~ Pleroma.Constants.mime_regex() ->
|
||||
data["mimeType"]
|
||||
|
||||
href =
|
||||
cond do
|
||||
is_map(url) && is_binary(url["href"]) -> url["href"]
|
||||
is_binary(data["url"]) -> data["url"]
|
||||
is_binary(data["href"]) -> data["href"]
|
||||
true -> nil
|
||||
end
|
||||
true ->
|
||||
nil
|
||||
end
|
||||
|
||||
href =
|
||||
cond do
|
||||
is_binary(url) -> url
|
||||
is_binary(url_data["href"]) -> url_data["href"]
|
||||
is_binary(data["url"]) -> data["url"]
|
||||
is_binary(data["href"]) -> data["href"]
|
||||
true -> nil
|
||||
end
|
||||
|
||||
if href && valid_http_url?(href) do
|
||||
attachment_url =
|
||||
%{
|
||||
"href" => href,
|
||||
"type" => Map.get(url_data, "type", "Link")
|
||||
}
|
||||
|> Maps.put_if_present("mediaType", media_type)
|
||||
|> Maps.put_if_present("width", url_data["width"] || data["width"])
|
||||
|> Maps.put_if_present("height", url_data["height"] || data["height"])
|
||||
|
||||
if href && valid_http_url?(href) do
|
||||
attachment_url =
|
||||
%{
|
||||
"href" => href,
|
||||
"type" => Map.get(url || %{}, "type", "Link")
|
||||
"url" => [attachment_url],
|
||||
"type" => data["type"] || "Document"
|
||||
}
|
||||
|> Maps.put_if_present("mediaType", media_type)
|
||||
|> Maps.put_if_present("width", (url || %{})["width"] || data["width"])
|
||||
|> Maps.put_if_present("height", (url || %{})["height"] || data["height"])
|
||||
|> Maps.put_if_present("name", data["name"])
|
||||
|> Maps.put_if_present("blurhash", data["blurhash"])
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
%{
|
||||
"url" => [attachment_url],
|
||||
"type" => data["type"] || "Document"
|
||||
}
|
||||
|> Maps.put_if_present("mediaType", media_type)
|
||||
|> Maps.put_if_present("name", data["name"])
|
||||
|> Maps.put_if_present("blurhash", data["blurhash"])
|
||||
else
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
end)
|
||||
|> Enum.filter(& &1)
|
||||
|
||||
|
|
@ -404,14 +416,23 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
|
||||
defp emoji_icon_url(_), do: nil
|
||||
|
||||
defp valid_emoji_icon_url(icon) do
|
||||
case emoji_icon_url(icon) do
|
||||
url when is_binary(url) -> if valid_http_url?(url), do: url
|
||||
_ -> nil
|
||||
end
|
||||
end
|
||||
|
||||
def fix_emoji(%{"tag" => tags} = object) when is_list(tags) do
|
||||
emoji =
|
||||
tags
|
||||
|> Enum.filter(fn data -> is_map(data) and data["type"] == "Emoji" and data["icon"] end)
|
||||
|> Enum.filter(fn data ->
|
||||
is_map(data) and data["type"] == "Emoji" and is_binary(data["name"]) and data["icon"]
|
||||
end)
|
||||
|> Enum.reduce(%{}, fn data, mapping ->
|
||||
name = String.trim(data["name"], ":")
|
||||
|
||||
case emoji_icon_url(data["icon"]) do
|
||||
case valid_emoji_icon_url(data["icon"]) do
|
||||
url when is_binary(url) -> Map.put(mapping, name, url)
|
||||
_ -> mapping
|
||||
end
|
||||
|
|
@ -420,10 +441,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
Map.put(object, "emoji", emoji)
|
||||
end
|
||||
|
||||
def fix_emoji(%{"tag" => %{"type" => "Emoji"} = tag} = object) do
|
||||
name = String.trim(tag["name"], ":")
|
||||
def fix_emoji(%{"tag" => %{"type" => "Emoji", "name" => name} = tag} = object)
|
||||
when is_binary(name) do
|
||||
name = String.trim(name, ":")
|
||||
|
||||
with url when is_binary(url) <- emoji_icon_url(tag["icon"]) do
|
||||
with url when is_binary(url) <- valid_emoji_icon_url(tag["icon"]) do
|
||||
Map.put(object, "emoji", %{name => url})
|
||||
else
|
||||
_ -> object
|
||||
|
|
@ -435,7 +457,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
def fix_tag(%{"tag" => tag} = object) when is_list(tag) do
|
||||
tags =
|
||||
tag
|
||||
|> Enum.filter(fn data -> data["type"] == "Hashtag" and data["name"] end)
|
||||
|> Enum.filter(fn data ->
|
||||
is_map(data) and data["type"] == "Hashtag" and is_binary(data["name"])
|
||||
end)
|
||||
|> Enum.map(fn
|
||||
%{"name" => "#" <> hashtag} -> String.downcase(hashtag)
|
||||
%{"name" => hashtag} -> String.downcase(hashtag)
|
||||
|
|
@ -502,10 +526,32 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
|> handle_incoming_normalized(options)
|
||||
end
|
||||
|
||||
defp fix_type_as_string(%{"type" => [type | _]} = data) when is_binary(type),
|
||||
do: Map.put(data, "type", type)
|
||||
defp fix_type_as_string(data) do
|
||||
data
|
||||
|> normalize_type()
|
||||
|> normalize_tag_types()
|
||||
end
|
||||
|
||||
defp fix_type_as_string(data), do: data
|
||||
defp normalize_type(%{"type" => types} = data) when is_list(types) do
|
||||
type = Enum.find(types, &(&1 in @supported_types)) || Enum.find(types, &is_binary/1)
|
||||
|
||||
if type, do: Map.put(data, "type", type), else: data
|
||||
end
|
||||
|
||||
defp normalize_type(data), do: data
|
||||
|
||||
defp normalize_tag_types(%{"tag" => tags} = data) when is_list(tags) do
|
||||
Map.put(data, "tag", Enum.map(tags, &normalize_tag_type/1))
|
||||
end
|
||||
|
||||
defp normalize_tag_types(%{"tag" => tag} = data) when is_map(tag) do
|
||||
Map.put(data, "tag", normalize_tag_type(tag))
|
||||
end
|
||||
|
||||
defp normalize_tag_types(data), do: data
|
||||
|
||||
defp normalize_tag_type(tag) when is_map(tag), do: TagValidator.normalize(tag)
|
||||
defp normalize_tag_type(tag), do: tag
|
||||
|
||||
# Flag objects are placed ahead of the ID check because Mastodon 2.8 and earlier send them
|
||||
# with nil ID.
|
||||
|
|
|
|||
|
|
@ -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