Merge branch 'features/ingestion-ecto-tag' into 'develop'
TagValidator: New See merge request pleroma/pleroma!3244
This commit is contained in:
commit
15f87cf658
24 changed files with 166 additions and 69 deletions
|
@ -114,9 +114,34 @@ def validate(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate(%{"type" => type} = object, meta)
|
||||||
|
when type in ~w[Event Question Audio Video Article] do
|
||||||
|
validator =
|
||||||
|
case type do
|
||||||
|
"Event" -> EventValidator
|
||||||
|
"Question" -> QuestionValidator
|
||||||
|
"Audio" -> AudioVideoValidator
|
||||||
|
"Video" -> AudioVideoValidator
|
||||||
|
"Article" -> ArticleNoteValidator
|
||||||
|
end
|
||||||
|
|
||||||
|
with {:ok, object} <-
|
||||||
|
object
|
||||||
|
|> validator.cast_and_validate()
|
||||||
|
|> Ecto.Changeset.apply_action(:insert) do
|
||||||
|
object = stringify_keys(object)
|
||||||
|
|
||||||
|
# Insert copy of hashtags as strings for the non-hashtag table indexing
|
||||||
|
tag = (object["tag"] || []) ++ Object.hashtags(%Object{data: object})
|
||||||
|
object = Map.put(object, "tag", tag)
|
||||||
|
|
||||||
|
{:ok, object, meta}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def validate(%{"type" => type} = object, meta)
|
def validate(%{"type" => type} = object, meta)
|
||||||
when type in ~w[Accept Reject Follow Update Like EmojiReact Announce
|
when type in ~w[Accept Reject Follow Update Like EmojiReact Announce
|
||||||
Event ChatMessage Question Audio Video Article Answer] do
|
ChatMessage Answer] do
|
||||||
validator =
|
validator =
|
||||||
case type do
|
case type do
|
||||||
"Accept" -> AcceptRejectValidator
|
"Accept" -> AcceptRejectValidator
|
||||||
|
@ -126,12 +151,7 @@ def validate(%{"type" => type} = object, meta)
|
||||||
"Like" -> LikeValidator
|
"Like" -> LikeValidator
|
||||||
"EmojiReact" -> EmojiReactValidator
|
"EmojiReact" -> EmojiReactValidator
|
||||||
"Announce" -> AnnounceValidator
|
"Announce" -> AnnounceValidator
|
||||||
"Event" -> EventValidator
|
|
||||||
"ChatMessage" -> ChatMessageValidator
|
"ChatMessage" -> ChatMessageValidator
|
||||||
"Question" -> QuestionValidator
|
|
||||||
"Audio" -> AudioVideoValidator
|
|
||||||
"Video" -> AudioVideoValidator
|
|
||||||
"Article" -> ArticleNoteValidator
|
|
||||||
"Answer" -> AnswerValidator
|
"Answer" -> AnswerValidator
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -180,7 +200,7 @@ def cast_and_apply(%{"type" => "Article"} = object) do
|
||||||
|
|
||||||
def cast_and_apply(o), do: {:error, {:validator_not_set, o}}
|
def cast_and_apply(o), do: {:error, {:validator_not_set, o}}
|
||||||
|
|
||||||
# is_struct/1 isn't present in Elixir 1.8.x
|
# is_struct/1 appears in Elixir 1.11
|
||||||
def stringify_keys(%{__struct__: _} = object) do
|
def stringify_keys(%{__struct__: _} = object) do
|
||||||
object
|
object
|
||||||
|> Map.from_struct()
|
|> Map.from_struct()
|
||||||
|
|
|
@ -27,7 +27,7 @@ def cast_data(data) do
|
||||||
|> cast(data, __schema__(:fields))
|
|> cast(data, __schema__(:fields))
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(cng) do
|
defp validate_data(cng) do
|
||||||
cng
|
cng
|
||||||
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
||||||
|> validate_inclusion(:type, ["Accept", "Reject"])
|
|> validate_inclusion(:type, ["Accept", "Reject"])
|
||||||
|
|
|
@ -50,7 +50,7 @@ def fix_after_cast(cng) do
|
||||||
cng
|
cng
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(data_cng) do
|
defp validate_data(data_cng) do
|
||||||
data_cng
|
data_cng
|
||||||
|> validate_inclusion(:type, ["Announce"])
|
|> validate_inclusion(:type, ["Announce"])
|
||||||
|> validate_required([:id, :type, :object, :actor, :to, :cc])
|
|> validate_required([:id, :type, :object, :actor, :to, :cc])
|
||||||
|
|
|
@ -50,7 +50,7 @@ def changeset(struct, data) do
|
||||||
|> cast(data, __schema__(:fields))
|
|> cast(data, __schema__(:fields))
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(data_cng) do
|
defp validate_data(data_cng) do
|
||||||
data_cng
|
data_cng
|
||||||
|> validate_inclusion(:type, ["Answer"])
|
|> validate_inclusion(:type, ["Answer"])
|
||||||
|> validate_required([:id, :inReplyTo, :name, :attributedTo, :actor])
|
|> validate_required([:id, :inReplyTo, :name, :attributedTo, :actor])
|
||||||
|
|
|
@ -9,6 +9,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNoteValidator 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.ObjectValidators.TagValidator
|
||||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
@ -22,8 +23,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNoteValidator do
|
||||||
field(:cc, ObjectValidators.Recipients, default: [])
|
field(:cc, ObjectValidators.Recipients, default: [])
|
||||||
field(:bto, ObjectValidators.Recipients, default: [])
|
field(:bto, ObjectValidators.Recipients, default: [])
|
||||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||||
# TODO: Write type
|
embeds_many(:tag, TagValidator)
|
||||||
field(:tag, {:array, :map}, default: [])
|
|
||||||
field(:type, :string)
|
field(:type, :string)
|
||||||
|
|
||||||
field(:name, :string)
|
field(:name, :string)
|
||||||
|
@ -90,11 +90,12 @@ def changeset(struct, data) do
|
||||||
data = fix(data)
|
data = fix(data)
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|> cast(data, __schema__(:fields) -- [:attachment])
|
|> cast(data, __schema__(:fields) -- [:attachment, :tag])
|
||||||
|> cast_embed(:attachment)
|
|> cast_embed(:attachment)
|
||||||
|
|> cast_embed(:tag)
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(data_cng) do
|
defp validate_data(data_cng) do
|
||||||
data_cng
|
data_cng
|
||||||
|> validate_inclusion(:type, ["Article", "Note"])
|
|> validate_inclusion(:type, ["Article", "Note"])
|
||||||
|> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id])
|
|> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id])
|
||||||
|
|
|
@ -6,7 +6,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
|
|
||||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.UrlObjectValidator
|
|
||||||
|
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
@ -90,7 +89,7 @@ defp fix_url(data) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(cng) do
|
defp validate_data(cng) do
|
||||||
cng
|
cng
|
||||||
|> validate_inclusion(:type, ~w[Document Audio Image Video])
|
|> validate_inclusion(:type, ~w[Document Audio Image Video])
|
||||||
|> validate_required([:mediaType, :url, :type])
|
|> validate_required([:mediaType, :url, :type])
|
||||||
|
|
|
@ -10,6 +10,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator 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.ObjectValidators.TagValidator
|
||||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
@ -23,8 +24,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator do
|
||||||
field(:cc, ObjectValidators.Recipients, default: [])
|
field(:cc, ObjectValidators.Recipients, default: [])
|
||||||
field(:bto, ObjectValidators.Recipients, default: [])
|
field(:bto, ObjectValidators.Recipients, default: [])
|
||||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||||
# TODO: Write type
|
embeds_many(:tag, TagValidator)
|
||||||
field(:tag, {:array, :map}, default: [])
|
|
||||||
field(:type, :string)
|
field(:type, :string)
|
||||||
|
|
||||||
field(:name, :string)
|
field(:name, :string)
|
||||||
|
@ -132,11 +132,12 @@ def changeset(struct, data) do
|
||||||
data = fix(data)
|
data = fix(data)
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|> cast(data, __schema__(:fields) -- [:attachment])
|
|> cast(data, __schema__(:fields) -- [:attachment, :tag])
|
||||||
|> cast_embed(:attachment)
|
|> cast_embed(:attachment)
|
||||||
|
|> cast_embed(:tag)
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(data_cng) do
|
defp validate_data(data_cng) do
|
||||||
data_cng
|
data_cng
|
||||||
|> validate_inclusion(:type, ["Audio", "Video"])
|
|> validate_inclusion(:type, ["Audio", "Video"])
|
||||||
|> validate_required([:id, :actor, :attributedTo, :type, :context, :attachment])
|
|> validate_required([:id, :actor, :attributedTo, :type, :context, :attachment])
|
||||||
|
|
|
@ -26,7 +26,7 @@ def cast_data(data) do
|
||||||
|> cast(data, __schema__(:fields))
|
|> cast(data, __schema__(:fields))
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(cng) do
|
defp validate_data(cng) do
|
||||||
cng
|
cng
|
||||||
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
||||||
|> validate_inclusion(:type, ["Block"])
|
|> validate_inclusion(:type, ["Block"])
|
||||||
|
|
|
@ -67,7 +67,7 @@ def changeset(struct, data) do
|
||||||
|> cast_embed(:attachment)
|
|> cast_embed(:attachment)
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(data_cng) do
|
defp validate_data(data_cng) do
|
||||||
data_cng
|
data_cng
|
||||||
|> validate_inclusion(:type, ["ChatMessage"])
|
|> validate_inclusion(:type, ["ChatMessage"])
|
||||||
|> validate_required([:id, :actor, :to, :type, :published])
|
|> validate_required([:id, :actor, :to, :type, :published])
|
||||||
|
|
|
@ -39,7 +39,7 @@ def cast_and_validate(data, meta \\ []) do
|
||||||
|> validate_data(meta)
|
|> validate_data(meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(cng, meta \\ []) do
|
defp validate_data(cng, meta) do
|
||||||
cng
|
cng
|
||||||
|> validate_required([:id, :actor, :to, :type, :object])
|
|> validate_required([:id, :actor, :to, :type, :object])
|
||||||
|> validate_inclusion(:type, ["Create"])
|
|> validate_inclusion(:type, ["Create"])
|
||||||
|
|
|
@ -79,7 +79,7 @@ defp fix(data, meta) do
|
||||||
|> CommonFixes.fix_actor()
|
|> CommonFixes.fix_actor()
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(cng, meta \\ []) do
|
defp validate_data(cng, meta) do
|
||||||
cng
|
cng
|
||||||
|> validate_required([:actor, :type, :object])
|
|> validate_required([:actor, :type, :object])
|
||||||
|> validate_inclusion(:type, ["Create"])
|
|> validate_inclusion(:type, ["Create"])
|
||||||
|
|
|
@ -53,7 +53,7 @@ def add_deleted_activity_id(cng) do
|
||||||
Tombstone
|
Tombstone
|
||||||
Video
|
Video
|
||||||
}
|
}
|
||||||
def validate_data(cng) do
|
defp validate_data(cng) do
|
||||||
cng
|
cng
|
||||||
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
||||||
|> validate_inclusion(:type, ["Delete"])
|
|> validate_inclusion(:type, ["Delete"])
|
||||||
|
|
|
@ -70,7 +70,7 @@ def validate_emoji(cng) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(data_cng) do
|
defp validate_data(data_cng) do
|
||||||
data_cng
|
data_cng
|
||||||
|> validate_inclusion(:type, ["EmojiReact"])
|
|> validate_inclusion(:type, ["EmojiReact"])
|
||||||
|> validate_required([:id, :type, :object, :actor, :context, :to, :cc, :content])
|
|> validate_required([:id, :type, :object, :actor, :context, :to, :cc, :content])
|
||||||
|
|
|
@ -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.ObjectValidators.TagValidator
|
||||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
@ -23,8 +24,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EventValidator do
|
||||||
field(:cc, ObjectValidators.Recipients, default: [])
|
field(:cc, ObjectValidators.Recipients, default: [])
|
||||||
field(:bto, ObjectValidators.Recipients, default: [])
|
field(:bto, ObjectValidators.Recipients, default: [])
|
||||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||||
# TODO: Write type
|
embeds_many(:tag, TagValidator)
|
||||||
field(:tag, {:array, :map}, default: [])
|
|
||||||
field(:type, :string)
|
field(:type, :string)
|
||||||
|
|
||||||
field(:name, :string)
|
field(:name, :string)
|
||||||
|
@ -81,11 +81,12 @@ def changeset(struct, data) do
|
||||||
data = fix(data)
|
data = fix(data)
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|> cast(data, __schema__(:fields) -- [:attachment])
|
|> cast(data, __schema__(:fields) -- [:attachment, :tag])
|
||||||
|> cast_embed(:attachment)
|
|> cast_embed(:attachment)
|
||||||
|
|> cast_embed(:tag)
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(data_cng) do
|
defp validate_data(data_cng) do
|
||||||
data_cng
|
data_cng
|
||||||
|> validate_inclusion(:type, ["Event"])
|
|> validate_inclusion(:type, ["Event"])
|
||||||
|> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id])
|
|> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id])
|
||||||
|
|
|
@ -27,7 +27,7 @@ def cast_data(data) do
|
||||||
|> cast(data, __schema__(:fields))
|
|> cast(data, __schema__(:fields))
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(cng) do
|
defp validate_data(cng) do
|
||||||
cng
|
cng
|
||||||
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
||||||
|> validate_inclusion(:type, ["Follow"])
|
|> validate_inclusion(:type, ["Follow"])
|
||||||
|
|
|
@ -76,7 +76,7 @@ def fix_recipients(cng) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(data_cng) do
|
defp validate_data(data_cng) do
|
||||||
data_cng
|
data_cng
|
||||||
|> validate_inclusion(:type, ["Like"])
|
|> validate_inclusion(:type, ["Like"])
|
||||||
|> validate_required([:id, :type, :object, :actor, :context, :to, :cc])
|
|> validate_required([:id, :type, :object, :actor, :context, :to, :cc])
|
||||||
|
|
|
@ -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.ObjectValidators.TagValidator
|
||||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
@ -24,8 +25,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
|
||||||
field(:cc, ObjectValidators.Recipients, default: [])
|
field(:cc, ObjectValidators.Recipients, default: [])
|
||||||
field(:bto, ObjectValidators.Recipients, default: [])
|
field(:bto, ObjectValidators.Recipients, default: [])
|
||||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||||
# TODO: Write type
|
embeds_many(:tag, TagValidator)
|
||||||
field(:tag, {:array, :map}, default: [])
|
|
||||||
field(:type, :string)
|
field(:type, :string)
|
||||||
field(:content, :string)
|
field(:content, :string)
|
||||||
field(:context, :string)
|
field(:context, :string)
|
||||||
|
@ -93,13 +93,14 @@ def changeset(struct, data) do
|
||||||
data = fix(data)
|
data = fix(data)
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|> cast(data, __schema__(:fields) -- [:anyOf, :oneOf, :attachment])
|
|> cast(data, __schema__(:fields) -- [:anyOf, :oneOf, :attachment, :tag])
|
||||||
|> cast_embed(:attachment)
|
|> cast_embed(:attachment)
|
||||||
|> cast_embed(:anyOf)
|
|> cast_embed(:anyOf)
|
||||||
|> cast_embed(:oneOf)
|
|> cast_embed(:oneOf)
|
||||||
|
|> cast_embed(:tag)
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(data_cng) do
|
defp validate_data(data_cng) do
|
||||||
data_cng
|
data_cng
|
||||||
|> validate_inclusion(:type, ["Question"])
|
|> validate_inclusion(:type, ["Question"])
|
||||||
|> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id])
|
|> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id])
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
|
||||||
|
use Ecto.Schema
|
||||||
|
|
||||||
|
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||||
|
|
||||||
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
@primary_key false
|
||||||
|
embedded_schema do
|
||||||
|
# Common
|
||||||
|
field(:type, :string)
|
||||||
|
field(:name, :string)
|
||||||
|
|
||||||
|
# Mention, Hashtag
|
||||||
|
field(:href, ObjectValidators.Uri)
|
||||||
|
|
||||||
|
# Emoji
|
||||||
|
embeds_one :icon, IconObjectValidator, primary_key: false do
|
||||||
|
field(:type, :string)
|
||||||
|
field(:url, ObjectValidators.Uri)
|
||||||
|
end
|
||||||
|
|
||||||
|
field(:updated, ObjectValidators.DateTime)
|
||||||
|
field(:id, ObjectValidators.Uri)
|
||||||
|
end
|
||||||
|
|
||||||
|
def cast_and_validate(data) do
|
||||||
|
data
|
||||||
|
|> cast_data()
|
||||||
|
end
|
||||||
|
|
||||||
|
def cast_data(data) do
|
||||||
|
%__MODULE__{}
|
||||||
|
|> changeset(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def changeset(struct, %{"type" => "Mention"} = data) do
|
||||||
|
struct
|
||||||
|
|> cast(data, [:type, :name, :href])
|
||||||
|
|> validate_required([:type, :href])
|
||||||
|
end
|
||||||
|
|
||||||
|
def changeset(struct, %{"type" => "Hashtag", "name" => name} = data) do
|
||||||
|
name =
|
||||||
|
cond do
|
||||||
|
"#" <> name -> name
|
||||||
|
name -> name
|
||||||
|
end
|
||||||
|
|> String.downcase()
|
||||||
|
|
||||||
|
data = Map.put(data, "name", name)
|
||||||
|
|
||||||
|
struct
|
||||||
|
|> cast(data, [:type, :name, :href])
|
||||||
|
|> validate_required([:type, :name])
|
||||||
|
end
|
||||||
|
|
||||||
|
def changeset(struct, %{"type" => "Emoji"} = data) do
|
||||||
|
data = Map.put(data, "name", String.trim(data["name"], ":"))
|
||||||
|
|
||||||
|
struct
|
||||||
|
|> cast(data, [:type, :name, :updated, :id])
|
||||||
|
|> cast_embed(:icon, with: &icon_changeset/2)
|
||||||
|
|> validate_required([:type, :name, :icon])
|
||||||
|
end
|
||||||
|
|
||||||
|
def icon_changeset(struct, data) do
|
||||||
|
struct
|
||||||
|
|> cast(data, [:type, :url])
|
||||||
|
|> validate_inclusion(:type, ~w[Image])
|
||||||
|
|> validate_required([:type, :url])
|
||||||
|
end
|
||||||
|
end
|
|
@ -38,7 +38,7 @@ def changeset(struct, data) do
|
||||||
|> cast(data, __schema__(:fields))
|
|> cast(data, __schema__(:fields))
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(data_cng) do
|
defp validate_data(data_cng) do
|
||||||
data_cng
|
data_cng
|
||||||
|> validate_inclusion(:type, ["Undo"])
|
|> validate_inclusion(:type, ["Undo"])
|
||||||
|> validate_required([:id, :type, :object, :actor, :to, :cc])
|
|> validate_required([:id, :type, :object, :actor, :to, :cc])
|
||||||
|
|
|
@ -28,7 +28,7 @@ def cast_data(data) do
|
||||||
|> cast(data, __schema__(:fields))
|
|> cast(data, __schema__(:fields))
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_data(cng) do
|
defp validate_data(cng) do
|
||||||
cng
|
cng
|
||||||
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
||||||
|> validate_inclusion(:type, ["Update"])
|
|> validate_inclusion(:type, ["Update"])
|
||||||
|
|
|
@ -40,19 +40,17 @@ def common_pipeline(object, meta) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def do_common_pipeline(object, meta) do
|
def do_common_pipeline(%{__struct__: _}, _meta), do: {:error, :is_struct}
|
||||||
with {_, {:ok, validated_object, meta}} <-
|
|
||||||
{:validate_object, @object_validator.validate(object, meta)},
|
def do_common_pipeline(message, meta) do
|
||||||
{_, {:ok, mrfd_object, meta}} <-
|
with {_, {:ok, message, meta}} <- {:validate, @object_validator.validate(message, meta)},
|
||||||
{:mrf_object, @mrf.pipeline_filter(validated_object, meta)},
|
{_, {:ok, message, meta}} <- {:mrf, @mrf.pipeline_filter(message, meta)},
|
||||||
{_, {:ok, activity, meta}} <-
|
{_, {:ok, message, meta}} <- {:persist, @activity_pub.persist(message, meta)},
|
||||||
{:persist_object, @activity_pub.persist(mrfd_object, meta)},
|
{_, {:ok, message, meta}} <- {:side_effects, @side_effects.handle(message, meta)},
|
||||||
{_, {:ok, activity, meta}} <-
|
{_, {:ok, _}} <- {:federation, maybe_federate(message, meta)} do
|
||||||
{:execute_side_effects, @side_effects.handle(activity, meta)},
|
{:ok, message, meta}
|
||||||
{_, {:ok, _}} <- {:federation, maybe_federate(activity, meta)} do
|
|
||||||
{:ok, activity, meta}
|
|
||||||
else
|
else
|
||||||
{:mrf_object, {:reject, message, _}} -> {:reject, message}
|
{:mrf, {:reject, message, _}} -> {:reject, message}
|
||||||
e -> {:error, e}
|
e -> {:error, e}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -564,7 +564,7 @@ def handle_incoming(
|
||||||
Pipeline.common_pipeline(data, local: false) do
|
Pipeline.common_pipeline(data, local: false) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
else
|
else
|
||||||
{:error, {:validate_object, _}} = e ->
|
{:error, {:validate, _}} = e ->
|
||||||
# Check if we have a create activity for this
|
# Check if we have a create activity for this
|
||||||
with {:ok, object_id} <- ObjectValidators.ObjectID.cast(data["object"]),
|
with {:ok, object_id} <- ObjectValidators.ObjectID.cast(data["object"]),
|
||||||
%Activity{data: %{"actor" => actor}} <-
|
%Activity{data: %{"actor" => actor}} <-
|
||||||
|
|
|
@ -228,17 +228,7 @@ def favorite_helper(user, id) do
|
||||||
{:find_object, _} ->
|
{:find_object, _} ->
|
||||||
{:error, :not_found}
|
{:error, :not_found}
|
||||||
|
|
||||||
{:common_pipeline,
|
{:common_pipeline, {:error, {:validate, {:error, changeset}}}} = e ->
|
||||||
{
|
|
||||||
:error,
|
|
||||||
{
|
|
||||||
:validate_object,
|
|
||||||
{
|
|
||||||
:error,
|
|
||||||
changeset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}} = e ->
|
|
||||||
if {:object, {"already liked by this actor", []}} in changeset.errors do
|
if {:object, {"already liked by this actor", []}} in changeset.errors do
|
||||||
{:ok, :already_liked}
|
{:ok, :already_liked}
|
||||||
else
|
else
|
||||||
|
|
|
@ -25,9 +25,6 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
|
||||||
MRFMock
|
MRFMock
|
||||||
|> expect(:pipeline_filter, fn o, m -> {:ok, o, m} end)
|
|> expect(:pipeline_filter, fn o, m -> {:ok, o, m} end)
|
||||||
|
|
||||||
ActivityPubMock
|
|
||||||
|> expect(:persist, fn o, m -> {:ok, o, m} end)
|
|
||||||
|
|
||||||
SideEffectsMock
|
SideEffectsMock
|
||||||
|> expect(:handle, fn o, m -> {:ok, o, m} end)
|
|> expect(:handle, fn o, m -> {:ok, o, m} end)
|
||||||
|> expect(:handle_after_transaction, fn m -> m end)
|
|> expect(:handle_after_transaction, fn m -> m end)
|
||||||
|
@ -42,6 +39,9 @@ test "when given an `object_data` in meta, Federation will receive a the origina
|
||||||
|
|
||||||
activity_with_object = %{activity | data: Map.put(activity.data, "object", object)}
|
activity_with_object = %{activity | data: Map.put(activity.data, "object", object)}
|
||||||
|
|
||||||
|
ActivityPubMock
|
||||||
|
|> expect(:persist, fn _, m -> {:ok, activity, m} end)
|
||||||
|
|
||||||
FederatorMock
|
FederatorMock
|
||||||
|> expect(:publish, fn ^activity_with_object -> :ok end)
|
|> expect(:publish, fn ^activity_with_object -> :ok end)
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ test "when given an `object_data` in meta, Federation will receive a the origina
|
||||||
|
|
||||||
assert {:ok, ^activity, ^meta} =
|
assert {:ok, ^activity, ^meta} =
|
||||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(
|
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(
|
||||||
activity,
|
activity.data,
|
||||||
meta
|
meta
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -59,6 +59,9 @@ test "it goes through validation, filtering, persisting, side effects and federa
|
||||||
activity = insert(:note_activity)
|
activity = insert(:note_activity)
|
||||||
meta = [local: true]
|
meta = [local: true]
|
||||||
|
|
||||||
|
ActivityPubMock
|
||||||
|
|> expect(:persist, fn _, m -> {:ok, activity, m} end)
|
||||||
|
|
||||||
FederatorMock
|
FederatorMock
|
||||||
|> expect(:publish, fn ^activity -> :ok end)
|
|> expect(:publish, fn ^activity -> :ok end)
|
||||||
|
|
||||||
|
@ -66,29 +69,35 @@ test "it goes through validation, filtering, persisting, side effects and federa
|
||||||
|> expect(:get, fn [:instance, :federating] -> true end)
|
|> expect(:get, fn [:instance, :federating] -> true end)
|
||||||
|
|
||||||
assert {:ok, ^activity, ^meta} =
|
assert {:ok, ^activity, ^meta} =
|
||||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity.data, meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it goes through validation, filtering, persisting, side effects without federation for remote activities" do
|
test "it goes through validation, filtering, persisting, side effects without federation for remote activities" do
|
||||||
activity = insert(:note_activity)
|
activity = insert(:note_activity)
|
||||||
meta = [local: false]
|
meta = [local: false]
|
||||||
|
|
||||||
|
ActivityPubMock
|
||||||
|
|> expect(:persist, fn _, m -> {:ok, activity, m} end)
|
||||||
|
|
||||||
ConfigMock
|
ConfigMock
|
||||||
|> expect(:get, fn [:instance, :federating] -> true end)
|
|> expect(:get, fn [:instance, :federating] -> true end)
|
||||||
|
|
||||||
assert {:ok, ^activity, ^meta} =
|
assert {:ok, ^activity, ^meta} =
|
||||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity.data, meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it goes through validation, filtering, persisting, side effects without federation for local activities if federation is deactivated" do
|
test "it goes through validation, filtering, persisting, side effects without federation for local activities if federation is deactivated" do
|
||||||
activity = insert(:note_activity)
|
activity = insert(:note_activity)
|
||||||
meta = [local: true]
|
meta = [local: true]
|
||||||
|
|
||||||
|
ActivityPubMock
|
||||||
|
|> expect(:persist, fn _, m -> {:ok, activity, m} end)
|
||||||
|
|
||||||
ConfigMock
|
ConfigMock
|
||||||
|> expect(:get, fn [:instance, :federating] -> false end)
|
|> expect(:get, fn [:instance, :federating] -> false end)
|
||||||
|
|
||||||
assert {:ok, ^activity, ^meta} =
|
assert {:ok, ^activity, ^meta} =
|
||||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity.data, meta)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue