Skip to content

Commit 752b566

Browse files
Merge pull request rails#45672 from jonathanhefner/generate-master-key-despite-require_master_key
Generate `master.key` even when `require_master_key`
2 parents 6d100e5 + 1740b1f commit 752b566

File tree

6 files changed

+63
-21
lines changed

6 files changed

+63
-21
lines changed

activesupport/lib/active_support/encrypted_file.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ def key
5353
read_env_key || read_key_file || handle_missing_key
5454
end
5555

56+
# Returns truthy if #key is truthy. Returns falsy otherwise. Unlike #key,
57+
# does not raise MissingKeyError when +raise_if_missing_key+ is true.
58+
def key?
59+
read_env_key || read_key_file
60+
end
61+
5662
# Reads the file and returns the decrypted content.
5763
#
5864
# Raises:

activesupport/test/encrypted_file_test.rb

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
class EncryptedFileTest < ActiveSupport::TestCase
77
setup do
8+
@original_env_content_key = ENV["CONTENT_KEY"]
9+
ENV["CONTENT_KEY"] = nil
10+
811
@content = "One little fox jumped over the hedge"
912

1013
@tmpdir = Dir.mktmpdir("encrypted-file-test-")
@@ -21,19 +24,17 @@ class EncryptedFileTest < ActiveSupport::TestCase
2124
FileUtils.rm_rf @content_path
2225
FileUtils.rm_rf @key_path
2326
FileUtils.rm_rf @tmpdir
27+
28+
ENV["CONTENT_KEY"] = @original_env_content_key
2429
end
2530

2631
test "reading content by env key" do
2732
FileUtils.rm_rf @key_path
2833

29-
begin
30-
ENV["CONTENT_KEY"] = @key
31-
@encrypted_file.write @content
34+
ENV["CONTENT_KEY"] = @key
35+
@encrypted_file.write @content
3236

33-
assert_equal @content, @encrypted_file.read
34-
ensure
35-
ENV["CONTENT_KEY"] = nil
36-
end
37+
assert_equal @content, @encrypted_file.read
3738
end
3839

3940
test "reading content by key file" do
@@ -59,17 +60,13 @@ class EncryptedFileTest < ActiveSupport::TestCase
5960
test "raise MissingKeyError when env key is blank" do
6061
FileUtils.rm_rf @key_path
6162

62-
begin
63-
ENV["CONTENT_KEY"] = ""
64-
raised = assert_raise ActiveSupport::EncryptedFile::MissingKeyError do
65-
@encrypted_file.write @content
66-
@encrypted_file.read
67-
end
68-
69-
assert_match(/Missing encryption key to decrypt file/, raised.message)
70-
ensure
71-
ENV["CONTENT_KEY"] = nil
63+
ENV["CONTENT_KEY"] = ""
64+
raised = assert_raise ActiveSupport::EncryptedFile::MissingKeyError do
65+
@encrypted_file.write @content
66+
@encrypted_file.read
7267
end
68+
69+
assert_match(/Missing encryption key to decrypt file/, raised.message)
7370
end
7471

7572
test "key can be added after MissingKeyError raised" do
@@ -86,6 +83,25 @@ class EncryptedFileTest < ActiveSupport::TestCase
8683
end
8784
end
8885

86+
test "key? is true when key file exists" do
87+
assert @encrypted_file.key?
88+
end
89+
90+
test "key? is true when env key is present" do
91+
FileUtils.rm_rf @key_path
92+
ENV["CONTENT_KEY"] = @key
93+
94+
assert @encrypted_file.key?
95+
end
96+
97+
test "key? is false and does not raise when the key is missing" do
98+
FileUtils.rm_rf @key_path
99+
100+
assert_nothing_raised do
101+
assert_not @encrypted_file.key?
102+
end
103+
end
104+
89105
test "raise InvalidKeyLengthError when key is too short" do
90106
File.write(@key_path, ActiveSupport::EncryptedFile.generate_key[0..-2])
91107

railties/lib/rails/commands/credentials/credentials_command.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def edit
3232

3333
ensure_editor_available(command: "bin/rails credentials:edit") || (return)
3434

35-
ensure_encryption_key_has_been_added if credentials.key.nil?
35+
ensure_encryption_key_has_been_added
3636
ensure_credentials_have_been_added
3737
ensure_diffing_driver_is_configured
3838

@@ -78,6 +78,8 @@ def credentials
7878
end
7979

8080
def ensure_encryption_key_has_been_added
81+
return if credentials.key?
82+
8183
require "rails/generators/rails/encryption_key_file/encryption_key_file_generator"
8284

8385
encryption_key_file_generator = Rails::Generators::EncryptionKeyFileGenerator.new
@@ -102,7 +104,7 @@ def change_credentials_in_system_editor
102104
end
103105

104106
def missing_credentials_message
105-
if credentials.key.nil?
107+
if !credentials.key?
106108
"Missing '#{key_path}' to decrypt credentials. See `bin/rails credentials:help`"
107109
else
108110
"File '#{content_path}' does not exist. Use `bin/rails credentials:edit` to change that."

railties/lib/rails/commands/encrypted/encrypted_command.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def edit(*)
2424
require_application!
2525

2626
ensure_editor_available(command: "bin/rails encrypted:edit") || (return)
27-
ensure_encryption_key_has_been_added if encrypted_configuration.key.nil?
27+
ensure_encryption_key_has_been_added
2828
ensure_encrypted_configuration_has_been_added
2929

3030
catch_editing_exceptions do
@@ -56,6 +56,7 @@ def encrypted_configuration
5656
end
5757

5858
def ensure_encryption_key_has_been_added
59+
return if encrypted_configuration.key?
5960
encryption_key_file_generator.add_key_file(key_path)
6061
encryption_key_file_generator.ignore_key_file(key_path)
6162
end
@@ -86,7 +87,7 @@ def encrypted_file_generator
8687
end
8788

8889
def missing_encrypted_configuration_message
89-
if encrypted_configuration.key.nil?
90+
if !encrypted_configuration.key?
9091
"Missing '#{key_path}' to decrypt data. See `bin/rails encrypted:help`"
9192
else
9293
"File '#{content_path}' does not exist. Use `bin/rails encrypted:edit #{content_path}` to change that."

railties/test/commands/credentials_test.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,15 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase
6666
assert_equal 1, read_file(".gitignore").scan("config/master.key").length
6767
end
6868

69+
test "edit command can add master key when require_master_key is true" do
70+
remove_file "config/credentials.yml.enc"
71+
remove_file "config/master.key"
72+
add_to_config "config.require_master_key = true"
73+
74+
assert_nothing_raised { run_edit_command }
75+
assert_file "config/master.key"
76+
end
77+
6978
test "edit command does not add master key when `RAILS_MASTER_KEY` env specified" do
7079
master_key = read_file("config/master.key")
7180
remove_file "config/master.key"

railties/test/commands/encrypted_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ class Rails::Command::EncryptedCommandTest < ActiveSupport::TestCase
5151
assert_equal 1, read_file(".gitignore").scan("config/master.key").length
5252
end
5353

54+
test "edit command can add master key when require_master_key is true" do
55+
remove_file "config/master.key"
56+
add_to_config "config.require_master_key = true"
57+
58+
assert_nothing_raised { run_edit_command }
59+
assert_file "config/master.key"
60+
end
61+
5462
test "edit command does not add master key when `RAILS_MASTER_KEY` env specified" do
5563
master_key = read_file("config/master.key")
5664
remove_file "config/master.key"

0 commit comments

Comments
 (0)