9f15f198154cc1a9f289042c94f3c70572f29c0d
[anni] / lib / pleroma / web / activity_pub / object_validators / tag_validator.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
6   use Ecto.Schema
7
8   alias Pleroma.EctoType.ActivityPub.ObjectValidators
9
10   import Ecto.Changeset
11
12   @primary_key false
13   embedded_schema do
14     # Common
15     field(:type, :string)
16     field(:name, :string)
17
18     # Mention, Hashtag
19     field(:href, ObjectValidators.Uri)
20
21     # Emoji
22     embeds_one :icon, IconObjectValidator, primary_key: false do
23       field(:type, :string)
24       field(:url, ObjectValidators.Uri)
25     end
26
27     field(:updated, ObjectValidators.DateTime)
28     field(:id, ObjectValidators.Uri)
29   end
30
31   def cast_and_validate(data) do
32     data
33     |> cast_data()
34   end
35
36   def cast_data(data) do
37     %__MODULE__{}
38     |> changeset(data)
39   end
40
41   def changeset(struct, %{"type" => "Mention"} = data) do
42     struct
43     |> cast(data, [:type, :name, :href])
44     |> validate_required([:type, :href])
45   end
46
47   def changeset(struct, %{"type" => "Hashtag", "name" => name} = data) do
48     name =
49       cond do
50         "#" <> name -> name
51         name -> name
52       end
53       |> String.downcase()
54
55     data = Map.put(data, "name", name)
56
57     struct
58     |> cast(data, [:type, :name, :href])
59     |> validate_required([:type, :name])
60   end
61
62   def changeset(struct, %{"type" => "Emoji"} = data) do
63     data = Map.put(data, "name", String.trim(data["name"], ":"))
64
65     struct
66     |> cast(data, [:type, :name, :updated, :id])
67     |> cast_embed(:icon, with: &icon_changeset/2)
68     |> validate_required([:type, :name, :icon])
69   end
70
71   def icon_changeset(struct, data) do
72     struct
73     |> cast(data, [:type, :url])
74     |> validate_inclusion(:type, ~w[Image])
75     |> validate_required([:type, :url])
76   end
77 end