diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb index ac99dcb59fc..5d8124b30b2 100644 --- a/config/initializers/secret_token.rb +++ b/config/initializers/secret_token.rb @@ -7,7 +7,7 @@ def generate_new_secure_token end def warn_missing_secret(secret) - warn "Missing `#{secret}` for '#{Rails.env}' environment. The secret will be generated and stored in `config/secrets.yml`" + warn "Missing Rails.application.secrets.#{secret} for #{Rails.env} environment. The secret will be generated and stored in config/secrets.yml." end def create_tokens @@ -16,8 +16,11 @@ def create_tokens env_key = ENV['SECRET_KEY_BASE'] yaml_additions = {} + # Ensure environment variable always overrides secrets.yml. + Rails.application.secrets.secret_key_base = env_key if env_key.present? + defaults = { - secret_key_base: env_key || file_key || generate_new_secure_token, + secret_key_base: file_key || generate_new_secure_token, otp_key_base: env_key || file_key || generate_new_secure_token, db_key_base: generate_new_secure_token } @@ -34,9 +37,22 @@ def create_tokens secrets_yml = Rails.root.join('config/secrets.yml') all_secrets = YAML.load_file(secrets_yml) if File.exist?(secrets_yml) all_secrets ||= {} - env_secrets = all_secrets[Rails.env.to_s] || {} - all_secrets[Rails.env.to_s] = env_secrets.merge(yaml_additions) + + all_secrets[Rails.env.to_s] = env_secrets.merge(yaml_additions) do |key, old, new| + if old.present? + warn < '<%= an_erb_expression %>') + + allow(File).to receive(:exist?).with('.secret').and_return(false) + allow(File).to receive(:exist?).with('config/secrets.yml').and_return(true) + allow(YAML).to receive(:load_file).with('config/secrets.yml').and_return('test' => yaml_secrets) + allow(self).to receive(:warn_missing_secret) + end + + it 'warns about updating db_key_base' do + expect(self).to receive(:warn_missing_secret).with('db_key_base') + + create_tokens + end + + it 'warns about the blank value existing in secrets.yml and exits' do + expect(self).to receive(:warn) do |warning| + expect(warning).to include('db_key_base') + expect(warning).to include('<%= an_erb_expression %>') + end + + create_tokens + end + + it 'does not update secrets.yml' do + expect(self).to receive(:exit).with(1).and_call_original + expect(File).not_to receive(:write) + + expect { create_tokens }.to raise_error(SystemExit) + end + end end end