From 7a8728a03986489e1c843ed850afc2c16fb6eb06 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Wojciech=20Wn=C4=99trzak?= <w.wnetrzak@gmail.com>
Date: Tue, 14 Nov 2017 11:44:23 +0100
Subject: Add CLI to manage encrypted files/configs.

To edit/show encrypted file:

```
bin/rails encrypted:edit config/staging_tokens.yml.enc
bin/rails encrypted:edit config/staging_tokens.yml.enc --key config/staging.key
bin/rails encrypted:show config/staging_tokens.yml.enc
```

Also provides a backing Rails.application.encrypted API for Ruby access:

```ruby
Rails.application.encrypted("config/staging_tokens.yml.enc").read
Rails.application.encrypted("config/staging_tokens.yml.enc").config
Rails.application.encrypted("config/staging_tokens.yml.enc", key: "config/staging.key")
```
---
 railties/test/commands/credentials_test.rb |  5 +-
 railties/test/commands/encrypted_test.rb   | 80 ++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+), 1 deletion(-)
 create mode 100644 railties/test/commands/encrypted_test.rb

(limited to 'railties/test')

diff --git a/railties/test/commands/credentials_test.rb b/railties/test/commands/credentials_test.rb
index 743fb5f788..4ef827fcf1 100644
--- a/railties/test/commands/credentials_test.rb
+++ b/railties/test/commands/credentials_test.rb
@@ -13,7 +13,10 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase
   teardown { teardown_app }
 
   test "edit without editor gives hint" do
-    assert_match "No $EDITOR to open credentials in", run_edit_command(editor: "")
+    run_edit_command(editor: "").tap do |output|
+      assert_match "No $EDITOR to open file in", output
+      assert_match "bin/rails credentials:edit", output
+    end
   end
 
   test "edit credentials" do
diff --git a/railties/test/commands/encrypted_test.rb b/railties/test/commands/encrypted_test.rb
new file mode 100644
index 0000000000..0461493f2a
--- /dev/null
+++ b/railties/test/commands/encrypted_test.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require "isolation/abstract_unit"
+require "env_helpers"
+require "rails/command"
+require "rails/commands/encrypted/encrypted_command"
+
+class Rails::Command::EncryptedCommandTest < ActiveSupport::TestCase
+  include ActiveSupport::Testing::Isolation, EnvHelpers
+
+  setup :build_app
+  teardown :teardown_app
+
+  test "edit without editor gives hint" do
+    run_edit_command("config/tokens.yml.enc", editor: "").tap do |output|
+      assert_match "No $EDITOR to open file in", output
+      assert_match "bin/rails encrypted:edit", output
+    end
+  end
+
+  test "edit encrypted file" do
+    # Run twice to ensure file can be reread after first edit pass.
+    2.times do
+      assert_match(/access_key_id: 123/, run_edit_command("config/tokens.yml.enc"))
+    end
+  end
+
+  test "edit command does not add master key to gitignore when already exist" do
+    run_edit_command("config/tokens.yml.enc")
+
+    Dir.chdir(app_path) do
+      assert_match "/config/master.key", File.read(".gitignore")
+    end
+  end
+
+  test "edit encrypts file with custom key" do
+    run_edit_command("config/tokens.yml.enc", key: "config/tokens.key")
+
+    Dir.chdir(app_path) do
+      assert File.exist?("config/tokens.yml.enc")
+      assert File.exist?("config/tokens.key")
+
+      assert_match "/config/tokens.key", File.read(".gitignore")
+    end
+
+    assert_match(/access_key_id: 123/, run_edit_command("config/tokens.yml.enc", key: "config/tokens.key"))
+  end
+
+  test "show encrypted file with custom key" do
+    run_edit_command("config/tokens.yml.enc", key: "config/tokens.key")
+
+    assert_match(/access_key_id: 123/, run_show_command("config/tokens.yml.enc", key: "config/tokens.key"))
+  end
+
+  test "won't corrupt encrypted file when passed wrong key" do
+    run_edit_command("config/tokens.yml.enc", key: "config/tokens.key")
+
+    assert_match "passed the wrong key",
+      run_edit_command("config/tokens.yml.enc", allow_failure: true)
+
+    assert_match(/access_key_id: 123/, run_show_command("config/tokens.yml.enc", key: "config/tokens.key"))
+  end
+
+  private
+    def run_edit_command(file, key: nil, editor: "cat", **options)
+      switch_env("EDITOR", editor) do
+        rails "encrypted:edit", prepare_args(file, key), **options
+      end
+    end
+
+    def run_show_command(file, key: nil)
+      rails "encrypted:show", prepare_args(file, key)
+    end
+
+    def prepare_args(file, key)
+      args = [ file ]
+      args.push("--key", key) if key
+      args
+    end
+end
-- 
cgit v1.2.3