Add new Emoji Ecto.Type and fix emoji in Question
authorHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Mon, 24 Aug 2020 23:16:12 +0000 (01:16 +0200)
committerHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Tue, 1 Sep 2020 06:34:57 +0000 (08:34 +0200)
lib/pleroma/ecto_type/activity_pub/object_validators/emoji.ex [new file with mode: 0644]
lib/pleroma/web/activity_pub/object_validators/audio_validator.ex
lib/pleroma/web/activity_pub/object_validators/chat_message_validator.ex
lib/pleroma/web/activity_pub/object_validators/event_validator.ex
lib/pleroma/web/activity_pub/object_validators/note_validator.ex
lib/pleroma/web/activity_pub/object_validators/question_validator.ex
test/web/activity_pub/object_validators/chat_validation_test.exs
test/web/activity_pub/transmogrifier/question_handling_test.exs

diff --git a/lib/pleroma/ecto_type/activity_pub/object_validators/emoji.ex b/lib/pleroma/ecto_type/activity_pub/object_validators/emoji.ex
new file mode 100644 (file)
index 0000000..4aacc5c
--- /dev/null
@@ -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
index d1869f18809ad7e8a068246546a9da004b7f841b..1a97c504a90848c93d8aa6789b32cfc2daddab2f 100644 (file)
@@ -9,6 +9,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do
   alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
   alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
   alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
+  alias Pleroma.Web.ActivityPub.Transmogrifier
 
   import Ecto.Changeset
 
@@ -33,8 +34,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do
     field(:attributedTo, ObjectValidators.ObjectID)
     field(:summary, :string)
     field(:published, ObjectValidators.DateTime)
-    # TODO: Write type
-    field(:emoji, :map, default: %{})
+    field(:emoji, ObjectValidators.Emoji, default: %{})
     field(:sensitive, :boolean, default: false)
     embeds_many(:attachment, AttachmentValidator)
     field(:replies_count, :integer, default: 0)
@@ -83,6 +83,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do
     data
     |> CommonFixes.fix_defaults()
     |> CommonFixes.fix_attribution()
+    |> Transmogrifier.fix_emoji()
     |> fix_url()
   end
 
index 91b475393335c9567b08c57132d50b36f649b4f9..6acd4a771df230e4644321e651d2b32132eeb431 100644 (file)
@@ -22,7 +22,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator do
     field(:content, ObjectValidators.SafeText)
     field(:actor, ObjectValidators.ObjectID)
     field(:published, ObjectValidators.DateTime)
-    field(:emoji, :map, default: %{})
+    field(:emoji, ObjectValidators.Emoji, default: %{})
 
     embeds_one(:attachment, AttachmentValidator)
   end
index 07e4821a4f5f37023e0b62c5998215b0fadc2d7a..0b4c99dc0286bd87a2ed21fda66b4633e28faf9d 100644 (file)
@@ -9,6 +9,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EventValidator do
   alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
   alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
   alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
+  alias Pleroma.Web.ActivityPub.Transmogrifier
 
   import Ecto.Changeset
 
@@ -39,8 +40,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EventValidator do
 
     field(:attributedTo, ObjectValidators.ObjectID)
     field(:published, ObjectValidators.DateTime)
-    # TODO: Write type
-    field(:emoji, :map, default: %{})
+    field(:emoji, ObjectValidators.Emoji, default: %{})
     field(:sensitive, :boolean, default: false)
     embeds_many(:attachment, AttachmentValidator)
     field(:replies_count, :integer, default: 0)
@@ -74,6 +74,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EventValidator do
     data
     |> CommonFixes.fix_defaults()
     |> CommonFixes.fix_attribution()
+    |> Transmogrifier.fix_emoji()
   end
 
   def changeset(struct, data) do
index 20e73561946996f4861cd409a1e57bd295a986a4..ab4469a59ac05aee6191ab27044074e893245c19 100644 (file)
@@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do
   use Ecto.Schema
 
   alias Pleroma.EctoType.ActivityPub.ObjectValidators
+  alias Pleroma.Web.ActivityPub.Transmogrifier
 
   import Ecto.Changeset
 
@@ -32,8 +33,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do
     field(:actor, ObjectValidators.ObjectID)
     field(:attributedTo, ObjectValidators.ObjectID)
     field(:published, ObjectValidators.DateTime)
-    # TODO: Write type
-    field(:emoji, :map, default: %{})
+    field(:emoji, ObjectValidators.Emoji, default: %{})
     field(:sensitive, :boolean, default: false)
     # TODO: Write type
     field(:attachment, {:array, :map}, default: [])
@@ -53,7 +53,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do
     |> validate_data()
   end
 
+  defp fix(data) do
+    data
+    |> Transmogrifier.fix_emoji()
+  end
+
   def cast_data(data) do
+    data = fix(data)
+
     %__MODULE__{}
     |> cast(data, __schema__(:fields))
   end
index 712047424665ce5729423729d359575ed1397b83..934d3c1ea048624c49c0831b226a8321ea98e5f7 100644 (file)
@@ -10,6 +10,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
   alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
   alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
   alias Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator
+  alias Pleroma.Web.ActivityPub.Transmogrifier
 
   import Ecto.Changeset
 
@@ -35,8 +36,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
     field(:attributedTo, ObjectValidators.ObjectID)
     field(:summary, :string)
     field(:published, ObjectValidators.DateTime)
-    # TODO: Write type
-    field(:emoji, :map, default: %{})
+    field(:emoji, ObjectValidators.Emoji, default: %{})
     field(:sensitive, :boolean, default: false)
     embeds_many(:attachment, AttachmentValidator)
     field(:replies_count, :integer, default: 0)
@@ -85,6 +85,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
     data
     |> CommonFixes.fix_defaults()
     |> CommonFixes.fix_attribution()
+    |> Transmogrifier.fix_emoji()
     |> fix_closed()
   end
 
index 50bf03515dff31ab30905a920d1bc606e1b655c3..16e4808e59708e415dba4ec59ffe8807befdae1b 100644 (file)
@@ -69,6 +69,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatValidationTest do
       assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
 
       assert Map.put(valid_chat_message, "attachment", nil) == object
+      assert match?(%{"firefox" => _}, object["emoji"])
     end
 
     test "validates for a basic object with an attachment", %{
index c82361828883ef0b17fb7ede4f46a6194b52ec7d..74ee7954382592231a5471467336e05878f2c345 100644 (file)
@@ -106,6 +106,57 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.QuestionHandlingTest do
     assert Enum.sort(object.data["oneOf"]) == Enum.sort(options)
   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
     data = File.read!("test/fixtures/mastodon-question-activity.json") |> Poison.decode!()