Merge branch 'bugfix/incoming-poll-emoji' into 'develop'
Fix emoji in Question, force generated context/context_id insertion Closes #1870 See merge request pleroma/pleroma!2915
This commit is contained in:
commit
9433311923
|
@ -0,0 +1,34 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.Emoji do
|
||||||
|
use Ecto.Type
|
||||||
|
|
||||||
|
def type, do: :map
|
||||||
|
|
||||||
|
def cast(data) when is_map(data) do
|
||||||
|
has_invalid_emoji? =
|
||||||
|
Enum.find(data, fn
|
||||||
|
{name, uri} when is_binary(name) and is_binary(uri) ->
|
||||||
|
# based on ObjectValidators.Uri.cast()
|
||||||
|
case URI.parse(uri) do
|
||||||
|
%URI{host: nil} -> true
|
||||||
|
%URI{host: ""} -> true
|
||||||
|
%URI{scheme: scheme} when scheme in ["https", "http"] -> false
|
||||||
|
_ -> true
|
||||||
|
end
|
||||||
|
|
||||||
|
{_name, _uri} ->
|
||||||
|
true
|
||||||
|
end)
|
||||||
|
|
||||||
|
if has_invalid_emoji?, do: :error, else: {:ok, data}
|
||||||
|
end
|
||||||
|
|
||||||
|
def cast(_data), do: :error
|
||||||
|
|
||||||
|
def dump(data), do: {:ok, data}
|
||||||
|
|
||||||
|
def load(data), do: {:ok, data}
|
||||||
|
end
|
|
@ -36,8 +36,7 @@ defp maybe_reinject_internal_fields(_, new_data), do: new_data
|
||||||
defp reinject_object(%Object{data: %{"type" => "Question"}} = object, new_data) do
|
defp reinject_object(%Object{data: %{"type" => "Question"}} = object, new_data) do
|
||||||
Logger.debug("Reinjecting object #{new_data["id"]}")
|
Logger.debug("Reinjecting object #{new_data["id"]}")
|
||||||
|
|
||||||
with new_data <- Transmogrifier.fix_object(new_data),
|
with data <- maybe_reinject_internal_fields(object, new_data),
|
||||||
data <- maybe_reinject_internal_fields(object, new_data),
|
|
||||||
{:ok, data, _} <- ObjectValidator.validate(data, %{}),
|
{:ok, data, _} <- ObjectValidator.validate(data, %{}),
|
||||||
changeset <- Object.change(object, %{data: data}),
|
changeset <- Object.change(object, %{data: data}),
|
||||||
changeset <- touch_changeset(changeset),
|
changeset <- touch_changeset(changeset),
|
||||||
|
|
|
@ -9,6 +9,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||||
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
@ -33,8 +34,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do
|
||||||
field(:attributedTo, ObjectValidators.ObjectID)
|
field(:attributedTo, ObjectValidators.ObjectID)
|
||||||
field(:summary, :string)
|
field(:summary, :string)
|
||||||
field(:published, ObjectValidators.DateTime)
|
field(:published, ObjectValidators.DateTime)
|
||||||
# TODO: Write type
|
field(:emoji, ObjectValidators.Emoji, default: %{})
|
||||||
field(:emoji, :map, default: %{})
|
|
||||||
field(:sensitive, :boolean, default: false)
|
field(:sensitive, :boolean, default: false)
|
||||||
embeds_many(:attachment, AttachmentValidator)
|
embeds_many(:attachment, AttachmentValidator)
|
||||||
field(:replies_count, :integer, default: 0)
|
field(:replies_count, :integer, default: 0)
|
||||||
|
@ -83,6 +83,7 @@ defp fix(data) do
|
||||||
data
|
data
|
||||||
|> CommonFixes.fix_defaults()
|
|> CommonFixes.fix_defaults()
|
||||||
|> CommonFixes.fix_attribution()
|
|> CommonFixes.fix_attribution()
|
||||||
|
|> Transmogrifier.fix_emoji()
|
||||||
|> fix_url()
|
|> fix_url()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator do
|
||||||
field(:content, ObjectValidators.SafeText)
|
field(:content, ObjectValidators.SafeText)
|
||||||
field(:actor, ObjectValidators.ObjectID)
|
field(:actor, ObjectValidators.ObjectID)
|
||||||
field(:published, ObjectValidators.DateTime)
|
field(:published, ObjectValidators.DateTime)
|
||||||
field(:emoji, :map, default: %{})
|
field(:emoji, ObjectValidators.Emoji, default: %{})
|
||||||
|
|
||||||
embeds_one(:attachment, AttachmentValidator)
|
embeds_one(:attachment, AttachmentValidator)
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,8 +11,8 @@ def fix_defaults(data) do
|
||||||
Utils.create_context(data["context"] || data["conversation"])
|
Utils.create_context(data["context"] || data["conversation"])
|
||||||
|
|
||||||
data
|
data
|
||||||
|> Map.put_new("context", context)
|
|> Map.put("context", context)
|
||||||
|> Map.put_new("context_id", context_id)
|
|> Map.put("context_id", context_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fix_attribution(data) do
|
def fix_attribution(data) do
|
||||||
|
|
|
@ -9,6 +9,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EventValidator do
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||||
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
@ -39,8 +40,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EventValidator do
|
||||||
|
|
||||||
field(:attributedTo, ObjectValidators.ObjectID)
|
field(:attributedTo, ObjectValidators.ObjectID)
|
||||||
field(:published, ObjectValidators.DateTime)
|
field(:published, ObjectValidators.DateTime)
|
||||||
# TODO: Write type
|
field(:emoji, ObjectValidators.Emoji, default: %{})
|
||||||
field(:emoji, :map, default: %{})
|
|
||||||
field(:sensitive, :boolean, default: false)
|
field(:sensitive, :boolean, default: false)
|
||||||
embeds_many(:attachment, AttachmentValidator)
|
embeds_many(:attachment, AttachmentValidator)
|
||||||
field(:replies_count, :integer, default: 0)
|
field(:replies_count, :integer, default: 0)
|
||||||
|
@ -74,6 +74,7 @@ defp fix(data) do
|
||||||
data
|
data
|
||||||
|> CommonFixes.fix_defaults()
|
|> CommonFixes.fix_defaults()
|
||||||
|> CommonFixes.fix_attribution()
|
|> CommonFixes.fix_attribution()
|
||||||
|
|> Transmogrifier.fix_emoji()
|
||||||
end
|
end
|
||||||
|
|
||||||
def changeset(struct, data) do
|
def changeset(struct, data) do
|
||||||
|
|
|
@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
|
|
||||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||||
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
@ -32,8 +33,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do
|
||||||
field(:actor, ObjectValidators.ObjectID)
|
field(:actor, ObjectValidators.ObjectID)
|
||||||
field(:attributedTo, ObjectValidators.ObjectID)
|
field(:attributedTo, ObjectValidators.ObjectID)
|
||||||
field(:published, ObjectValidators.DateTime)
|
field(:published, ObjectValidators.DateTime)
|
||||||
# TODO: Write type
|
field(:emoji, ObjectValidators.Emoji, default: %{})
|
||||||
field(:emoji, :map, default: %{})
|
|
||||||
field(:sensitive, :boolean, default: false)
|
field(:sensitive, :boolean, default: false)
|
||||||
# TODO: Write type
|
# TODO: Write type
|
||||||
field(:attachment, {:array, :map}, default: [])
|
field(:attachment, {:array, :map}, default: [])
|
||||||
|
@ -53,7 +53,14 @@ def cast_and_validate(data) do
|
||||||
|> validate_data()
|
|> validate_data()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp fix(data) do
|
||||||
|
data
|
||||||
|
|> Transmogrifier.fix_emoji()
|
||||||
|
end
|
||||||
|
|
||||||
def cast_data(data) do
|
def cast_data(data) do
|
||||||
|
data = fix(data)
|
||||||
|
|
||||||
%__MODULE__{}
|
%__MODULE__{}
|
||||||
|> cast(data, __schema__(:fields))
|
|> cast(data, __schema__(:fields))
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator
|
||||||
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
@ -35,8 +36,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
|
||||||
field(:attributedTo, ObjectValidators.ObjectID)
|
field(:attributedTo, ObjectValidators.ObjectID)
|
||||||
field(:summary, :string)
|
field(:summary, :string)
|
||||||
field(:published, ObjectValidators.DateTime)
|
field(:published, ObjectValidators.DateTime)
|
||||||
# TODO: Write type
|
field(:emoji, ObjectValidators.Emoji, default: %{})
|
||||||
field(:emoji, :map, default: %{})
|
|
||||||
field(:sensitive, :boolean, default: false)
|
field(:sensitive, :boolean, default: false)
|
||||||
embeds_many(:attachment, AttachmentValidator)
|
embeds_many(:attachment, AttachmentValidator)
|
||||||
field(:replies_count, :integer, default: 0)
|
field(:replies_count, :integer, default: 0)
|
||||||
|
@ -85,6 +85,7 @@ defp fix(data) do
|
||||||
data
|
data
|
||||||
|> CommonFixes.fix_defaults()
|
|> CommonFixes.fix_defaults()
|
||||||
|> CommonFixes.fix_attribution()
|
|> CommonFixes.fix_attribution()
|
||||||
|
|> Transmogrifier.fix_emoji()
|
||||||
|> fix_closed()
|
|> fix_closed()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -318,9 +318,6 @@ def fix_emoji(%{"tag" => tags} = object) when is_list(tags) do
|
||||||
Map.put(mapping, name, data["icon"]["url"])
|
Map.put(mapping, name, data["icon"]["url"])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
# we merge mastodon and pleroma emoji into a single mapping, to allow for both wire formats
|
|
||||||
emoji = Map.merge(object["emoji"] || %{}, emoji)
|
|
||||||
|
|
||||||
Map.put(object, "emoji", emoji)
|
Map.put(object, "emoji", emoji)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ test "validates for a basic object we build", %{valid_chat_message: valid_chat_m
|
||||||
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
|
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
|
||||||
|
|
||||||
assert Map.put(valid_chat_message, "attachment", nil) == object
|
assert Map.put(valid_chat_message, "attachment", nil) == object
|
||||||
|
assert match?(%{"firefox" => _}, object["emoji"])
|
||||||
end
|
end
|
||||||
|
|
||||||
test "validates for a basic object with an attachment", %{
|
test "validates for a basic object with an attachment", %{
|
||||||
|
|
|
@ -106,6 +106,57 @@ test "Mastodon Question activity with HTML tags in plaintext" do
|
||||||
assert Enum.sort(object.data["oneOf"]) == Enum.sort(options)
|
assert Enum.sort(object.data["oneOf"]) == Enum.sort(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "Mastodon Question activity with custom emojis" do
|
||||||
|
options = [
|
||||||
|
%{
|
||||||
|
"type" => "Note",
|
||||||
|
"name" => ":blobcat:",
|
||||||
|
"replies" => %{"totalItems" => 0, "type" => "Collection"}
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
"type" => "Note",
|
||||||
|
"name" => ":blobfox:",
|
||||||
|
"replies" => %{"totalItems" => 0, "type" => "Collection"}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
tag = [
|
||||||
|
%{
|
||||||
|
"icon" => %{
|
||||||
|
"type" => "Image",
|
||||||
|
"url" => "https://blob.cat/emoji/custom/blobcats/blobcat.png"
|
||||||
|
},
|
||||||
|
"id" => "https://blob.cat/emoji/custom/blobcats/blobcat.png",
|
||||||
|
"name" => ":blobcat:",
|
||||||
|
"type" => "Emoji",
|
||||||
|
"updated" => "1970-01-01T00:00:00Z"
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
"icon" => %{"type" => "Image", "url" => "https://blob.cat/emoji/blobfox/blobfox.png"},
|
||||||
|
"id" => "https://blob.cat/emoji/blobfox/blobfox.png",
|
||||||
|
"name" => ":blobfox:",
|
||||||
|
"type" => "Emoji",
|
||||||
|
"updated" => "1970-01-01T00:00:00Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
data =
|
||||||
|
File.read!("test/fixtures/mastodon-question-activity.json")
|
||||||
|
|> Poison.decode!()
|
||||||
|
|> Kernel.put_in(["object", "oneOf"], options)
|
||||||
|
|> Kernel.put_in(["object", "tag"], tag)
|
||||||
|
|
||||||
|
{:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
|
||||||
|
object = Object.normalize(activity, false)
|
||||||
|
|
||||||
|
assert object.data["oneOf"] == options
|
||||||
|
|
||||||
|
assert object.data["emoji"] == %{
|
||||||
|
"blobcat" => "https://blob.cat/emoji/custom/blobcats/blobcat.png",
|
||||||
|
"blobfox" => "https://blob.cat/emoji/blobfox/blobfox.png"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
test "returns an error if received a second time" do
|
test "returns an error if received a second time" do
|
||||||
data = File.read!("test/fixtures/mastodon-question-activity.json") |> Poison.decode!()
|
data = File.read!("test/fixtures/mastodon-question-activity.json") |> Poison.decode!()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue