AcceptValidator: Add basic validator with tests.
authorlain <lain@soykaf.club>
Tue, 11 Aug 2020 13:13:07 +0000 (15:13 +0200)
committerlain <lain@soykaf.club>
Tue, 11 Aug 2020 13:13:07 +0000 (15:13 +0200)
lib/pleroma/web/activity_pub/builder.ex
lib/pleroma/web/activity_pub/object_validator.ex
lib/pleroma/web/activity_pub/object_validators/accept_validator.ex [new file with mode: 0644]
test/web/activity_pub/object_validators/accept_validation_test.exs [new file with mode: 0644]

index 1b4c421b880a38160062e8d4b13367c20e5be6b3..e1f88e6cc926c7b0ab864663ec25173eee66faf6 100644 (file)
@@ -14,6 +14,19 @@ defmodule Pleroma.Web.ActivityPub.Builder do
 
   require Pleroma.Constants
 
+  @spec accept(User.t(), Activity.t()) :: {:ok, map(), keyword()}
+  def accept(actor, accepted_activity) do
+    data = %{
+      "id" => Utils.generate_activity_id(),
+      "actor" => actor.ap_id,
+      "type" => "Accept",
+      "object" => accepted_activity.data["id"],
+      "to" => [accepted_activity.actor]
+    }
+
+    {:ok, data, []}
+  end
+
   @spec follow(User.t(), User.t()) :: {:ok, map(), keyword()}
   def follow(follower, followed) do
     data = %{
index e1114a44d952f30d23d46d9273d4a57194e03012..d9dd2bc309cdd44ff06c677133b93f234d390638 100644 (file)
@@ -13,6 +13,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
   alias Pleroma.EctoType.ActivityPub.ObjectValidators
   alias Pleroma.Object
   alias Pleroma.User
+  alias Pleroma.Web.ActivityPub.ObjectValidators.AcceptValidator
   alias Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator
   alias Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator
   alias Pleroma.Web.ActivityPub.ObjectValidators.BlockValidator
@@ -30,6 +31,16 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
   @spec validate(map(), keyword()) :: {:ok, map(), keyword()} | {:error, any()}
   def validate(object, meta)
 
+  def validate(%{"type" => "Accept"} = object, meta) do
+    with {:ok, object} <-
+           object
+           |> AcceptValidator.cast_and_validate()
+           |> Ecto.Changeset.apply_action(:insert) do
+      object = stringify_keys(object)
+      {:ok, object, meta}
+    end
+  end
+
   def validate(%{"type" => "Follow"} = object, meta) do
     with {:ok, object} <-
            object
diff --git a/lib/pleroma/web/activity_pub/object_validators/accept_validator.ex b/lib/pleroma/web/activity_pub/object_validators/accept_validator.ex
new file mode 100644 (file)
index 0000000..b81e078
--- /dev/null
@@ -0,0 +1,42 @@
+# 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.AcceptValidator do
+  use Ecto.Schema
+
+  alias Pleroma.EctoType.ActivityPub.ObjectValidators
+
+  import Ecto.Changeset
+  import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
+
+  @primary_key false
+
+  embedded_schema do
+    field(:id, ObjectValidators.ObjectID, primary_key: true)
+    field(:type, :string)
+    field(:object, ObjectValidators.ObjectID)
+    field(:actor, ObjectValidators.ObjectID)
+    field(:to, ObjectValidators.Recipients, default: [])
+    field(:cc, ObjectValidators.Recipients, default: [])
+  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, ["Accept"])
+    |> validate_actor_presence()
+    |> validate_object_presence()
+  end
+
+  def cast_and_validate(data) do
+    data
+    |> cast_data
+    |> validate_data
+  end
+end
diff --git a/test/web/activity_pub/object_validators/accept_validation_test.exs b/test/web/activity_pub/object_validators/accept_validation_test.exs
new file mode 100644 (file)
index 0000000..7f5dc14
--- /dev/null
@@ -0,0 +1,44 @@
+# 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.AcceptValidationTest do
+  use Pleroma.DataCase
+  alias Pleroma.Web.ActivityPub.Builder
+  alias Pleroma.Web.ActivityPub.Pipeline
+  alias Pleroma.Web.ActivityPub.ObjectValidator
+
+  import Pleroma.Factory
+
+  setup do
+    follower = insert(:user)
+    followed = insert(:user, local: false)
+
+    {:ok, follow_data, _} = Builder.follow(follower, followed)
+    {:ok, follow_activity, _} = Pipeline.common_pipeline(follow_data, local: true)
+
+    {:ok, accept_data, _} = Builder.accept(followed, follow_activity)
+
+    %{accept_data: accept_data, followed: followed}
+  end
+
+  test "it validates a basic 'accept'", %{accept_data: accept_data} do
+    assert {:ok, _, _} = ObjectValidator.validate(accept_data, [])
+  end
+
+  test "it fails when the actor doesn't exist", %{accept_data: accept_data} do
+    accept_data =
+      accept_data
+      |> Map.put("actor", "https://gensokyo.2hu/users/raymoo")
+
+    assert {:error, _} = ObjectValidator.validate(accept_data, [])
+  end
+
+  test "it fails when the accepted activity doesn't exist", %{accept_data: accept_data} do
+    accept_data =
+      accept_data
+      |> Map.put("object", "https://gensokyo.2hu/users/raymoo/follows/1")
+
+    assert {:error, _} = ObjectValidator.validate(accept_data, [])
+  end
+end