]> cat aescling's git repositories - mastodon.git/commitdiff
Fix account merging in maintenance script (#15264)
authorThibG <thib@sitedethib.com>
Fri, 4 Dec 2020 01:23:51 +0000 (02:23 +0100)
committerGitHub <noreply@github.com>
Fri, 4 Dec 2020 01:23:51 +0000 (02:23 +0100)
Also include AccountNote and AccountDeletionRequest to the list of classes
needing to be reassigned the merged account.

app/models/concerns/account_merging.rb
lib/mastodon/maintenance_cli.rb

index 45050c269a33d9850874f1d1d46e88cdd4ced22a..c3b7018f2c3db57aa04a14d96070465d8ece227a 100644 (file)
@@ -15,7 +15,7 @@ module AccountMerging
       Status, StatusPin, MediaAttachment, Poll, Report, Tombstone, Favourite,
       Follow, FollowRequest, Block, Mute, AccountIdentityProof,
       AccountModerationNote, AccountPin, AccountStat, ListAccount,
-      PollVote, Mention
+      PollVote, Mention, AccountDeletionRequest, AccountNote
     ]
 
     owned_classes.each do |klass|
@@ -28,7 +28,10 @@ module AccountMerging
       end
     end
 
-    target_classes = [Follow, FollowRequest, Block, Mute, AccountModerationNote, AccountPin]
+    target_classes = [
+      Follow, FollowRequest, Block, Mute, AccountModerationNote, AccountPin,
+      AccountNote
+    ]
 
     target_classes.each do |klass|
       klass.where(target_account_id: other_account.id).find_each do |record|
index 547238ec6ed3a8147637cf7d47d947a82a0ea0f7..99d13f43da4b45c143b4e7a44909f009267476db 100644 (file)
@@ -55,8 +55,8 @@ module Mastodon
       belongs_to :account, inverse_of: :account_stat
     end
 
+    # Dummy class, to make migration possible across version changes
     class Account < ApplicationRecord
-      # Dummy class, to make migration possible across version changes
       has_one :user, inverse_of: :account
       has_one :account_stat, inverse_of: :account
 
@@ -69,6 +69,49 @@ module Mastodon
       def acct
         local? ? username : "#{username}@#{domain}"
       end
+
+      # This is a duplicate of the AccountMerging concern because we need it to
+      # be independent from code version.
+      def merge_with!(other_account)
+        # Since it's the same remote resource, the remote resource likely
+        # already believes we are following/blocking, so it's safe to
+        # re-attribute the relationships too. However, during the presence
+        # of the index bug users could have *also* followed the reference
+        # account already, therefore mass update will not work and we need
+        # to check for (and skip past) uniqueness errors
+
+        owned_classes = [
+          Status, StatusPin, MediaAttachment, Poll, Report, Tombstone, Favourite,
+          Follow, FollowRequest, Block, Mute, AccountIdentityProof,
+          AccountModerationNote, AccountPin, AccountStat, ListAccount,
+          PollVote, Mention
+        ]
+        owned_classes << AccountDeletionRequest if ActiveRecord::Base.connection.table_exists?(:account_deletion_requests)
+        owned_classes << AccountNote if ActiveRecord::Base.connection.table_exists?(:account_notes)
+
+        owned_classes.each do |klass|
+          klass.where(account_id: other_account.id).find_each do |record|
+            begin
+              record.update_attribute(:account_id, id)
+            rescue ActiveRecord::RecordNotUnique
+              next
+            end
+          end
+        end
+
+        target_classes = [Follow, FollowRequest, Block, Mute, AccountModerationNote, AccountPin]
+        target_classes << AccountNote if ActiveRecord::Base.connection.table_exists?(:account_notes)
+
+        target_classes.each do |klass|
+          klass.where(target_account_id: other_account.id).find_each do |record|
+            begin
+              record.update_attribute(:target_account_id, id)
+            rescue ActiveRecord::RecordNotUnique
+              next
+            end
+          end
+        end
+      end
     end
 
     class User < ApplicationRecord