diff options
Diffstat (limited to 'lib')
4 files changed, 98 insertions, 4 deletions
| diff --git a/lib/pleroma/web/activity_pub/builder.ex b/lib/pleroma/web/activity_pub/builder.ex index 4a247ad0c..63f89c2b4 100644 --- a/lib/pleroma/web/activity_pub/builder.ex +++ b/lib/pleroma/web/activity_pub/builder.ex @@ -83,6 +83,20 @@ defmodule Pleroma.Web.ActivityPub.Builder do      end    end +  def announce(actor, object) do +    to = [actor.follower_address, object.data["actor"]] + +    {:ok, +     %{ +       "id" => Utils.generate_activity_id(), +       "actor" => actor.ap_id, +       "object" => object.data["id"], +       "to" => to, +       "context" => object.data["context"], +       "type" => "Announce" +     }, []} +  end +    @spec object_action(User.t(), Object.t()) :: {:ok, map(), keyword()}    defp object_action(actor, object) do      object_actor = User.get_cached_by_ap_id(object.data["actor"]) diff --git a/lib/pleroma/web/activity_pub/object_validator.ex b/lib/pleroma/web/activity_pub/object_validator.ex index 549e5e761..600e58123 100644 --- a/lib/pleroma/web/activity_pub/object_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validator.ex @@ -11,6 +11,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do    alias Pleroma.Object    alias Pleroma.User +  alias Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator    alias Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator    alias Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator    alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator @@ -58,6 +59,16 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do      end    end +  def validate(%{"type" => "Announce"} = object, meta) do +    with {:ok, object} <- +           object +           |> AnnounceValidator.cast_and_validate() +           |> Ecto.Changeset.apply_action(:insert) do +      object = stringify_keys(object |> Map.from_struct()) +      {:ok, object, meta} +    end +  end +    def stringify_keys(%{__struct__: _} = object) do      object      |> Map.from_struct() diff --git a/lib/pleroma/web/activity_pub/object_validators/announce_validator.ex b/lib/pleroma/web/activity_pub/object_validators/announce_validator.ex new file mode 100644 index 000000000..158ae199d --- /dev/null +++ b/lib/pleroma/web/activity_pub/object_validators/announce_validator.ex @@ -0,0 +1,68 @@ +# 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.AnnounceValidator do +  use Ecto.Schema + +  alias Pleroma.Web.ActivityPub.ObjectValidators.Types +  alias Pleroma.Web.ActivityPub.Utils + +  import Ecto.Changeset +  import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations + +  @primary_key false + +  embedded_schema do +    field(:id, Types.ObjectID, primary_key: true) +    field(:type, :string) +    field(:object, Types.ObjectID) +    field(:actor, Types.ObjectID) +    field(:context, :string) +    field(:to, Types.Recipients, default: []) +    field(:cc, Types.Recipients, default: []) +  end + +  def cast_and_validate(data) do +    data +    |> cast_data() +    |> validate_data() +  end + +  def cast_data(data) do +    %__MODULE__{} +    |> changeset(data) +  end + +  def changeset(struct, data) do +    struct +    |> cast(data, __schema__(:fields)) +    |> fix_after_cast() +  end + +  def fix_after_cast(cng) do +    cng +  end + +  def validate_data(data_cng) do +    data_cng +    |> validate_inclusion(:type, ["Announce"]) +    |> validate_required([:id, :type, :object, :actor, :context, :to, :cc]) +    |> validate_actor_presence() +    |> validate_object_presence() +    |> validate_existing_announce() +  end + +  def validate_existing_announce(cng) do +    actor = get_field(cng, :actor) +    object = get_field(cng, :object) + +    if actor && object && Utils.get_existing_announce(actor, %{data: %{"id" => object}}) do +      cng +      |> add_error(:actor, "already announced this object") +      |> add_error(:object, "already announced by this actor") +    else +      cng +    end +  end +end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 80701bb63..6104af4f9 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -677,13 +677,14 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do          _options        ) do      with actor <- Containment.get_actor(data), -         {:ok, %User{} = actor} <- User.get_or_fetch_by_ap_id(actor), -         {:ok, object} <- get_embedded_obj_helper(object_id, actor), +         {_, {:ok, %User{} = actor}} <- {:fetch_user, User.get_or_fetch_by_ap_id(actor)}, +         {_, {:ok, object}} <- {:get_embedded, get_embedded_obj_helper(object_id, actor)},           public <- Visibility.is_public?(data), -         {:ok, activity, _object} <- ActivityPub.announce(actor, object, id, false, public) do +         {_, {:ok, activity, _object}} <- +           {:announce, ActivityPub.announce(actor, object, id, false, public)} do        {:ok, activity}      else -      _e -> :error +      e -> {:error, e}      end    end | 
