Add support for incoming remote unfollows
authorFrancis Dinh <normandy@firemail.cc>
Fri, 18 May 2018 02:15:57 +0000 (22:15 -0400)
committerFrancis Dinh <normandy@firemail.cc>
Fri, 18 May 2018 02:15:57 +0000 (22:15 -0400)
lib/pleroma/user.ex
lib/pleroma/web/activity_pub/transmogrifier.ex
test/fixtures/mastodon-unfollow-activity.json [new file with mode: 0644]
test/web/activity_pub/transmogrifier_test.exs

index 399a66787dff4bf01128bd6a9492c5242aafb656..6a8129ac84b2572432d80e2cd77d76b27cbdcd6b 100644 (file)
@@ -404,18 +404,22 @@ defmodule Pleroma.User do
       from(
         u in User,
         select_merge: %{
-          search_distance: fragment(
-            "? <-> (? || ?)",
-            ^query,
-            u.nickname,
-            u.name
-          )}
+          search_distance:
+            fragment(
+              "? <-> (? || ?)",
+              ^query,
+              u.nickname,
+              u.name
+            )
+        }
       )
 
-    q = from(s in subquery(inner),
-      order_by: s.search_distance,
-      limit: 20
-    )
+    q =
+      from(
+        s in subquery(inner),
+        order_by: s.search_distance,
+        limit: 20
+      )
 
     Repo.all(q)
   end
index 463d1e59d53d5e10ede158d8e83af56122f2df48..0bec8c4dd018711ef7f5db894c8b17cff8f403d7 100644 (file)
@@ -241,6 +241,24 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
     end
   end
 
+  def handle_incoming(
+        %{
+          "type" => "Undo",
+          "object" => %{"type" => "Follow", "object" => followed},
+          "actor" => follower,
+          "id" => id
+        } = data
+      ) do
+    with %User{local: true} = followed = User.get_cached_by_ap_id(followed),
+         %User{} = follower = User.get_or_fetch_by_ap_id(follower),
+         {:ok, activity} <- ActivityPub.unfollow(follower, followed, false) do
+      User.unfollow(follower, followed)
+      {:ok, activity}
+    else
+      e -> :error
+    end
+  end
+
   # TODO
   # Accept
   # Undo for non-Announce
diff --git a/test/fixtures/mastodon-unfollow-activity.json b/test/fixtures/mastodon-unfollow-activity.json
new file mode 100644 (file)
index 0000000..022b47a
--- /dev/null
@@ -0,0 +1,33 @@
+{
+    "@context": [
+            "https://www.w3.org/ns/activitystreams",
+            "https://w3id.org/security/v1",
+            {
+              "toot": "http://joinmastodon.org/ns#",
+              "sensitive": "as:sensitive",
+              "ostatus": "http://ostatus.org#",
+              "movedTo": "as:movedTo",
+              "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
+              "inReplyToAtomUri": "ostatus:inReplyToAtomUri",
+              "conversation": "ostatus:conversation",
+              "atomUri": "ostatus:atomUri",
+              "Hashtag": "as:Hashtag",
+              "Emoji": "toot:Emoji"
+            }
+          ],
+    "signature": {
+        "type": "RsaSignature2017",
+        "signatureValue": "Kn1/UkAQGJVaXBfWLAHcnwHg8YMAUqlEaBuYLazAG+pz5hqivsyrBmPV186Xzr+B4ZLExA9+SnOoNx/GOz4hBm0kAmukNSILAsUd84tcJ2yT9zc1RKtembK4WiwOw7li0+maeDN0HaB6t+6eTqsCWmtiZpprhXD8V1GGT8yG7X24fQ9oFGn+ng7lasbcCC0988Y1eGqNe7KryxcPuQz57YkDapvtONzk8gyLTkZMV4De93MyRHq6GVjQVIgtiYabQAxrX6Q8C+4P/jQoqdWJHEe+MY5JKyNaT/hMPt2Md1ok9fZQBGHlErk22/zy8bSN19GdG09HmIysBUHRYpBLig==",
+        "creator": "http://mastodon.example.org/users/admin#main-key",
+        "created": "2018-02-17T13:29:31Z"
+      },
+    "type": "Undo",
+    "object": {
+      "type": "Follow", 
+      "object": "http://localtesting.pleroma.lol/users/lain",
+      "nickname": "lain",
+      "id": "http://mastodon.example.org/users/admin#follows/2",
+      "actor": "http://mastodon.example.org/users/admin" 
+    },
+    "actor": "http://mastodon.example.org/users/admin"
+}
index a3408da9db58a95983585a645879d68b6b5fb04d..8ed7147f4eded461ddb2fdbe7ff72956f332c1da 100644 (file)
@@ -260,6 +260,30 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       assert data["object"]["id"] ==
                "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
     end
+
+    test "it works for incomming unfollows" do
+      user = insert(:user)
+
+      follow_data =
+        File.read!("test/fixtures/mastodon-follow-activity.json")
+        |> Poison.decode!()
+        |> Map.put("object", user.ap_id)
+
+      {:ok, %Activity{data: _, local: false}} = Transmogrifier.handle_incoming(follow_data)
+
+      data =
+        File.read!("test/fixtures/mastodon-unfollow-activity.json")
+        |> Poison.decode!()
+        |> Map.put("object", follow_data)
+
+      {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
+
+      assert data["type"] == "Undo"
+      assert data["object"]["type"] == "Follow"
+      assert data["actor"] == "http://mastodon.example.org/users/admin"
+
+      refute User.following?(User.get_by_ap_id(data["actor"]), user)
+    end
   end
 
   describe "prepare outgoing" do