diff --git a/lib/pleroma/ecto_type/activity_pub/object_validators/map_of_string.ex b/lib/pleroma/ecto_type/activity_pub/object_validators/map_of_string.ex new file mode 100644 index 0000000000..9c610a64b8 --- /dev/null +++ b/lib/pleroma/ecto_type/activity_pub/object_validators/map_of_string.ex @@ -0,0 +1,29 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.MapOfString do + use Ecto.Type + + def type, do: :map + + def cast(object) when is_map(object) do + data = + object + |> Enum.reduce(%{}, fn + {lang, value}, acc when is_binary(lang) and is_binary(value) -> + Map.put(acc, lang, value) + + _, acc -> + acc + end) + + {:ok, data} + end + + def cast(_), do: :error + + def dump(data), do: {:ok, data} + + def load(data), do: {:ok, data} +end diff --git a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex index 01960da831..c96717e78f 100644 --- a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex @@ -15,6 +15,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do field(:type, :string, default: "Link") field(:mediaType, ObjectValidators.MIME, default: "application/octet-stream") field(:name, :string) + field(:nameMap, ObjectValidators.MapOfString) field(:blurhash, :string) embeds_many :url, UrlObjectValidator, primary_key: false do @@ -44,7 +45,7 @@ def changeset(struct, data) do |> fix_url() struct - |> cast(data, [:id, :type, :mediaType, :name, :blurhash]) + |> cast(data, [:id, :type, :mediaType, :name, :nameMap, :blurhash]) |> cast_embed(:url, with: &url_changeset/2, required: true) end diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex index 22cf0cc05b..b626ccca6f 100644 --- a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex +++ b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex @@ -50,7 +50,9 @@ defmacro status_object_fields do embeds_many(:tag, TagValidator) field(:name, :string) + field(:nameMap, ObjectValidators.MapOfString) field(:summary, :string) + field(:summaryMap, ObjectValidators.MapOfString) field(:context, :string) diff --git a/lib/pleroma/web/activity_pub/object_validators/question_options_validator.ex b/lib/pleroma/web/activity_pub/object_validators/question_options_validator.ex index 8d7f7b9fa6..bbd1b25cc2 100644 --- a/lib/pleroma/web/activity_pub/object_validators/question_options_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/question_options_validator.ex @@ -7,10 +7,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator do import Ecto.Changeset + alias Pleroma.EctoType.ActivityPub.ObjectValidators + @primary_key false embedded_schema do field(:name, :string) + field(:nameMap, ObjectValidators.MapOfString) embeds_one :replies, Replies, primary_key: false do field(:totalItems, :integer) @@ -22,7 +25,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator do def changeset(struct, data) do struct - |> cast(data, [:name, :type]) + |> cast(data, [:name, :nameMap, :type]) |> cast_embed(:replies, with: &replies_changeset/2) |> validate_inclusion(:type, ["Note"]) |> validate_required([:name, :type]) diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/map_of_string_test.exs b/test/pleroma/ecto_type/activity_pub/object_validators/map_of_string_test.exs new file mode 100644 index 0000000000..aecf482e3a --- /dev/null +++ b/test/pleroma/ecto_type/activity_pub/object_validators/map_of_string_test.exs @@ -0,0 +1,43 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.MapOfStringTest do + alias Pleroma.EctoType.ActivityPub.ObjectValidators.MapOfString + use Pleroma.DataCase, async: true + + test "it validates" do + data = %{ + "en-US" => "mew mew", + "en-GB" => "meow meow" + } + + assert {:ok, ^data} = MapOfString.cast(data) + end + + test "it validates empty strings" do + data = %{ + "en-US" => "mew mew", + "en-GB" => "" + } + + assert {:ok, ^data} = MapOfString.cast(data) + end + + test "it ignores non-strings within the map" do + data = %{ + "en-US" => "mew mew", + "en-GB" => 123 + } + + assert {:ok, validated_data} = MapOfString.cast(data) + + assert validated_data == %{"en-US" => "mew mew"} + end + + test "it complains with non-map data" do + assert :error = MapOfString.cast("mew") + assert :error = MapOfString.cast(["mew"]) + assert :error = MapOfString.cast([%{"en-US" => "mew"}]) + end +end diff --git a/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs index 511637e1d3..dedd389511 100644 --- a/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs +++ b/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs @@ -37,6 +37,31 @@ test "a note from factory validates" do note = insert(:note) %{valid?: true} = ArticleNotePageValidator.cast_and_validate(note.data) end + + test "Note with contentMap and summaryMap", %{note: note} do + summary_map = %{ + "en-US" => "mew", + "en-GB" => "meow" + } + + content_map = %{ + "en-US" => "mew mew", + "en-GB" => "meow meow" + } + + note = + note + |> Map.put("summaryMap", summary_map) + |> Map.put("contentMap", content_map) + + assert %{ + valid?: true, + changes: %{ + summaryMap: ^summary_map, + contentMap: ^content_map + } + } = ArticleNotePageValidator.cast_and_validate(note) + end end describe "Note with history" do diff --git a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs index a615c1d9ac..e433e9cd9e 100644 --- a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs +++ b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs @@ -42,6 +42,26 @@ test "works with honkerific attachments" do assert attachment.mediaType == "application/octet-stream" end + test "works with nameMap" do + attachment_data = %{ + "mediaType" => "", + "name" => "", + "nameMap" => %{ + "en-US" => "mew mew", + "en-GB" => "meow meow" + }, + "summary" => "298p3RG7j27tfsZ9RQ.jpg", + "type" => "Document", + "url" => "https://honk.tedunangst.com/d/298p3RG7j27tfsZ9RQ.jpg" + } + + assert {:ok, attachment} = + AttachmentValidator.cast_and_validate(attachment_data) + |> Ecto.Changeset.apply_action(:insert) + + assert attachment.nameMap == attachment_data["nameMap"] + end + test "works with an unknown but valid mime type" do attachment = %{ "mediaType" => "x-custom/x-type", diff --git a/test/pleroma/web/activity_pub/object_validators/question_options_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/question_options_validator_test.exs new file mode 100644 index 0000000000..87a0bafa07 --- /dev/null +++ b/test/pleroma/web/activity_pub/object_validators/question_options_validator_test.exs @@ -0,0 +1,27 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidatorTest do + use Pleroma.DataCase, async: true + + alias Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator + + describe "Validates Question options" do + test "" do + name_map = %{ + "en-US" => "mew", + "en-GB" => "meow" + } + + data = %{ + "type" => "Note", + "name" => "mew", + "nameMap" => name_map + } + + assert %{valid?: true, changes: %{nameMap: ^name_map}} = + QuestionOptionsValidator.changeset(%QuestionOptionsValidator{}, data) + end + end +end