From 0d5bce018df9c99c771daaaa1de3ab0efc0cba5c Mon Sep 17 00:00:00 2001 From: lain Date: Mon, 18 May 2020 16:54:10 +0200 Subject: [PATCH] AnnounceValidator: Validate for existing announce --- .../object_validators/announce_validator.ex | 17 ++++++++++++++++- test/web/activity_pub/object_validator_test.exs | 13 +++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/web/activity_pub/object_validators/announce_validator.ex b/lib/pleroma/web/activity_pub/object_validators/announce_validator.ex index fbefaf257..158ae199d 100644 --- a/lib/pleroma/web/activity_pub/object_validators/announce_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/announce_validator.ex @@ -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 @@ def validate_data(data_cng) 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 diff --git a/test/web/activity_pub/object_validator_test.exs b/test/web/activity_pub/object_validator_test.exs index 9313015f1..e24e0f913 100644 --- a/test/web/activity_pub/object_validator_test.exs +++ b/test/web/activity_pub/object_validator_test.exs @@ -329,5 +329,18 @@ test "returns an error if we don't have the actor", %{valid_announce: valid_anno 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