summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/web/activity_pub/builder.ex16
-rw-r--r--lib/pleroma/web/activity_pub/object_validator.ex17
-rw-r--r--lib/pleroma/web/activity_pub/object_validators/common_validations.ex20
-rw-r--r--lib/pleroma/web/activity_pub/object_validators/delete_validator.ex64
4 files changed, 117 insertions, 0 deletions
diff --git a/lib/pleroma/web/activity_pub/builder.ex b/lib/pleroma/web/activity_pub/builder.ex
index 429a510b8..5cc46c3ea 100644
--- a/lib/pleroma/web/activity_pub/builder.ex
+++ b/lib/pleroma/web/activity_pub/builder.ex
@@ -10,6 +10,22 @@ defmodule Pleroma.Web.ActivityPub.Builder do
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.Visibility
+ @spec delete(User.t(), String.t()) :: {:ok, map(), keyword()}
+ def delete(actor, object_id) do
+ object = Object.normalize(object_id)
+
+ to = (object.data["to"] || []) ++ (object.data["cc"] || [])
+
+ {:ok,
+ %{
+ "id" => Utils.generate_activity_id(),
+ "actor" => actor.ap_id,
+ "object" => object_id,
+ "to" => to,
+ "type" => "Delete"
+ }, []}
+ end
+
@spec like(User.t(), Object.t()) :: {:ok, map(), keyword()}
def like(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 dc4bce059..f476c6f72 100644
--- a/lib/pleroma/web/activity_pub/object_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validator.ex
@@ -12,10 +12,21 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
+ alias Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator
@spec validate(map(), keyword()) :: {:ok, map(), keyword()} | {:error, any()}
def validate(object, meta)
+ def validate(%{"type" => "Delete"} = object, meta) do
+ with {:ok, object} <-
+ object
+ |> DeleteValidator.cast_and_validate()
+ |> Ecto.Changeset.apply_action(:insert) do
+ object = stringify_keys(object)
+ {:ok, object, meta}
+ end
+ end
+
def validate(%{"type" => "Like"} = object, meta) do
with {:ok, object} <-
object |> LikeValidator.cast_and_validate() |> Ecto.Changeset.apply_action(:insert) do
@@ -24,6 +35,12 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
end
end
+ def stringify_keys(%{__struct__: _} = object) do
+ object
+ |> Map.from_struct()
+ |> stringify_keys
+ end
+
def stringify_keys(object) do
object
|> Map.new(fn {key, val} -> {to_string(key), val} end)
diff --git a/lib/pleroma/web/activity_pub/object_validators/common_validations.ex b/lib/pleroma/web/activity_pub/object_validators/common_validations.ex
index b479c3918..e115d9526 100644
--- a/lib/pleroma/web/activity_pub/object_validators/common_validations.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/common_validations.ex
@@ -8,6 +8,26 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations do
alias Pleroma.Object
alias Pleroma.User
+ def validate_recipients_presence(cng, fields \\ [:to, :cc]) do
+ non_empty =
+ fields
+ |> Enum.map(fn field -> get_field(cng, field) end)
+ |> Enum.any?(fn
+ [] -> false
+ _ -> true
+ end)
+
+ if non_empty do
+ cng
+ else
+ fields
+ |> Enum.reduce(cng, fn field, cng ->
+ cng
+ |> add_error(field, "no recipients in any field")
+ end)
+ end
+ end
+
def validate_actor_presence(cng, field_name \\ :actor) do
cng
|> validate_change(field_name, fn field_name, actor ->
diff --git a/lib/pleroma/web/activity_pub/object_validators/delete_validator.ex b/lib/pleroma/web/activity_pub/object_validators/delete_validator.ex
new file mode 100644
index 000000000..8dd5c19ad
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/object_validators/delete_validator.ex
@@ -0,0 +1,64 @@
+# 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.DeleteValidator do
+ use Ecto.Schema
+
+ alias Pleroma.Web.ActivityPub.ObjectValidators.Types
+
+ 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(:actor, Types.ObjectID)
+ field(:to, Types.Recipients, default: [])
+ field(:cc, Types.Recipients, default: [])
+ field(:object, Types.ObjectID)
+ end
+
+ def cast_data(data) do
+ %__MODULE__{}
+ |> cast(data, __schema__(:fields))
+ end
+
+ def validate_data(cng) do
+ cng
+ |> validate_required([:id, :type, :actor, :to, :cc, :object])
+ |> validate_inclusion(:type, ["Delete"])
+ |> validate_same_domain()
+ |> validate_object_presence()
+ |> validate_recipients_presence()
+ end
+
+ def validate_same_domain(cng) do
+ actor_domain =
+ cng
+ |> get_field(:actor)
+ |> URI.parse()
+ |> (& &1.host).()
+
+ object_domain =
+ cng
+ |> get_field(:object)
+ |> URI.parse()
+ |> (& &1.host).()
+
+ if object_domain != actor_domain do
+ cng
+ |> add_error(:actor, "is not allowed to delete object")
+ else
+ cng
+ end
+ end
+
+ def cast_and_validate(data) do
+ data
+ |> cast_data
+ |> validate_data
+ end
+end