Add `allow_following_move` setting to User
authorEgor Kislitsyn <egor@kislitsyn.com>
Tue, 12 Nov 2019 11:36:50 +0000 (18:36 +0700)
committerEgor Kislitsyn <egor@kislitsyn.com>
Tue, 12 Nov 2019 11:45:28 +0000 (18:45 +0700)
docs/API/differences_in_mastoapi_responses.md
lib/pleroma/following_relationship.ex
lib/pleroma/user.ex
lib/pleroma/web/mastodon_api/controllers/account_controller.ex
lib/pleroma/web/mastodon_api/views/account_view.ex
priv/repo/migrations/20191025081729_add_also_known_as_to_users.exs [deleted file]
priv/repo/migrations/20191025081729_add_move_support_to_users.exs [new file with mode: 0644]
test/web/activity_pub/activity_pub_test.exs
test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs
test/web/mastodon_api/views/account_view_test.exs

index aca0f5e0e9d01c1ec43398778a0feaedb1fea72f..41965f872bb4bae24d705e71073a49788368954b 100644 (file)
@@ -57,6 +57,7 @@ Has these additional fields under the `pleroma` object:
 - `settings_store`: A generic map of settings for frontends. Opaque to the backend. Only returned in `verify_credentials` and `update_credentials`
 - `chat_token`: The token needed for Pleroma chat. Only returned in `verify_credentials`
 - `deactivated`: boolean, true when the user is deactivated
+- `allow_following_move`: boolean, true when the user allows automatically follow moved following accounts
 - `unread_conversation_count`: The count of unread conversations. Only returned to the account owner.
 
 ### Source
@@ -130,6 +131,7 @@ Additional parameters can be added to the JSON body/Form data:
 - `default_scope` - the scope returned under `privacy` key in Source subentity
 - `pleroma_settings_store` - Opaque user settings to be saved on the backend.
 - `skip_thread_containment` - if true, skip filtering out broken threads
+- `allow_following_move` - if true, allows automatically follow moved following accounts
 - `pleroma_background_image` - sets the background image of the user.
 
 ### Pleroma Settings Store
index 2f89eb4cf6ccdbe5fa945f888e18cc59780c6c42..40538f7bf17586bd557f0522bcd61f5c94b91f76 100644 (file)
@@ -109,26 +109,20 @@ defmodule Pleroma.FollowingRelationship do
   end
 
   def move_following(origin, target) do
-    following_relationships =
-      __MODULE__
-      |> where(following_id: ^origin.id)
-      |> preload([:follower])
-      |> limit(50)
-      |> Repo.all()
-
-    case following_relationships do
-      [] ->
-        :ok
-
-      following_relationships ->
-        Enum.each(following_relationships, fn following_relationship ->
-          Repo.transaction(fn ->
-            Repo.delete(following_relationship)
-            User.follow(following_relationship.follower, target)
-          end)
-        end)
-
-        move_following(origin, target)
+    __MODULE__
+    |> join(:inner, [r], f in assoc(r, :follower))
+    |> where(following_id: ^origin.id)
+    |> where([r, f], f.allow_following_move == true)
+    |> limit(50)
+    |> preload([:follower])
+    |> Repo.all()
+    |> Enum.map(fn following_relationship ->
+      Repo.delete(following_relationship)
+      Pleroma.Web.CommonAPI.follow(following_relationship.follower, target)
+    end)
+    |> case do
+      [] -> :ok
+      _ -> move_following(origin, target)
     end
   end
 end
index 8715b37de66e4af9a4e9131450e84b7ad3899461..d40f6ed08062a7a1c3f0aef4c7405792cf764263 100644 (file)
@@ -104,6 +104,7 @@ defmodule Pleroma.User do
     field(:raw_fields, {:array, :map}, default: [])
     field(:discoverable, :boolean, default: false)
     field(:invisible, :boolean, default: false)
+    field(:allow_following_move, :boolean, default: true)
     field(:skip_thread_containment, :boolean, default: false)
     field(:also_known_as, {:array, :string}, default: [])
 
@@ -314,6 +315,7 @@ defmodule Pleroma.User do
         :hide_followers_count,
         :hide_follows_count,
         :hide_favorites,
+        :allow_following_move,
         :background,
         :show_role,
         :skip_thread_containment,
@@ -359,6 +361,7 @@ defmodule Pleroma.User do
         :hide_follows,
         :fields,
         :hide_followers,
+        :allow_following_move,
         :discoverable,
         :hide_followers_count,
         :hide_follows_count,
index 73fad519ecbe1259f3ab0782beaddbf818943bcc..7df7dc0974b61374bc663021970fc70b97d250a2 100644 (file)
@@ -152,6 +152,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
         :hide_favorites,
         :show_role,
         :skip_thread_containment,
