diff --git a/app/models/mixins/miq_web_server_runner_mixin.rb b/app/models/mixins/miq_web_server_runner_mixin.rb index 5bcb9c54e48..5b4ed615aee 100644 --- a/app/models/mixins/miq_web_server_runner_mixin.rb +++ b/app/models/mixins/miq_web_server_runner_mixin.rb @@ -12,7 +12,6 @@ def run # The heartbeating will be done in a separate thread worker_thread = Thread.new { super } - worker.class.configure_secret_token start_rails_server(worker.rails_server_options) # when puma exits allow the heartbeat thread to exit cleanly using #do_exit diff --git a/app/models/mixins/miq_web_server_worker_mixin.rb b/app/models/mixins/miq_web_server_worker_mixin.rb index 9a3459be310..8bc88696c7c 100644 --- a/app/models/mixins/miq_web_server_worker_mixin.rb +++ b/app/models/mixins/miq_web_server_worker_mixin.rb @@ -18,25 +18,8 @@ def binding_address BINDING_ADDRESS end - def preload_for_console - configure_secret_token(SecureRandom.hex(64)) - end - def preload_for_worker_role raise "Expected database to be seeded via `rake db:seed`." unless EvmDatabase.seeded_primordially? - - configure_secret_token - end - - def configure_secret_token(token = MiqDatabase.first.session_secret_token) - return if Rails.application.config.secret_key_base - - Rails.application.config.secret_key_base = token - - # To set a secret token after the Rails.application is initialized, - # we need to reset the secrets since they are cached: - # https://github.com/rails/rails/blob/7-0-stable/railties/lib/rails/application.rb#L392-L404 - Rails.application.secrets = nil if Rails.version < "7.1" end def rails_server diff --git a/config/application.rb b/config/application.rb index 2a875913791..b5f24677ab1 100644 --- a/config/application.rb +++ b/config/application.rb @@ -209,6 +209,11 @@ class Application < Rails::Application end end + # Run after code is eager loaded so we can autoload MiqDatabase and ApplicationRecord + initializer :init_secret_token, :after => :eager_load! do + Vmdb::Initializer.init_secret_token + end + config.after_initialize do Vmdb::Initializer.init ActiveRecord::Base.connection_pool.release_connection diff --git a/lib/vmdb/initializer.rb b/lib/vmdb/initializer.rb index 1eae159f817..816bf571f95 100644 --- a/lib/vmdb/initializer.rb +++ b/lib/vmdb/initializer.rb @@ -12,11 +12,18 @@ def self.init MiqServer.my_server.starting_server_record MiqServer.my_server.update(:status => "started") end + end + + def self.init_secret_token + return if Rails.application.config.secret_key_base - # Rails console needs session store configured - if defined?(Rails::Console) - MiqUiWorker.preload_for_console + token = if ActiveRecord::Base.connectable? && MiqDatabase.table_exists? && MiqDatabase.any? + MiqDatabase.first.session_secret_token + else + SecureRandom.hex(64) end + + Rails.application.config.secret_key_base = token end private_class_method def self.log_db_connectable diff --git a/spec/lib/vmdb/initializer_spec.rb b/spec/lib/vmdb/initializer_spec.rb new file mode 100644 index 00000000000..5d992d9feff --- /dev/null +++ b/spec/lib/vmdb/initializer_spec.rb @@ -0,0 +1,41 @@ +RSpec.describe Vmdb::Initializer do + describe ".init_secret_token" do + before do + @token = Rails.application.secret_key_base + end + + after do + Rails.application.config.secret_key_base = @token + Rails.application.secrets = nil + end + + it "defaults to MiqDatabase session_secret_token" do + MiqDatabase.seed + Rails.application.config.secret_key_base = nil + Rails.application.secrets = nil + + described_class.init_secret_token + expect(Rails.application.secret_key_base).to eq(MiqDatabase.first.session_secret_token) + expect(Rails.application.config.secret_key_base).to eq(MiqDatabase.first.session_secret_token) + end + + it "uses random hex when MiqDatabase isn't seeded" do + Rails.application.config.secret_key_base = nil + Rails.application.secrets = nil + + described_class.init_secret_token + expect(Rails.application.secret_key_base).to match(/^\h{128}$/) + expect(Rails.application.config.secret_key_base).to match(/^\h{128}$/) + end + + it "does not reset secrets when token already configured" do + existing_value = SecureRandom.hex(64) + Rails.application.config.secret_key_base = existing_value + Rails.application.secrets = nil + + described_class.init_secret_token + expect(Rails.application.secret_key_base).to eq(existing_value) + expect(Rails.application.config.secret_key_base).to eq(existing_value) + end + end +end diff --git a/spec/models/miq_ui_worker_spec.rb b/spec/models/miq_ui_worker_spec.rb index 89a2ddd1852..43e0ade2e86 100644 --- a/spec/models/miq_ui_worker_spec.rb +++ b/spec/models/miq_ui_worker_spec.rb @@ -53,7 +53,6 @@ it "#preload_for_worker_role autoloads api collection classes and descendants" do allow(EvmDatabase).to receive(:seeded_primordially?).and_return(true) - expect(MiqUiWorker).to receive(:configure_secret_token) MiqUiWorker.preload_for_worker_role expect(defined?(ServiceAnsibleTower)).to be_truthy end diff --git a/spec/models/miq_web_service_worker_spec.rb b/spec/models/miq_web_service_worker_spec.rb index 4b284f0bbd0..ae050db6804 100644 --- a/spec/models/miq_web_service_worker_spec.rb +++ b/spec/models/miq_web_service_worker_spec.rb @@ -8,7 +8,6 @@ it "preload_for_worker_role autoloads api collection classes and descendants" do allow(EvmDatabase).to receive(:seeded_primordially?).and_return(true) - expect(MiqWebServiceWorker).to receive(:configure_secret_token) MiqWebServiceWorker.preload_for_worker_role expect(defined?(ServiceAnsibleTower)).to be_truthy end diff --git a/spec/models/mixins/miq_web_server_worker_mixin_spec.rb b/spec/models/mixins/miq_web_server_worker_mixin_spec.rb index e706c66ae6e..448c4f82633 100644 --- a/spec/models/mixins/miq_web_server_worker_mixin_spec.rb +++ b/spec/models/mixins/miq_web_server_worker_mixin_spec.rb @@ -14,43 +14,6 @@ end end - before do - @token = Rails.application.secret_key_base - MiqDatabase.seed - end - - after do - Rails.application.config.secret_key_base = @token - Rails.application.secrets = nil if Rails.version < "7.1" - end - - it ".configure_secret_token defaults to MiqDatabase session_secret_token" do - Rails.application.config.secret_key_base = nil - - test_class.configure_secret_token - expect(Rails.application.secret_key_base).to eq(MiqDatabase.first.session_secret_token) - expect(Rails.application.config.secret_key_base).to eq(MiqDatabase.first.session_secret_token) - end - - it ".configure_secret_token accepts an input token" do - Rails.application.config.secret_key_base = nil - - token = SecureRandom.hex(64) - test_class.configure_secret_token(token) - expect(Rails.application.secret_key_base).to eq(token) - expect(Rails.application.config.secret_key_base).to eq(token) - end - - it ".configure_secret_token does not reset secrets when token already configured" do - existing_value = SecureRandom.hex(64) - Rails.application.config.secret_key_base = existing_value - Rails.application.secrets = nil if Rails.version < "7.1" - - test_class.configure_secret_token - expect(Rails.application.secret_key_base).to eq(existing_value) - expect(Rails.application.config.secret_key_base).to eq(existing_value) - end - it "#rails_server_options" do w = FactoryBot.create(:miq_ui_worker, :uri => "http://127.0.0.1:3000") expect(w.rails_server_options).to include(