From 33cd80d69c1491ff70ce9191113763c76cb7e6b7 Mon Sep 17 00:00:00 2001
From: Claire <claire.github-309c@sitedethib.com>
Date: Tue, 26 Apr 2022 21:22:09 +0200
Subject: [PATCH] Fix instance actor being incorrectly created when running
 migrations (#18109)

* Add migration test about instance actor key

* Fix old migration

* Work around incorrect database state
---
 app/models/account.rb                           | 6 ++++++
 app/models/concerns/account_finder_concern.rb   | 2 +-
 db/migrate/20190715164535_add_instance_actor.rb | 8 ++++++++
 lib/tasks/tests.rake                            | 5 +++++
 4 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/app/models/account.rb b/app/models/account.rb
index a8c5df208..7b460b054 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -559,6 +559,12 @@ class Account < ApplicationRecord
   before_validation :prepare_username, on: :create
   before_destroy :clean_feed_manager
 
+  def ensure_keys!
+    return unless local? && private_key.blank? && public_key.blank?
+    generate_keys
+    save!
+  end
+
   private
 
   def prepare_contents
diff --git a/app/models/concerns/account_finder_concern.rb b/app/models/concerns/account_finder_concern.rb
index 0dadddad1..e8b804934 100644
--- a/app/models/concerns/account_finder_concern.rb
+++ b/app/models/concerns/account_finder_concern.rb
@@ -13,7 +13,7 @@ module AccountFinderConcern
     end
 
     def representative
-      Account.find(-99)
+      Account.find(-99).tap(&:ensure_keys!)
     rescue ActiveRecord::RecordNotFound
       Account.create!(id: -99, actor_type: 'Application', locked: true, username: Rails.configuration.x.local_domain)
     end
diff --git a/db/migrate/20190715164535_add_instance_actor.rb b/db/migrate/20190715164535_add_instance_actor.rb
index 8c0301d69..0ae53199a 100644
--- a/db/migrate/20190715164535_add_instance_actor.rb
+++ b/db/migrate/20190715164535_add_instance_actor.rb
@@ -2,6 +2,14 @@ class AddInstanceActor < ActiveRecord::Migration[5.2]
   class Account < ApplicationRecord
     # Dummy class, to make migration possible across version changes
     validates :username, uniqueness: { scope: :domain, case_sensitive: false }
+
+    before_create :generate_keys
+
+    def generate_keys
+      keypair = OpenSSL::PKey::RSA.new(2048)
+      self.private_key = keypair.to_pem
+      self.public_key  = keypair.public_key.to_pem
+    end
   end
 
   def up
diff --git a/lib/tasks/tests.rake b/lib/tasks/tests.rake
index 8082f32fb..0f3b44a74 100644
--- a/lib/tasks/tests.rake
+++ b/lib/tasks/tests.rake
@@ -33,6 +33,11 @@ namespace :tests do
         puts 'AccountConversation records not created as expected'
         exit(1)
       end
+
+      if Account.find(-99).private_key.blank?
+        puts 'Instance actor does not have a private key'
+        exit(1)
+      end
     end
 
     desc 'Populate the database with test data for 2.4.0'