Extract diffing to separate credentials:diff command

上级 b4112f45
...@@ -43,24 +43,27 @@ def edit ...@@ -43,24 +43,27 @@ def edit
say "Couldn't decrypt #{content_path}. Perhaps you passed the wrong key?" say "Couldn't decrypt #{content_path}. Perhaps you passed the wrong key?"
end end
def show(git_textconv_path = nil) def show
if git_textconv_path extract_environment_option_from_argument(default_environment: nil)
default_environment = extract_environment_from_path(git_textconv_path) require_application!
fallback_message = File.read(git_textconv_path)
say credentials.read.presence || missing_credentials_message
end end
extract_environment_option_from_argument(default_environment: default_environment) def diff(content_path)
@content_path = content_path
extract_environment_option_from_argument(default_environment: extract_environment_from_path(content_path))
require_application! require_application!
say credentials(git_textconv_path).read.presence || fallback_message || missing_credentials_message say credentials.read.presence || credentials.content_path.read
rescue => e rescue
raise(e) unless git_textconv_path say credentials.content_path.read
fallback_message
end end
private private
def credentials(content = nil) def credentials
Rails.application.encrypted(content || content_path, key_path: key_path) Rails.application.encrypted(content_path, key_path: key_path)
end end
def ensure_encryption_key_has_been_added def ensure_encryption_key_has_been_added
...@@ -90,8 +93,9 @@ def missing_credentials_message ...@@ -90,8 +93,9 @@ def missing_credentials_message
end end
end end
def content_path def content_path
options[:environment] ? "config/credentials/#{options[:environment]}.yml.enc" : "config/credentials.yml.enc" @content_path ||= options[:environment] ? "config/credentials/#{options[:environment]}.yml.enc" : "config/credentials.yml.enc"
end end
def key_path def key_path
...@@ -99,15 +103,7 @@ def key_path ...@@ -99,15 +103,7 @@ def key_path
end end
def extract_environment_from_path(path) def extract_environment_from_path(path)
regex = %r{ available_environments.find { |env| path.include? env } if path.match?(/\.yml\.enc$/)
([A-Za-z0-9]+) # match the environment
(?<!credentials) # don't match if file contains the word "credentials"
# in such case, the environment should be the default one
\.yml\.enc # look for `.yml.enc` file extension
}x
path.match(regex)
Regexp.last_match(1)
end end
def encryption_key_file_generator def encryption_key_file_generator
......
...@@ -24,7 +24,7 @@ def enabled? ...@@ -24,7 +24,7 @@ def enabled?
end end
def enable def enable
system_call("git config diff.rails_credentials.textconv 'bin/rails credentials:show'", accepted_codes: [0]) system_call("git config diff.rails_credentials.textconv 'bin/rails credentials:diff'", accepted_codes: [0])
git_attributes = Rails.root.join(".gitattributes") git_attributes = Rails.root.join(".gitattributes")
File.open(git_attributes, "a+") do |file| File.open(git_attributes, "a+") do |file|
......
...@@ -10,9 +10,8 @@ ...@@ -10,9 +10,8 @@
class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation, EnvHelpers include ActiveSupport::Testing::Isolation, EnvHelpers
setup { build_app } setup :build_app
teardown :teardown_app
teardown { teardown_app }
test "edit without editor gives hint" do test "edit without editor gives hint" do
run_edit_command(editor: "").tap do |output| run_edit_command(editor: "").tap do |output|
...@@ -125,7 +124,7 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase ...@@ -125,7 +124,7 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase
assert(File.exist?(git_attributes)) assert(File.exist?(git_attributes))
assert_equal(expected, File.read(git_attributes)) assert_equal(expected, File.read(git_attributes))
Dir.chdir(app_path) do Dir.chdir(app_path) do
assert_equal("bin/rails credentials:show\n", `git config --get 'diff.rails_credentials.textconv'`) assert_equal "bin/rails credentials:diff", `git config --get 'diff.rails_credentials.textconv'`.strip
end end
ensure ensure
file.close! file.close!
...@@ -148,47 +147,41 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase ...@@ -148,47 +147,41 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase
assert_match(/access_key_id: 123/, run_show_command) assert_match(/access_key_id: 123/, run_show_command)
end end
test "show command when argument is provided (from git diff left file)" do test "diff from git diff left file" do
run_edit_command(environment: "development") run_edit_command(environment: "development")
assert_match(/access_key_id: 123/, run_show_command("config/credentials/development.yml.enc")) assert_match(/access_key_id: 123/, run_diff_command("config/credentials/development.yml.enc"))
end end
test "show command when argument is provided (from git diff right file)" do test "diff from git diff right file" do
run_edit_command(environment: "development") run_edit_command(environment: "development")
dir = Dir.mktmpdir content_path = app_path("config", "credentials", "KnAM4a_development.yml.enc")
file_path = File.join(dir, "KnAM4a_development.yml.enc") File.write(content_path,
file_content = File.read(app_path("config", "credentials", "development.yml.enc")) File.read(app_path("config", "credentials", "development.yml.enc")))
File.write(file_path, file_content)
assert_match(/access_key_id: 123/, run_show_command(file_path)) assert_match(/access_key_id: 123/, run_diff_command(content_path))
ensure
FileUtils.rm_rf(dir)
end end
test "show command when argument is provided (git diff) and filename is the master credentials" do test "diff for main credentials" do
assert_match(/access_key_id: 123/, run_show_command("config/credentials.yml.enc")) assert_match(/access_key_id: 123/, run_diff_command("config/credentials.yml.enc"))
end end
test "show command when argument is provided (git diff) and master key is not available" do test "diff when master key is not available" do
remove_file "config/master.key" remove_file "config/master.key"
raw_content = File.read(app_path("config", "credentials.yml.enc")) raw_content = File.read(app_path("config", "credentials.yml.enc"))
assert_match(raw_content, run_show_command("config/credentials.yml.enc")) assert_match(raw_content, run_diff_command("config/credentials.yml.enc"))
end end
test "show command when argument is provided (git diff) return the raw encrypted content in an error occurs" do test "diff returns raw encrypted content when errors occur" do
run_edit_command(environment: "development") run_edit_command(environment: "development")
dir = Dir.mktmpdir content_path = app_path("20190807development.yml.enc")
file_path = File.join(dir, "20190807development.yml.enc") encrypted_content = File.read(app_path("config", "credentials", "development.yml.enc"))
file_content = File.read(app_path("config", "credentials", "development.yml.enc")) File.write(content_path, encrypted_content + "ruin decryption")
File.write(file_path, file_content)
assert_match(file_content, run_show_command(file_path)) assert_match(encrypted_content, run_diff_command(content_path))
ensure
FileUtils.rm_rf(dir)
end end
test "show command raises error when require_master_key is specified and key does not exist" do test "show command raises error when require_master_key is specified and key does not exist" do
...@@ -227,9 +220,12 @@ def run_edit_command(editor: "cat", environment: nil, **options) ...@@ -227,9 +220,12 @@ def run_edit_command(editor: "cat", environment: nil, **options)
end end
end end
def run_show_command(path = nil, environment: nil, **options) def run_show_command(environment: nil, **options)
args = environment ? ["--environment", environment] : [] args = environment ? ["--environment", environment] : []
args.unshift(path)
rails "credentials:show", args, **options rails "credentials:show", args, **options
end end
def run_diff_command(path, **options)
rails "credentials:diff", path, **options
end
end end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册