AnnounceValidator: Validate for existing announce
authorlain <lain@soykaf.club>
Mon, 18 May 2020 14:54:10 +0000 (16:54 +0200)
committerlain <lain@soykaf.club>
Mon, 18 May 2020 14:54:10 +0000 (16:54 +0200)
lib/pleroma/web/activity_pub/object_validators/announce_validator.ex
test/web/activity_pub/object_validator_test.exs

index fbefaf257cbaf9f2699abbb453fc440fe23366b8..158ae199d4d6ff6bd884901103680e9e1e2ea7b9 100644 (file)
@@ -6,9 +6,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator do
   use Ecto.Schema
 
   alias Pleroma.Web.ActivityPub.ObjectValidators.Types
+  alias Pleroma.Web.ActivityPub.Utils
 
-  import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
   import Ecto.Changeset
+  import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
 
   @primary_key false
 
@@ -49,5 +50,19 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator do
     |> 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
index 9313015f1984214109a16f5e149a02f3d0812a78..e24e0f913959272c2b39424645ebc334b0b0772f 100644 (file)
@@ -329,5 +329,18 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidatorTest do
 
       assert {:actor, {"can't find user", []}} in cng.errors
     end
+
+    test "returns an error if the actor already announced the object", %{
+      valid_announce: valid_announce,
+      announcer: announcer,
+      post_activity: post_activity
+    } do
+      _announce = CommonAPI.repeat(post_activity.id, announcer)
+
+      {:error, cng} = ObjectValidator.validate(valid_announce, [])
+
+      assert {:actor, {"already announced this object", []}} in cng.errors
+      assert {:object, {"already announced by this actor", []}} in cng.errors
+    end
   end
 end