[#1878] Added types for `emoji`, `attachment`, added casting for `tag` Object fields.

This commit is contained in:
Ivan Tashkinov 2020-01-05 18:42:21 +03:00
parent 0af60b94d2
commit 56bbcef4d2
7 changed files with 120 additions and 45 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -0,0 +1,47 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# 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

View File

@ -0,0 +1,27 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# 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

View File

@ -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

View File

@ -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