+        :allow_following_move,
         :discoverable
       ]
       |> Enum.reduce(%{}, fn key, acc ->
index e30fed6102b7b16a491cfc0f6010df1570371025..7aae7d1880e5c74317743bcb85caba83d27f2c01 100644 (file)
@@ -163,6 +163,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
     |> maybe_put_chat_token(user, opts[:for], opts)
     |> maybe_put_activation_status(user, opts[:for])
     |> maybe_put_follow_requests_count(user, opts[:for])
+    |> maybe_put_allow_following_move(user, opts[:for])
     |> maybe_put_unread_conversation_count(user, opts[:for])
   end
 
@@ -239,6 +240,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
 
   defp maybe_put_notification_settings(data, _, _), do: data
 
+  defp maybe_put_allow_following_move(data, %User{id: user_id} = user, %User{id: user_id}) do
+    Kernel.put_in(data, [:pleroma, :allow_following_move], user.allow_following_move)
+  end
+
+  defp maybe_put_allow_following_move(data, _, _), do: data
+
   defp maybe_put_activation_status(data, user, %User{is_admin: true}) do
     Kernel.put_in(data, [:pleroma, :deactivated], user.deactivated)
   end
diff --git a/priv/repo/migrations/20191025081729_add_also_known_as_to_users.exs b/priv/repo/migrations/20191025081729_add_also_known_as_to_users.exs
deleted file mode 100644 (file)
index 3d9e0a3..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-defmodule Pleroma.Repo.Migrations.AddAlsoKnownAsToUsers do
-  use Ecto.Migration
-
-  def change do
-    alter table(:users) do
-      add(:also_known_as, {:array, :string}, default: [])
-    end
-  end
-end
diff --git a/priv/repo/migrations/20191025081729_add_move_support_to_users.exs b/priv/repo/migrations/20191025081729_add_move_support_to_users.exs
new file mode 100644 (file)
index 0000000..580b9eb
--- /dev/null
@@ -0,0 +1,10 @@
+defmodule Pleroma.Repo.Migrations.AddMoveSupportToUsers do
+  use Ecto.Migration
+
+  def change do
+    alter table(:users) do
+      add(:also_known_as, {:array, :string}, default: [], null: false)
+      add(:allow_following_move, :boolean, default: true, null: false)
+    end
+  end
+end
index 3f79593e5548fe53b339f0e8caa85439fa7bda1f..6c5e5d38e69fea2b3a7b47c2af9e5caaaa3378d5 100644 (file)
@@ -1428,10 +1428,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       %{ap_id: old_ap_id} = old_user = insert(:user)
       %{ap_id: new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id])
       follower = insert(:user)
+      follower_move_opted_out = insert(:user, allow_following_move: false)
 
       User.follow(follower, old_user)
+      User.follow(follower_move_opted_out, old_user)
 
       assert User.following?(follower, old_user)
+      assert User.following?(follower_move_opted_out, old_user)
 
       assert {:ok, activity} = ActivityPub.move(old_user, new_user)
 
@@ -1458,6 +1461,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
 
       refute User.following?(follower, old_user)
       assert User.following?(follower, new_user)
+
+      assert User.following?(follower_move_opted_out, old_user)
+      refute User.following?(follower_move_opted_out, new_user)
     end
 
     test "old user must be in the new user's `also_known_as` list" do
index 519b56d6cb64255f00ba55e34baffe74ad783012..77cfce4fa8e10fbcc0f6730f069434e75c7cf3be 100644 (file)
@@ -103,6 +103,21 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
       assert user["locked"] == true
     end
 
+    test "updates the user's allow_following_move", %{conn: conn} do
+      user = insert(:user)
+
+      assert user.allow_following_move == true
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> patch("/api/v1/accounts/update_credentials", %{allow_following_move: "false"})
+
+      assert refresh_record(user).allow_following_move == false
+      assert user = json_response(conn, 200)
+      assert user["pleroma"]["allow_following_move"] == false
+    end
+
     test "updates the user's default scope", %{conn: conn} do
       user = insert(:user)
 
index af88841ed234c5f8ba87a49312a79abe302247fe..3aa5d2e3b06af423e737b08bb349bc837093a356 100644 (file)
@@ -102,7 +102,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
     privacy = user.default_scope
 
     assert %{
-             pleroma: %{notification_settings: ^notification_settings},
+             pleroma: %{notification_settings: ^notification_settings, allow_following_move: true},
              source: %{privacy: ^privacy}
            } = AccountView.render("show.json", %{user: user, for: user})
   end