Add migration to migrate existing local legacy keypairs to new table (#39686)

This commit is contained in:
Claire
2026-07-03 16:35:07 +02:00
committed by GitHub
parent f4fdbe3029
commit fbc8f5e200
3 changed files with 71 additions and 2 deletions

View File

@@ -0,0 +1,64 @@
# frozen_string_literal: true
class MigrateLocalAccountKeypairs < ActiveRecord::Migration[8.1]
disable_ddl_transaction!
class Account < ApplicationRecord
has_many :keypairs, inverse_of: :account
scope :local, -> { where(domain: nil) }
end
class Keypair < ApplicationRecord
self.inheritance_column = nil
encrypts :private_key
belongs_to :account
enum :type, {
rsa: 0,
}, validate: true
end
def up
Account.reset_column_information
Keypair.reset_column_information
Account.local.where.not(private_key: nil).in_batches do |accounts|
Keypair.upsert_all(
accounts.map do |account|
{
type: :rsa,
account_id: account.id,
local_fragment: '#main-key',
public_key: account.public_key,
private_key: account.private_key,
}
end,
unique_by: [:account_id, :local_fragment]
)
accounts.update_all(public_key: '', private_key: nil)
end
Account.reset_column_information
Keypair.reset_column_information
end
def down
Account.reset_column_information
Keypair.reset_column_information
Account.local.where(private_key: nil).find_each do |account|
keypair = account.keypairs.find_by(local_fragment: '#main-key')
next if keypair.nil?
account.update(public_key: keypair.public_key, private_key: keypair.private_key)
keypair.delete
end
Account.reset_column_information
Keypair.reset_column_information
end
end

View File

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.1].define(version: 2026_07_01_161826) do
ActiveRecord::Schema[8.1].define(version: 2026_07_02_144128) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_catalog.plpgsql"

View File

@@ -51,11 +51,16 @@ namespace :tests do
exit(1)
end
if Account.find(Account::INSTANCE_ACTOR_ID).private_key.blank?
if Account.find(Account::INSTANCE_ACTOR_ID).keypair.blank?
puts 'Instance actor does not have a private key'
exit(1)
end
if Account.local.where.not(private_key: nil).exists?
puts 'Private keys not properly migrated'
exit(1)
end
unless Account.find_by(username: 'user', domain: nil).custom_filters.map { |filter| filter.keywords.pluck(:keyword) } == [['test'], ['take']]
puts 'CustomFilterKeyword records not created as expected'
exit(1)