object_validators: Mark validate_data as private
[akkoma] / lib / pleroma / web / activity_pub / object_validators / attachment_validator.ex
index f53bb02bec8d3261ec76e00cf1948b4907fb5c9e..4a0d1473de8e755f9def08c247641f7a21036e6e 100644 (file)
@@ -1,11 +1,11 @@
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
   use Ecto.Schema
 
-  alias Pleroma.Web.ActivityPub.ObjectValidators.UrlObjectValidator
+  alias Pleroma.EctoType.ActivityPub.ObjectValidators
 
   import Ecto.Changeset
 
@@ -14,8 +14,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
     field(:type, :string)
     field(:mediaType, :string, default: "application/octet-stream")
     field(:name, :string)
+    field(:blurhash, :string)
 
-    embeds_many(:url, UrlObjectValidator)
+    embeds_many :url, UrlObjectValidator, primary_key: false do
+      field(:type, :string)
+      field(:href, ObjectValidators.Uri)
+      field(:mediaType, :string, default: "application/octet-stream")
+    end
   end
 
   def cast_and_validate(data) do
@@ -36,45 +41,57 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
       |> fix_url()
 
     struct
-    |> cast(data, [:type, :mediaType, :name])
-    |> cast_embed(:url, required: true)
+    |> cast(data, [:type, :mediaType, :name, :blurhash])
+    |> cast_embed(:url, with: &url_changeset/2)
+    |> validate_inclusion(:type, ~w[Link Document Audio Image Video])
+    |> validate_required([:type, :mediaType, :url])
+  end
+
+  def url_changeset(struct, data) do
+    data = fix_media_type(data)
+
+    struct
+    |> cast(data, [:type, :href, :mediaType])
+    |> validate_inclusion(:type, ["Link"])
+    |> validate_required([:type, :href, :mediaType])
   end
 
   def fix_media_type(data) do
-    data =
-      data
-      |> Map.put_new("mediaType", data["mimeType"])
+    data = Map.put_new(data, "mediaType", data["mimeType"])
 
     if MIME.valid?(data["mediaType"]) do
       data
     else
-      data
-      |> Map.put("mediaType", "application/octet-stream")
+      Map.put(data, "mediaType", "application/octet-stream")
     end
   end
 
-  def fix_url(data) do
-    case data["url"] do
-      url when is_binary(url) ->
-        data
-        |> Map.put(
-          "url",
-          [
-            %{
-              "href" => url,
-              "type" => "Link",
-              "mediaType" => data["mediaType"]
-            }
-          ]
-        )
-
-      _ ->
+  defp handle_href(href, mediaType) do
+    [
+      %{
+        "href" => href,
+        "type" => "Link",
+        "mediaType" => mediaType
+      }
+    ]
+  end
+
+  defp fix_url(data) do
+    cond do
+      is_binary(data["url"]) ->
+        Map.put(data, "url", handle_href(data["url"], data["mediaType"]))
+
+      is_binary(data["href"]) and data["url"] == nil ->
+        Map.put(data, "url", handle_href(data["href"], data["mediaType"]))
+
+      true ->
         data
     end
   end
 
-  def validate_data(cng) do
+  defp validate_data(cng) do
     cng
+    |> validate_inclusion(:type, ~w[Document Audio Image Video])
     |> validate_required([:mediaType, :url, :type])
   end
 end