Skip to content

Commit 9213a9d

Browse files
committed
Merge pull request #23351 from jrafanie/set-secret-token-globally-earlier-after-eager-load-hook
Set secret_key_base early enough for rails processes
2 parents 99489ca + e6d6cd7 commit 9213a9d

8 files changed

+56
-60
lines changed

app/models/mixins/miq_web_server_runner_mixin.rb

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ def run
1212
# The heartbeating will be done in a separate thread
1313
worker_thread = Thread.new { super }
1414

15-
worker.class.configure_secret_token
1615
start_rails_server(worker.rails_server_options)
1716

1817
# when puma exits allow the heartbeat thread to exit cleanly using #do_exit

app/models/mixins/miq_web_server_worker_mixin.rb

-17
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,8 @@ def binding_address
1818
BINDING_ADDRESS
1919
end
2020

21-
def preload_for_console
22-
configure_secret_token(SecureRandom.hex(64))
23-
end
24-
2521
def preload_for_worker_role
2622
raise "Expected database to be seeded via `rake db:seed`." unless EvmDatabase.seeded_primordially?
27-
28-
configure_secret_token
29-
end
30-
31-
def configure_secret_token(token = MiqDatabase.first.session_secret_token)
32-
return if Rails.application.config.secret_key_base
33-
34-
Rails.application.config.secret_key_base = token
35-
36-
# To set a secret token after the Rails.application is initialized,
37-
# we need to reset the secrets since they are cached:
38-
# https://github.com/rails/rails/blob/7-0-stable/railties/lib/rails/application.rb#L392-L404
39-
Rails.application.secrets = nil if Rails.version < "7.1"
4023
end
4124

4225
def rails_server

config/application.rb

+5
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ class Application < Rails::Application
209209
end
210210
end
211211

212+
# Run after code is eager loaded so we can autoload MiqDatabase and ApplicationRecord
213+
initializer :init_secret_token, :after => :eager_load! do
214+
Vmdb::Initializer.init_secret_token
215+
end
216+
212217
config.after_initialize do
213218
Vmdb::Initializer.init
214219
ActiveRecord::Base.connection_pool.release_connection

lib/vmdb/initializer.rb

+10-3
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,18 @@ def self.init
1212
MiqServer.my_server.starting_server_record
1313
MiqServer.my_server.update(:status => "started")
1414
end
15+
end
16+
17+
def self.init_secret_token
18+
return if Rails.application.config.secret_key_base
1519

16-
# Rails console needs session store configured
17-
if defined?(Rails::Console)
18-
MiqUiWorker.preload_for_console
20+
token = if ActiveRecord::Base.connectable? && MiqDatabase.table_exists? && MiqDatabase.any?
21+
MiqDatabase.first.session_secret_token
22+
else
23+
SecureRandom.hex(64)
1924
end
25+
26+
Rails.application.config.secret_key_base = token
2027
end
2128

2229
private_class_method def self.log_db_connectable

spec/lib/vmdb/initializer_spec.rb

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
RSpec.describe Vmdb::Initializer do
2+
describe ".init_secret_token" do
3+
before do
4+
@token = Rails.application.secret_key_base
5+
end
6+
7+
after do
8+
Rails.application.config.secret_key_base = @token
9+
Rails.application.secrets = nil
10+
end
11+
12+
it "defaults to MiqDatabase session_secret_token" do
13+
MiqDatabase.seed
14+
Rails.application.config.secret_key_base = nil
15+
Rails.application.secrets = nil
16+
17+
described_class.init_secret_token
18+
expect(Rails.application.secret_key_base).to eq(MiqDatabase.first.session_secret_token)
19+
expect(Rails.application.config.secret_key_base).to eq(MiqDatabase.first.session_secret_token)
20+
end
21+
22+
it "uses random hex when MiqDatabase isn't seeded" do
23+
Rails.application.config.secret_key_base = nil
24+
Rails.application.secrets = nil
25+
26+
described_class.init_secret_token
27+
expect(Rails.application.secret_key_base).to match(/^\h{128}$/)
28+
expect(Rails.application.config.secret_key_base).to match(/^\h{128}$/)
29+
end
30+
31+
it "does not reset secrets when token already configured" do
32+
existing_value = SecureRandom.hex(64)
33+
Rails.application.config.secret_key_base = existing_value
34+
Rails.application.secrets = nil
35+
36+
described_class.init_secret_token
37+
expect(Rails.application.secret_key_base).to eq(existing_value)
38+
expect(Rails.application.config.secret_key_base).to eq(existing_value)
39+
end
40+
end
41+
end

spec/models/miq_ui_worker_spec.rb

-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353

5454
it "#preload_for_worker_role autoloads api collection classes and descendants" do
5555
allow(EvmDatabase).to receive(:seeded_primordially?).and_return(true)
56-
expect(MiqUiWorker).to receive(:configure_secret_token)
5756
MiqUiWorker.preload_for_worker_role
5857
expect(defined?(ServiceAnsibleTower)).to be_truthy
5958
end

spec/models/miq_web_service_worker_spec.rb

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
it "preload_for_worker_role autoloads api collection classes and descendants" do
1010
allow(EvmDatabase).to receive(:seeded_primordially?).and_return(true)
11-
expect(MiqWebServiceWorker).to receive(:configure_secret_token)
1211
MiqWebServiceWorker.preload_for_worker_role
1312
expect(defined?(ServiceAnsibleTower)).to be_truthy
1413
end

spec/models/mixins/miq_web_server_worker_mixin_spec.rb

-37
Original file line numberDiff line numberDiff line change
@@ -14,43 +14,6 @@
1414
end
1515
end
1616

17-
before do
18-
@token = Rails.application.secret_key_base
19-
MiqDatabase.seed
20-
end
21-
22-
after do
23-
Rails.application.config.secret_key_base = @token
24-
Rails.application.secrets = nil if Rails.version < "7.1"
25-
end
26-
27-
it ".configure_secret_token defaults to MiqDatabase session_secret_token" do
28-
Rails.application.config.secret_key_base = nil
29-
30-
test_class.configure_secret_token
31-
expect(Rails.application.secret_key_base).to eq(MiqDatabase.first.session_secret_token)
32-
expect(Rails.application.config.secret_key_base).to eq(MiqDatabase.first.session_secret_token)
33-
end
34-
35-
it ".configure_secret_token accepts an input token" do
36-
Rails.application.config.secret_key_base = nil
37-
38-
token = SecureRandom.hex(64)
39-
test_class.configure_secret_token(token)
40-
expect(Rails.application.secret_key_base).to eq(token)
41-
expect(Rails.application.config.secret_key_base).to eq(token)
42-
end
43-
44-
it ".configure_secret_token does not reset secrets when token already configured" do
45-
existing_value = SecureRandom.hex(64)
46-
Rails.application.config.secret_key_base = existing_value
47-
Rails.application.secrets = nil if Rails.version < "7.1"
48-
49-
test_class.configure_secret_token
50-
expect(Rails.application.secret_key_base).to eq(existing_value)
51-
expect(Rails.application.config.secret_key_base).to eq(existing_value)
52-
end
53-
5417
it "#rails_server_options" do
5518
w = FactoryBot.create(:miq_ui_worker, :uri => "http://127.0.0.1:3000")
5619
expect(w.rails_server_options).to include(

0 commit comments

Comments
 (0)