aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/lib/rails/application.rb3
-rw-r--r--railties/lib/rails/application/configuration.rb4
-rw-r--r--railties/lib/rails/commands/credentials/credentials_command.rb11
-rw-r--r--railties/lib/rails/commands/encrypted/encrypted_command.rb12
-rw-r--r--railties/lib/rails/generators/app_base.rb7
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile.tt2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/boot.rb.tt2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt2
-rw-r--r--railties/lib/rails/generators/rails/credentials/credentials_generator.rb3
-rw-r--r--railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb2
-rw-r--r--railties/test/application/configuration_test.rb8
-rw-r--r--railties/test/commands/credentials_test.rb26
-rw-r--r--railties/test/commands/encrypted_test.rb18
-rw-r--r--railties/test/generators/app_generator_test.rb31
14 files changed, 114 insertions, 17 deletions
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 293a736bfd..a200a1005c 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -472,7 +472,8 @@ module Rails
ActiveSupport::EncryptedConfiguration.new(
config_path: Rails.root.join(path),
key_path: Rails.root.join(key_path),
- env_key: env_key
+ env_key: env_key,
+ raise_if_missing_key: config.require_master_key
)
end
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index cbc04f8a48..5d8d6740c8 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -16,7 +16,8 @@ module Rails
:ssl_options, :public_file_server,
:session_options, :time_zone, :reload_classes_only_on_change,
:beginning_of_week, :filter_redirect, :x, :enable_dependency_loading,
- :read_encrypted_secrets, :log_level, :content_security_policy_report_only
+ :read_encrypted_secrets, :log_level, :content_security_policy_report_only,
+ :require_master_key
attr_reader :encoding, :api_only
@@ -56,6 +57,7 @@ module Rails
@read_encrypted_secrets = false
@content_security_policy = nil
@content_security_policy_report_only = false
+ @require_master_key = false
end
def load_defaults(target_version)
diff --git a/railties/lib/rails/commands/credentials/credentials_command.rb b/railties/lib/rails/commands/credentials/credentials_command.rb
index 8085f07c2b..385d3976da 100644
--- a/railties/lib/rails/commands/credentials/credentials_command.rb
+++ b/railties/lib/rails/commands/credentials/credentials_command.rb
@@ -33,8 +33,7 @@ module Rails
def show
require_application_and_environment!
- say Rails.application.credentials.read.presence ||
- "No credentials have been added yet. Use bin/rails credentials:edit to change that."
+ say Rails.application.credentials.read.presence || missing_credentials_message
end
private
@@ -67,6 +66,14 @@ module Rails
Rails::Generators::CredentialsGenerator.new
end
+
+ def missing_credentials_message
+ if Rails.application.credentials.key.nil?
+ "Missing master key to decrypt credentials. See bin/rails credentials:help"
+ else
+ "No credentials have been added yet. Use bin/rails credentials:edit to change that."
+ end
+ end
end
end
end
diff --git a/railties/lib/rails/commands/encrypted/encrypted_command.rb b/railties/lib/rails/commands/encrypted/encrypted_command.rb
index 898094f1a4..912c453f09 100644
--- a/railties/lib/rails/commands/encrypted/encrypted_command.rb
+++ b/railties/lib/rails/commands/encrypted/encrypted_command.rb
@@ -37,9 +37,9 @@ module Rails
def show(file_path)
require_application_and_environment!
+ encrypted = Rails.application.encrypted(file_path, key_path: options[:key])
- say Rails.application.encrypted(file_path, key_path: options[:key]).read.presence ||
- "File '#{file_path}' does not exist. Use bin/rails encrypted:edit #{file_path} to change that."
+ say encrypted.read.presence || missing_encrypted_message(key: encrypted.key, key_path: options[:key], file_path: file_path)
end
private
@@ -72,6 +72,14 @@ module Rails
Rails::Generators::EncryptedFileGenerator.new
end
+
+ def missing_encrypted_message(key:, key_path:, file_path:)
+ if key.nil?
+ "Missing '#{key_path}' to decrypt data. See bin/rails encrypted:help"
+ else
+ "File '#{file_path}' does not exist. Use bin/rails encrypted:edit #{file_path} to change that."
+ end
+ end
end
end
end
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index b9ae24de59..400f954dcd 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -84,6 +84,9 @@ module Rails
class_option :skip_system_test, type: :boolean, default: false,
desc: "Skip system test files"
+ class_option :skip_bootsnap, type: :boolean, default: false,
+ desc: "Skip bootsnap gem"
+
class_option :dev, type: :boolean, default: false,
desc: "Setup the #{name} with Gemfile pointing to your Rails checkout"
@@ -435,6 +438,10 @@ module Rails
!options[:skip_listen] && os_supports_listen_out_of_the_box?
end
+ def depend_on_bootsnap?
+ !options[:skip_bootsnap] && !options[:dev]
+ end
+
def os_supports_listen_out_of_the_box?
RbConfig::CONFIG["host_os"] =~ /darwin|linux/
end
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile.tt b/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
index e3ed3e7c11..23bb89f4ce 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
@@ -29,9 +29,11 @@ ruby <%= "'#{RUBY_VERSION}'" -%>
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
+<% if depend_on_bootsnap? -%>
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false
+<%- end -%>
<%- if options.api? -%>
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
# gem 'rack-cors'
diff --git a/railties/lib/rails/generators/rails/app/templates/config/boot.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/boot.rb.tt
index 6246e7bf85..720d36a2a4 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/boot.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/boot.rb.tt
@@ -1,7 +1,9 @@
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
require 'bundler/setup' # Set up gems listed in the Gemfile.
+<% if depend_on_bootsnap? -%>
require 'bootsnap/setup' # Speed up boot time by caching expensive operations.
+<%- end -%>
if %w[s server c console].any? { |a| ARGV.include?(a) }
puts "=> Booting Rails"
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt
index f630d9985a..8351d849ec 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt
@@ -10,7 +10,7 @@
# This is needed for recyclable cache keys.
# Rails.application.config.active_record.cache_versioning = true
-# Use AES 256 GCM authenticated encryption for encrypted cookies.
+# Use AES-256-GCM authenticated encryption for encrypted cookies.
# Existing cookies will be converted on read then written with the new scheme.
# Rails.application.config.action_dispatch.use_authenticated_cookie_encryption = true
diff --git a/railties/lib/rails/generators/rails/credentials/credentials_generator.rb b/railties/lib/rails/generators/rails/credentials/credentials_generator.rb
index 01a5b502f9..9103b1122e 100644
--- a/railties/lib/rails/generators/rails/credentials/credentials_generator.rb
+++ b/railties/lib/rails/generators/rails/credentials/credentials_generator.rb
@@ -36,7 +36,8 @@ module Rails
ActiveSupport::EncryptedConfiguration.new(
config_path: "config/credentials.yml.enc",
key_path: "config/master.key",
- env_key: "RAILS_MASTER_KEY"
+ env_key: "RAILS_MASTER_KEY",
+ raise_if_missing_key: true
)
end
diff --git a/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb b/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb
index ddce5f6fe2..4ce2fc1d86 100644
--- a/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb
+++ b/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb
@@ -24,7 +24,7 @@ module Rails
def add_encrypted_file_silently(file_path, key_path, template = encrypted_file_template)
unless File.exist?(file_path)
- setup = { content_path: file_path, key_path: key_path, env_key: "RAILS_MASTER_KEY" }
+ setup = { content_path: file_path, key_path: key_path, env_key: "RAILS_MASTER_KEY", raise_if_missing_key: true }
ActiveSupport::EncryptedFile.new(setup).write(template)
end
end
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index d28f7ffc7f..ec745a397e 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -707,6 +707,14 @@ module ApplicationTests
assert_match(/Missing.*RAILS_MASTER_KEY/, error)
end
+ test "credentials does not raise error when require_master_key is false and master key does not exist" do
+ remove_file "config/master.key"
+ add_to_config "config.require_master_key = false"
+ app "development"
+
+ assert_not app.credentials.secret_key_base
+ end
+
test "protect from forgery is the default in a new app" do
make_basic_app
diff --git a/railties/test/commands/credentials_test.rb b/railties/test/commands/credentials_test.rb
index f1bb1ef08a..7c464b3fde 100644
--- a/railties/test/commands/credentials_test.rb
+++ b/railties/test/commands/credentials_test.rb
@@ -26,10 +26,6 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase
end
end
- test "show credentials" do
- assert_match(/access_key_id: 123/, run_show_command)
- end
-
test "edit command does not add master key to gitignore when already exist" do
run_edit_command
@@ -47,6 +43,24 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase
assert_match(/api_key: abc/, run_show_command)
end
+ test "show credentials" do
+ assert_match(/access_key_id: 123/, run_show_command)
+ end
+
+ test "show command raise error when require_master_key is specified and key does not exist" do
+ remove_file "config/master.key"
+ add_to_config "config.require_master_key = true"
+
+ assert_match(/Missing encryption key to decrypt file with/, run_show_command(allow_failure: true))
+ end
+
+ test "show command does not raise error when require_master_key is false and master key does not exist" do
+ remove_file "config/master.key"
+ add_to_config "config.require_master_key = false"
+
+ assert_match(/Missing master key to decrypt credentials/, run_show_command)
+ end
+
private
def run_edit_command(editor: "cat")
switch_env("EDITOR", editor) do
@@ -54,7 +68,7 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase
end
end
- def run_show_command
- rails "credentials:show"
+ def run_show_command(**options)
+ rails "credentials:show", **options
end
end
diff --git a/railties/test/commands/encrypted_test.rb b/railties/test/commands/encrypted_test.rb
index 0461493f2a..6647dcc902 100644
--- a/railties/test/commands/encrypted_test.rb
+++ b/railties/test/commands/encrypted_test.rb
@@ -52,6 +52,20 @@ class Rails::Command::EncryptedCommandTest < ActiveSupport::TestCase
assert_match(/access_key_id: 123/, run_show_command("config/tokens.yml.enc", key: "config/tokens.key"))
end
+ test "show command raise error when require_master_key is specified and key does not exist" do
+ add_to_config "config.require_master_key = true"
+
+ assert_match(/Missing encryption key to decrypt file with/,
+ run_show_command("config/tokens.yml.enc", key: "unexist.key", allow_failure: true))
+ end
+
+ test "show command does not raise error when require_master_key is false and master key does not exist" do
+ remove_file "config/master.key"
+ add_to_config "config.require_master_key = false"
+
+ assert_match(/Missing 'config\/master\.key' to decrypt data/, run_show_command("config/tokens.yml.enc"))
+ end
+
test "won't corrupt encrypted file when passed wrong key" do
run_edit_command("config/tokens.yml.enc", key: "config/tokens.key")
@@ -68,8 +82,8 @@ class Rails::Command::EncryptedCommandTest < ActiveSupport::TestCase
end
end
- def run_show_command(file, key: nil)
- rails "encrypted:show", prepare_args(file, key)
+ def run_show_command(file, key: nil, **options)
+ rails "encrypted:show", prepare_args(file, key), **options
end
def prepare_args(file, key)
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 96803db838..110aca70c1 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -792,6 +792,37 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_bootsnap
+ run_generator
+
+ assert_gem "bootsnap"
+ assert_file "config/boot.rb" do |content|
+ assert_match(/require 'bootsnap\/setup'/, content)
+ end
+ end
+
+ def test_skip_bootsnap
+ run_generator [destination_root, "--skip-bootsnap"]
+
+ assert_file "Gemfile" do |content|
+ assert_no_match(/bootsnap/, content)
+ end
+ assert_file "config/boot.rb" do |content|
+ assert_no_match(/require 'bootsnap\/setup'/, content)
+ end
+ end
+
+ def test_bootsnap_with_dev_option
+ run_generator [destination_root, "--dev"]
+
+ assert_file "Gemfile" do |content|
+ assert_no_match(/bootsnap/, content)
+ end
+ assert_file "config/boot.rb" do |content|
+ assert_no_match(/require 'bootsnap\/setup'/, content)
+ end
+ end
+
def test_inclusion_of_ruby_version
run_generator