From e0d3313bac6bd2fbf10df27d79d72157f63ae6ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Wn=C4=99trzak?= Date: Wed, 19 Sep 2018 23:02:00 +0200 Subject: Support environment specific credentials file. (#33521) For `production` environment look first for `config/credentials/production.yml.enc` file that can be decrypted by `ENV["RAILS_MASTER_KEY"]` or `config/credentials/production.key` master key. Edit given environment credentials file by command `rails credentials:edit --environment production`. Default behavior can be overwritten by setting `config.credentials.content_path` and `config.credentials.key_path`. --- railties/test/commands/credentials_test.rb | 26 +++++++++++++--- railties/test/credentials_test.rb | 49 ++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 railties/test/credentials_test.rb (limited to 'railties/test') diff --git a/railties/test/commands/credentials_test.rb b/railties/test/commands/credentials_test.rb index 5b8b9e4eda..7842b0db61 100644 --- a/railties/test/commands/credentials_test.rb +++ b/railties/test/commands/credentials_test.rb @@ -55,6 +55,14 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase end end + test "edit command modifies file specified by environment option" do + assert_match(/access_key_id: 123/, run_edit_command(environment: "production")) + Dir.chdir(app_path) do + assert File.exist?("config/credentials/production.key") + assert File.exist?("config/credentials/production.yml.enc") + end + end + test "show credentials" do assert_match(/access_key_id: 123/, run_show_command) end @@ -70,17 +78,25 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase remove_file "config/master.key" add_to_config "config.require_master_key = false" - assert_match(/Missing master key to decrypt credentials/, run_show_command) + assert_match(/Missing 'config\/master\.key' to decrypt credentials/, run_show_command) + end + + test "show command displays content specified by environment option" do + run_edit_command(environment: "production") + + assert_match(/access_key_id: 123/, run_show_command(environment: "production")) end private - def run_edit_command(editor: "cat") + def run_edit_command(editor: "cat", environment: nil, **options) switch_env("EDITOR", editor) do - rails "credentials:edit" + args = environment ? ["--environment", environment] : [] + rails "credentials:edit", args, **options end end - def run_show_command(**options) - rails "credentials:show", **options + def run_show_command(environment: nil, **options) + args = environment ? ["--environment", environment] : [] + rails "credentials:show", args, **options end end diff --git a/railties/test/credentials_test.rb b/railties/test/credentials_test.rb new file mode 100644 index 0000000000..03370e0fc7 --- /dev/null +++ b/railties/test/credentials_test.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require "isolation/abstract_unit" + +class Rails::CredentialsTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation + + setup :build_app + teardown :teardown_app + + test "reads credentials from environment specific path" do + with_credentials do |content, key| + Dir.chdir(app_path) do + Dir.mkdir("config/credentials") + File.write("config/credentials/production.yml.enc", content) + File.write("config/credentials/production.key", key) + end + + app("production") + + assert_equal "revealed", Rails.application.credentials.mystery + end + end + + test "reads credentials from customized path and key" do + with_credentials do |content, key| + Dir.chdir(app_path) do + Dir.mkdir("config/credentials") + File.write("config/credentials/staging.yml.enc", content) + File.write("config/credentials/staging.key", key) + end + + add_to_env_config("production", "config.credentials.content_path = config.root.join('config/credentials/staging.yml.enc')") + add_to_env_config("production", "config.credentials.key_path = config.root.join('config/credentials/staging.key')") + app("production") + + assert_equal "revealed", Rails.application.credentials.mystery + end + end + + private + def with_credentials + key = "2117e775dc2024d4f49ddf3aeb585919" + # secret_key_base: secret + # mystery: revealed + content = "vgvKu4MBepIgZ5VHQMMPwnQNsLlWD9LKmJHu3UA/8yj6x+3fNhz3DwL9brX7UA==--qLdxHP6e34xeTAiI--nrcAsleXuo9NqiEuhntAhw==" + yield(content, key) + end +end -- cgit v1.2.3