diff options
4 files changed, 129 insertions, 4 deletions
| diff --git a/lib/pleroma/web/activity_pub/object_validator.ex b/lib/pleroma/web/activity_pub/object_validator.ex index 3f1dffe2b..d770ce1be 100644 --- a/lib/pleroma/web/activity_pub/object_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validator.ex @@ -16,6 +16,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do    alias Pleroma.Web.ActivityPub.ObjectValidators.AcceptRejectValidator    alias Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator    alias Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator +  alias Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator    alias Pleroma.Web.ActivityPub.ObjectValidators.BlockValidator    alias Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator    alias Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator @@ -137,6 +138,16 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do      end    end +  def validate(%{"type" => "Audio"} = object, meta) do +    with {:ok, object} <- +           object +           |> AudioValidator.cast_and_validate() +           |> Ecto.Changeset.apply_action(:insert) do +      object = stringify_keys(object) +      {:ok, object, meta} +    end +  end +    def validate(%{"type" => "Answer"} = object, meta) do      with {:ok, object} <-             object @@ -176,7 +187,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do          %{"type" => "Create", "object" => %{"type" => objtype} = object} = create_activity,          meta        ) -      when objtype in ["Question", "Answer"] do +      when objtype in ~w[Question Answer Audio] do      with {:ok, object_data} <- cast_and_apply(object),           meta = Keyword.put(meta, :object_data, object_data |> stringify_keys),           {:ok, create_activity} <- @@ -210,6 +221,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do      AnswerValidator.cast_and_apply(object)    end +  def cast_and_apply(%{"type" => "Audio"} = object) do +    AudioValidator.cast_and_apply(object) +  end +    def cast_and_apply(o), do: {:error, {:validator_not_set, o}}    # is_struct/1 isn't present in Elixir 1.8.x diff --git a/lib/pleroma/web/activity_pub/object_validators/audio_validator.ex b/lib/pleroma/web/activity_pub/object_validators/audio_validator.ex new file mode 100644 index 000000000..5ff9e3832 --- /dev/null +++ b/lib/pleroma/web/activity_pub/object_validators/audio_validator.ex @@ -0,0 +1,109 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do +  use Ecto.Schema + +  alias Pleroma.EctoType.ActivityPub.ObjectValidators +  alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator +  alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations +  alias Pleroma.Web.ActivityPub.Utils + +  import Ecto.Changeset + +  @primary_key false +  @derive Jason.Encoder + +  # Extends from NoteValidator +  embedded_schema do +    field(:id, ObjectValidators.ObjectID, primary_key: true) +    field(:to, ObjectValidators.Recipients, default: []) +    field(:cc, ObjectValidators.Recipients, default: []) +    field(:bto, ObjectValidators.Recipients, default: []) +    field(:bcc, ObjectValidators.Recipients, default: []) +    # TODO: Write type +    field(:tag, {:array, :map}, default: []) +    field(:type, :string) +    field(:content, :string) +    field(:context, :string) + +    # TODO: Remove actor on objects +    field(:actor, ObjectValidators.ObjectID) + +    field(:attributedTo, ObjectValidators.ObjectID) +    field(:summary, :string) +    field(:published, ObjectValidators.DateTime) +    # TODO: Write type +    field(:emoji, :map, default: %{}) +    field(:sensitive, :boolean, default: false) +    embeds_many(:attachment, AttachmentValidator) +    field(:replies_count, :integer, default: 0) +    field(:like_count, :integer, default: 0) +    field(:announcement_count, :integer, default: 0) +    field(:inReplyTo, :string) +    field(:uri, ObjectValidators.Uri) +    # short identifier for PleromaFE to group statuses by context +    field(:context_id, :integer) + +    field(:likes, {:array, :string}, default: []) +    field(:announcements, {:array, :string}, default: []) +  end + +  def cast_and_apply(data) do +    data +    |> cast_data +    |> apply_action(:insert) +  end + +  def cast_and_validate(data) do +    data +    |> cast_data() +    |> validate_data() +  end + +  def cast_data(data) do +    %__MODULE__{} +    |> changeset(data) +  end + +  # based on Pleroma.Web.ActivityPub.Utils.lazy_put_objects_defaults +  defp fix_defaults(data) do +    %{data: %{"id" => context}, id: context_id} = +      Utils.create_context(data["context"] || data["conversation"]) + +    data +    |> Map.put_new_lazy("published", &Utils.make_date/0) +    |> Map.put_new("context", context) +    |> Map.put_new("context_id", context_id) +  end + +  defp fix_attribution(data) do +    data +    |> Map.put_new("actor", data["attributedTo"]) +  end + +  defp fix(data) do +    data +    |> fix_defaults() +    |> fix_attribution() +  end + +  def changeset(struct, data) do +    data = fix(data) + +    struct +    |> cast(data, __schema__(:fields) -- [:attachment]) +    |> cast_embed(:attachment) +  end + +  def validate_data(data_cng) do +    data_cng +    |> validate_inclusion(:type, ["Audio"]) +    |> validate_required([:id, :actor, :attributedTo, :type, :context]) +    |> CommonValidations.validate_any_presence([:cc, :to]) +    |> CommonValidations.validate_fields_match([:actor, :attributedTo]) +    |> CommonValidations.validate_actor_presence() +    |> CommonValidations.validate_host_match() +  end +end diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex index bcd6fd2fb..3dc66c60b 100644 --- a/lib/pleroma/web/activity_pub/side_effects.ex +++ b/lib/pleroma/web/activity_pub/side_effects.ex @@ -340,7 +340,8 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do      end    end -  def handle_object_creation(%{"type" => "Question"} = object, meta) do +  def handle_object_creation(%{"type" => objtype} = object, meta) +      when objtype in ~w[Audio Question] do      with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do        {:ok, object, meta}      end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 544f3f3b6..6be17e0ed 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -461,7 +461,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do          %{"type" => "Create", "object" => %{"type" => objtype} = object} = data,          options        ) -      when objtype in ["Article", "Event", "Note", "Video", "Page", "Audio"] do +      when objtype in ~w{Article Event Note Video Page} do      actor = Containment.get_actor(data)      with nil <- Activity.get_create_by_object_ap_id(object["id"]), @@ -555,7 +555,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do          %{"type" => "Create", "object" => %{"type" => objtype}} = data,          _options        ) -      when objtype in ["Question", "Answer", "ChatMessage"] do +      when objtype in ~w{Question Answer ChatMessage Audio} do      with {:ok, %User{}} <- ObjectValidator.fetch_actor(data),           {:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do        {:ok, activity} | 
