bugfix/follow-state (#104)
authorfloatingghost <hannah@coffee-and-dreams.uk>
Sat, 23 Jul 2022 18:58:45 +0000 (18:58 +0000)
committerFloatingGhost <hannah@coffee-and-dreams.uk>
Sat, 23 Jul 2022 19:01:48 +0000 (20:01 +0100)
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/104

lib/mix/tasks/pleroma/user.ex
lib/pleroma/user.ex
test/pleroma/web/common_api_test.exs

index f8c6d57812753610532e273d6707b0eba9e67bd7..8972d4cfb927d60ac2aa51e0a98493571e310cfa 100644 (file)
@@ -487,6 +487,38 @@ defmodule Mix.Tasks.Pleroma.User do
     |> Stream.run()
   end
 
+  def run(["fix_follow_state", local_user, remote_user]) do
+    start_pleroma()
+
+    with {:local, %User{} = local} <- {:local, User.get_by_nickname(local_user)},
+         {:remote, %User{} = remote} <- {:remote, User.get_by_nickname(remote_user)},
+         {:follow_data, %{data: %{"state" => request_state}}} <-
+           {:follow_data, Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(local, remote)} do
+      calculated_state = User.following?(local, remote)
+
+      shell_info(
+        "Request state is #{request_state}, vs calculated state of following=#{calculated_state}"
+      )
+
+      if calculated_state == false && request_state == "accept" do
+        shell_info("Discrepancy found, fixing")
+        Pleroma.Web.CommonAPI.reject_follow_request(local, remote)
+        shell_info("Relationship fixed")
+      else
+        shell_info("No discrepancy found")
+      end
+    else
+      {:local, _} ->
+        shell_error("No local user #{local_user}")
+
+      {:remote, _} ->
+        shell_error("No remote user #{remote_user}")
+
+      {:follow_data, _} ->
+        shell_error("No follow data for #{local_user} and #{remote_user}")
+    end
+  end
+
   defp set_moderator(user, value) do
     {:ok, user} =
       user
index b256c87e1f7d36047488e2929fe03c534e9dd79c..3845353770413ceac21b069a7de815423b88f88c 100644 (file)
@@ -1502,13 +1502,19 @@ defmodule Pleroma.User do
         blocker
       end
 
-    # clear any requested follows as well
+    # clear any requested follows from both sides as well
     blocked =
       case CommonAPI.reject_follow_request(blocked, blocker) do
         {:ok, %User{} = updated_blocked} -> updated_blocked
         nil -> blocked
       end
 
+    blocker =
+      case CommonAPI.reject_follow_request(blocker, blocked) do
+        {:ok, %User{} = updated_blocker} -> updated_blocker
+        nil -> blocker
+      end
+
     unsubscribe(blocked, blocker)
 
     unfollowing_blocked = Config.get([:activitypub, :unfollow_blocked], true)
index 20870bdd70ed87b813ea25ba3b4a522fc18d5718..c92c4ec8811ab8b264dd1b93dbe77542e516f1b3 100644 (file)
@@ -61,9 +61,11 @@ defmodule Pleroma.Web.CommonAPITest do
   describe "blocking" do
     setup do
       blocker = insert(:user)
-      blocked = insert(:user)
-      User.follow(blocker, blocked)
-      User.follow(blocked, blocker)
+      blocked = insert(:user, local: false)
+      CommonAPI.follow(blocker, blocked)
+      CommonAPI.follow(blocked, blocker)
+      CommonAPI.accept_follow_request(blocker, blocked)
+      CommonAPI.accept_follow_request(blocked, blocked)
       %{blocker: blocker, blocked: blocked}
     end
 
@@ -72,6 +74,9 @@ defmodule Pleroma.Web.CommonAPITest do
 
       with_mock Pleroma.Web.Federator,
         publish: fn _ -> nil end do
+        assert User.get_follow_state(blocker, blocked) == :follow_accept
+        refute is_nil(Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(blocker, blocked))
+
         assert {:ok, block} = CommonAPI.block(blocker, blocked)
 
         assert block.local
@@ -79,6 +84,11 @@ defmodule Pleroma.Web.CommonAPITest do
         refute User.following?(blocker, blocked)
         refute User.following?(blocked, blocker)
 
+        refute User.get_follow_state(blocker, blocked)
+
+        assert %{data: %{"state" => "reject"}} =
+                 Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(blocker, blocked)
+
         assert called(Pleroma.Web.Federator.publish(block))
       end
     end