From 9474d35a3c4e78805496f447284259b65a4b1fef Mon Sep 17 00:00:00 2001 From: Maxim Lapis Date: Thu, 4 Sep 2025 17:32:53 +0200 Subject: [PATCH] Update existing code to use account_secrets table --- app/models/account.rb | 16 ++++-- .../activitypub/process_account_service.rb | 1 - lib/mastodon/cli/accounts.rb | 5 +- lib/tasks/tests.rake | 54 ++++++++++++------- 4 files changed, 50 insertions(+), 26 deletions(-) diff --git a/app/models/account.rb b/app/models/account.rb index 529224248b5..6b1b28d92ce 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -271,7 +271,7 @@ class Account < ApplicationRecord end def keypair - @keypair ||= OpenSSL::PKey::RSA.new(private_key || public_key) + @keypair ||= OpenSSL::PKey::RSA.new(account_secret.private_key || public_key) end def tags_as_strings=(tag_names) @@ -445,7 +445,7 @@ class Account < ApplicationRecord before_destroy :clean_feed_manager def ensure_keys! - return unless local? && private_key.blank? && public_key.blank? + return unless local? && (account_secret.nil? || account_secret.private_key.blank?) && public_key.blank? generate_keys save! @@ -459,11 +459,17 @@ class Account < ApplicationRecord end def generate_keys - return unless local? && private_key.blank? && public_key.blank? + return unless local? && (account_secret.nil? || account_secret.private_key.blank?) && public_key.blank? keypair = OpenSSL::PKey::RSA.new(2048) - self.private_key = keypair.to_pem - self.public_key = keypair.public_key.to_pem + + if account_secret.nil? + create_account_secret!(private_key: keypair.to_pem) + else + account_secret.update!(private_key: keypair.to_pem) + end + + self.public_key = keypair.public_key.to_pem end def normalize_domain diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index 201f7513b9b..dc0d236f075 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -74,7 +74,6 @@ class ActivityPub::ProcessAccountService < BaseService @account.protocol = :activitypub @account.username = @username @account.domain = @domain - @account.private_key = nil @account.suspended_at = domain_block.created_at if auto_suspend? @account.suspension_origin = :local if auto_suspend? @account.silenced_at = domain_block.created_at if auto_silence? diff --git a/lib/mastodon/cli/accounts.rb b/lib/mastodon/cli/accounts.rb index 1b33f56055a..0fe20daa196 100644 --- a/lib/mastodon/cli/accounts.rb +++ b/lib/mastodon/cli/accounts.rb @@ -614,9 +614,10 @@ module Mastodon::CLI def rotate_keys_for_account(account, delay = 0) fail_with_message 'No such account' if account.nil? - old_key = account.private_key + old_key = account.account_secret.private_key new_key = OpenSSL::PKey::RSA.new(2048) - account.update(private_key: new_key.to_pem, public_key: new_key.public_key.to_pem) + account.account_secret.update!(private_key: new_key.to_pem) + account.update!(public_key: new_key.public_key.to_pem) ActivityPub::UpdateDistributionWorker.perform_in(delay, account.id, { 'sign_with' => old_key }) end end diff --git a/lib/tasks/tests.rake b/lib/tasks/tests.rake index 9385e390ded..b16fa932850 100644 --- a/lib/tasks/tests.rake +++ b/lib/tasks/tests.rake @@ -51,7 +51,7 @@ namespace :tests do exit(1) end - if Account.find(Account::INSTANCE_ACTOR_ID).private_key.blank? + if Account.find(Account::INSTANCE_ACTOR_ID).account_secret.private_key.blank? puts 'Instance actor does not have a private key' exit(1) end @@ -236,10 +236,16 @@ namespace :tests do (4, 'User', 1, 'trends', E'--- false\n', now(), now()); INSERT INTO "accounts" - (id, username, domain, private_key, public_key, created_at, updated_at) + (id, username, domain, public_key, created_at, updated_at) VALUES - (10, 'kmruser', NULL, #{user_private_key}, #{user_public_key}, now(), now()), - (11, 'qcuser', NULL, #{user_private_key}, #{user_public_key}, now(), now()); + (10, 'kmruser', NULL, #{user_public_key}, now(), now()), + (11, 'qcuser', NULL, #{user_public_key}, now(), now()); + + INSERT INTO "account_secrets" + (account_id, private_key, created_at, updated_at) + VALUES + (10, #{user_private_key}, now(), now()), + (11, #{user_private_key}, now(), now()); INSERT INTO "users" (id, account_id, email, created_at, updated_at, admin, locale, chosen_languages) @@ -302,37 +308,49 @@ namespace :tests do -- accounts INSERT INTO "accounts" - (id, username, domain, private_key, public_key, created_at, updated_at) + (id, username, domain, public_key, created_at, updated_at) VALUES - (1, 'admin', NULL, #{admin_private_key}, #{admin_public_key}, now(), now()), - (2, 'user', NULL, #{user_private_key}, #{user_public_key}, now(), now()); + (1, 'admin', NULL, #{admin_public_key}, now(), now()), + (2, 'user', NULL, #{user_public_key}, now(), now()); + + INSERT INTO "account_secrets" + (account_id, private_key, created_at, updated_at) + VALUES + (1, #{admin_private_key}, now(), now()), + (2, #{user_private_key}, now(), now()); INSERT INTO "accounts" - (id, username, domain, private_key, public_key, created_at, updated_at, remote_url, salmon_url) + (id, username, domain, public_key, created_at, updated_at, remote_url, salmon_url) VALUES - (3, 'remote', 'remote.com', NULL, #{remote_public_key}, now(), now(), + (3, 'remote', 'remote.com', #{remote_public_key}, now(), now(), 'https://remote.com/@remote', 'https://remote.com/salmon/1'), - (4, 'Remote', 'remote.com', NULL, #{remote_public_key}, now(), now(), + (4, 'Remote', 'remote.com', #{remote_public_key}, now(), now(), 'https://remote.com/@Remote', 'https://remote.com/salmon/1'), - (5, 'REMOTE', 'Remote.com', NULL, #{remote_public_key2}, now() - interval '1 year', now() - interval '1 year', + (5, 'REMOTE', 'Remote.com', #{remote_public_key2}, now() - interval '1 year', now() - interval '1 year', 'https://remote.com/stale/@REMOTE', 'https://remote.com/stale/salmon/1'); INSERT INTO "accounts" - (id, username, domain, private_key, public_key, created_at, updated_at, protocol, inbox_url, outbox_url, followers_url) + (id, username, domain, public_key, created_at, updated_at, protocol, inbox_url, outbox_url, followers_url) VALUES - (6, 'bob', 'ActivityPub.com', NULL, #{remote_public_key_ap}, now(), now(), + (6, 'bob', 'ActivityPub.com', #{remote_public_key_ap}, now(), now(), 1, 'https://activitypub.com/users/bob/inbox', 'https://activitypub.com/users/bob/outbox', 'https://activitypub.com/users/bob/followers'); INSERT INTO "accounts" - (id, username, domain, private_key, public_key, created_at, updated_at) + (id, username, domain, public_key, created_at, updated_at) VALUES - (7, 'user', #{local_domain}, #{user_private_key}, #{user_public_key}, now(), now()), - (8, 'pt_user', NULL, #{user_private_key}, #{user_public_key}, now(), now()); + (7, 'user', #{local_domain}, #{user_public_key}, now(), now()), + (8, 'pt_user', NULL, #{user_public_key}, now(), now()); + + INSERT INTO "account_secrets" + (account_id, private_key, created_at, updated_at) + VALUES + (7, #{user_private_key}, now(), now()), + (8, #{user_private_key}, now(), now()); INSERT INTO "accounts" - (id, username, domain, private_key, public_key, created_at, updated_at, protocol, inbox_url, outbox_url, followers_url, suspended) + (id, username, domain, public_key, created_at, updated_at, protocol, inbox_url, outbox_url, followers_url, suspended) VALUES - (9, 'evil', 'activitypub.com', NULL, #{remote_public_key_ap}, now(), now(), + (9, 'evil', 'activitypub.com', #{remote_public_key_ap}, now(), now(), 1, 'https://activitypub.com/users/evil/inbox', 'https://activitypub.com/users/evil/outbox', 'https://activitypub.com/users/evil/followers', true);