diff --git a/lib/pleroma/web/activity_pub/object_validator.ex b/lib/pleroma/web/activity_pub/object_validator.ex index 24f340539..5edae934b 100644 --- a/lib/pleroma/web/activity_pub/object_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validator.ex @@ -43,9 +43,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do end def stringify_keys(object) do - object - |> Enum.map(fn {key, val} -> {to_string(key), val} end) - |> Enum.into(%{}) + Map.new(object, fn {key, val} -> {to_string(key), val} end) end def fetch_actor_and_object(object) do diff --git a/lib/pleroma/web/activity_pub/object_validators/like_validator.ex b/lib/pleroma/web/activity_pub/object_validators/like_validator.ex index ccbc7d071..981996d49 100644 --- a/lib/pleroma/web/activity_pub/object_validators/like_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/like_validator.ex @@ -30,8 +30,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do end def cast_data(data) do - %__MODULE__{} - |> cast(data, [:id, :type, :object, :actor, :context, :to, :cc]) + cast(%__MODULE__{}, data, [:id, :type, :object, :actor, :context, :to, :cc]) end def validate_data(data_cng) do diff --git a/lib/pleroma/web/activity_pub/object_validators/note_validator.ex b/lib/pleroma/web/activity_pub/object_validators/note_validator.ex index 279d2d065..4c433ceb8 100644 --- a/lib/pleroma/web/activity_pub/object_validators/note_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/note_validator.ex @@ -27,11 +27,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do field(:attributedTo, Types.ObjectID) field(:summary, :string) field(:published, Types.DateTime) - # TODO: Write type - field(:emoji, :map, default: %{}) + field(:emoji, Types.Emoji, default: %{}) field(:sensitive, :boolean, default: false) - # TODO: Write type - field(:attachment, {:array, :map}, default: []) + field(:attachment, Types.Attachments, default: []) field(:replies_count, :integer, default: 0) field(:like_count, :integer, default: 0) field(:announcement_count, :integer, default: 0) diff --git a/lib/pleroma/web/activity_pub/object_validators/types/attachments.ex b/lib/pleroma/web/activity_pub/object_validators/types/attachments.ex new file mode 100644 index 000000000..40c930011 --- /dev/null +++ b/lib/pleroma/web/activity_pub/object_validators/types/attachments.ex @@ -0,0 +1,47 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.ObjectValidators.Types.Attachments do + use Ecto.Type + + def type, do: {:array, :map} + + # Note based on Transmogrifier.prepare_attachments/1 + def cast(attachments_list) when is_list(attachments_list) do + if Enum.all?(attachments_list, &is_map/1) do + casted_attachments = + Enum.map( + attachments_list, + fn data -> + {media_type, href} = + with [%{"mediaType" => media_type, "href" => href} | _] <- data["url"] do + {media_type, href} + else + _ -> {nil, data["url"]} + end + + %{"mediaType" => media_type, "type" => "Document"} + |> Map.merge(data) + |> Map.put("url", href) + end + ) + + {:ok, casted_attachments} + else + :error + end + end + + def cast(_) do + :error + end + + def dump(data) do + {:ok, data} + end + + def load(data) do + {:ok, data} + end +end diff --git a/lib/pleroma/web/activity_pub/object_validators/types/emoji.ex b/lib/pleroma/web/activity_pub/object_validators/types/emoji.ex new file mode 100644 index 000000000..f3e114fc3 --- /dev/null +++ b/lib/pleroma/web/activity_pub/object_validators/types/emoji.ex @@ -0,0 +1,27 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.ObjectValidators.Types.Emoji do + use Ecto.Type + + def type, do: :map + + @doc "Casts to %{name => url} format" + def cast(emoji) when is_map(emoji) do + # To do: validate that all values are URIs? + {:ok, emoji} + end + + def cast(_) do + :error + end + + def dump(data) do + {:ok, data} + end + + def load(data) do + {:ok, data} + end +end diff --git a/lib/pleroma/web/activity_pub/object_validators/types/tags.ex b/lib/pleroma/web/activity_pub/object_validators/types/tags.ex index b46743bf3..3d4158b2f 100644 --- a/lib/pleroma/web/activity_pub/object_validators/types/tags.ex +++ b/lib/pleroma/web/activity_pub/object_validators/types/tags.ex @@ -3,14 +3,15 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.ActivityPub.ObjectValidators.Types.Tags do + alias Pleroma.Web.ActivityPub.Transmogrifier + use Ecto.Type def type, do: {:array, :map} - # Note: supporting binaries and maps as list elements - def cast(list) when is_list(list) do - if Enum.all?(list, &(is_map(&1) || is_binary(&1))) do - {:ok, list} + def cast(tags_list) when is_list(tags_list) do + if Enum.all?(tags_list, &(is_map(&1) || is_binary(&1))) do + {:ok, Transmogrifier.as2_tags(tags_list)} else :error end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index ba12d9853..ac070e895 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -31,17 +31,17 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do """ def fix_object(object, options \\ []) do object - |> strip_internal_fields - |> fix_actor - |> fix_url - |> fix_attachments - |> fix_context + |> strip_internal_fields() + |> fix_actor() + |> fix_url() + |> fix_attachments() + |> fix_context() |> fix_in_reply_to(options) - |> fix_emoji - |> fix_tag - |> fix_content_map - |> fix_addressing - |> fix_summary + |> fix_emoji() + |> fix_tag() + |> fix_content_map() + |> fix_addressing() + |> fix_summary() |> fix_type(options) end @@ -931,17 +931,17 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do # Prepares the object of an outgoing create activity. def prepare_object(object) do object - |> set_sensitive - |> add_hashtags - |> add_mention_tags - |> add_emoji_tags - |> add_attributed_to - |> prepare_attachments - |> set_conversation - |> set_reply_to_uri - |> strip_internal_fields - |> strip_internal_tags - |> set_type + |> set_sensitive() + |> add_hashtags() + |> add_mention_tags() + |> add_emoji_tags() + |> add_attributed_to() + |> prepare_attachments() + |> set_conversation() + |> set_reply_to_uri() + |> strip_internal_fields() + |> strip_internal_tags() + |> set_type() end # @doc @@ -955,7 +955,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do object_id |> Object.normalize() |> Map.get(:data) - |> prepare_object + |> prepare_object() data = data @@ -975,12 +975,12 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do if Visibility.is_private?(object) && object.data["actor"] == ap_id do data |> Map.put("object", object |> Map.get(:data) |> prepare_object) else - data |> maybe_fix_object_url + maybe_fix_object_url(data) end data = data - |> strip_internal_fields + |> strip_internal_fields() |> Map.merge(Utils.make_json_ld_header()) |> Map.delete("bcc") @@ -1028,8 +1028,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do def prepare_outgoing(%{"type" => _type} = data) do data = data - |> strip_internal_fields - |> maybe_fix_object_url + |> strip_internal_fields() + |> maybe_fix_object_url() |> Map.merge(Utils.make_json_ld_header()) {:ok, data} @@ -1054,9 +1054,15 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do def maybe_fix_object_url(data), do: data def add_hashtags(object) do - tags = - (object["tag"] || []) - |> Enum.map(fn + tags = as2_tags(object["tag"] || []) + Map.put(object, "tag", tags) + end + + @doc "Converts `tag` list to ActivityStreams 2.0 format" + def as2_tags(tags) when is_list(tags) do + Enum.map( + tags, + fn # Expand internal representation tags into AS2 tags. tag when is_binary(tag) -> %{ @@ -1068,9 +1074,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do # Do not process tags which are already AS2 tag objects. tag when is_map(tag) -> tag - end) - - Map.put(object, "tag", tags) + end + ) end def add_mention_tags(object) do