From 18edc299b262974d3acb9d6f9c3758629b2c0968 Mon Sep 17 00:00:00 2001
From: Roger Braun <roger@rogerbraun.net>
Date: Sun, 30 Apr 2017 12:36:47 +0200
Subject: [PATCH] Handle duplicates.

---
 lib/pleroma/web/ostatus/ostatus.ex | 15 +++++++++------
 test/web/ostatus/ostatus_test.exs  |  6 ++++++
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex
index 6f169af73..16b6ac421 100644
--- a/lib/pleroma/web/ostatus/ostatus.ex
+++ b/lib/pleroma/web/ostatus/ostatus.ex
@@ -3,7 +3,7 @@ defmodule Pleroma.Web.OStatus do
   import Pleroma.Web.XML
   require Logger
 
-  alias Pleroma.{Repo, User, Web}
+  alias Pleroma.{Repo, User, Web, Object}
   alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.{WebFinger, Websub}
 
@@ -28,11 +28,9 @@ def handle_incoming(xml_string) do
 
       case object_type do
         'http://activitystrea.ms/schema/1.0/note' ->
-          {:ok, activity} = handle_note(entry, doc)
-          activity
+          with {:ok, activity} <- handle_note(entry, doc), do: activity
         'http://activitystrea.ms/schema/1.0/comment' ->
-          {:ok, activity} = handle_note(entry, doc)
-          activity
+          with {:ok, activity} <- handle_note(entry, doc), do: activity
         _ ->
           Logger.error("Couldn't parse incoming document")
           nil
@@ -86,7 +84,12 @@ def handle_note(entry, doc \\ nil) do
       object
     end
 
-    ActivityPub.create(to, actor, context, object, %{}, date)
+    # TODO: Bail out sooner and use transaction.
+    if Object.get_by_ap_id(id) do
+      {:error, "duplicate activity"}
+    else
+      ActivityPub.create(to, actor, context, object, %{}, date)
+    end
   end
 
   def find_or_make_user(uri) do
diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs
index 3edd39911..07073a40d 100644
--- a/test/web/ostatus/ostatus_test.exs
+++ b/test/web/ostatus/ostatus_test.exs
@@ -2,6 +2,12 @@ defmodule Pleroma.Web.OStatusTest do
   use Pleroma.DataCase
   alias Pleroma.Web.OStatus
 
+  test "don't insert create notes twice" do
+    incoming = File.read!("test/fixtures/incoming_note_activity.xml")
+    {:ok, [_activity]} = OStatus.handle_incoming(incoming)
+    assert {:ok, [{:error, "duplicate activity"}]} == OStatus.handle_incoming(incoming)
+  end
+
   test "handle incoming note - GS, Salmon" do
     incoming = File.read!("test/fixtures/incoming_note_activity.xml")
     {:ok, [activity]} = OStatus.handle_incoming(incoming)