Keep symbolic link after editing credentials.yml.enc

When editing credentials.yml.enc after creating a symbolic link,
the symbolic link is removed and overwritten with a normal file.
This commit changes the behavior to keep the symbolic link.

In case of using a dead symbolic link that link is revived after writing.

Fixes #36411
This commit is contained in:
sinsoku 2019-10-14 02:18:29 +09:00 committed by Kasper Timm Hansen
parent d87a0c6a20
commit 6db6432d71
No known key found for this signature in database
GPG Key ID: 191153215EDA53D8
3 changed files with 41 additions and 8 deletions

View File

@ -1,3 +1,7 @@
* Support symbolic links for `content_path` in `ActiveSupport::EncryptedFile`.
*Takumi Shotoku*
* Improve `Range#===`, `Range#include?`, and `Range#cover?` to work with beginless (startless)
and endless range targets.

View File

@ -30,7 +30,8 @@ module ActiveSupport
attr_reader :content_path, :key_path, :env_key, :raise_if_missing_key
def initialize(content_path:, key_path:, env_key:, raise_if_missing_key:)
@content_path, @key_path = Pathname.new(content_path), Pathname.new(key_path)
@content_path = Pathname.new(content_path).yield_self { |path| path.symlink? ? path.realpath : path }
@key_path = Pathname.new(key_path)
@env_key, @raise_if_missing_key = env_key, raise_if_missing_key
end

View File

@ -12,9 +12,7 @@ class EncryptedFileTest < ActiveSupport::TestCase
@key_path = File.join(Dir.tmpdir, "content.txt.key")
File.write(@key_path, ActiveSupport::EncryptedFile.generate_key)
@encrypted_file = ActiveSupport::EncryptedFile.new(
content_path: @content_path, key_path: @key_path, env_key: "CONTENT_KEY", raise_if_missing_key: true
)
@encrypted_file = encrypted_file(@content_path)
end
teardown do
@ -50,10 +48,40 @@ class EncryptedFileTest < ActiveSupport::TestCase
end
test "raise MissingKeyError when key is missing" do
assert_raise(ActiveSupport::EncryptedFile::MissingKeyError) do
ActiveSupport::EncryptedFile.new(
content_path: @content_path, key_path: "", env_key: "", raise_if_missing_key: true
).read
assert_raise ActiveSupport::EncryptedFile::MissingKeyError do
encrypted_file(@content_path, key_path: "", env_key: "").read
end
end
test "respects existing content_path symlink" do
@encrypted_file.write(@content)
symlink_path = File.join(Dir.tmpdir, "content_symlink.txt.enc")
File.symlink(@encrypted_file.content_path, symlink_path)
encrypted_file(symlink_path).write(@content)
assert File.symlink?(symlink_path)
assert_equal @content, @encrypted_file.read
ensure
FileUtils.rm_rf symlink_path
end
test "creates new content_path symlink if it's dead" do
symlink_path = File.join(Dir.tmpdir, "content_symlink.txt.enc")
File.symlink(@content_path, symlink_path)
encrypted_file(symlink_path).write(@content)
assert File.exist?(@content_path)
assert_equal @content, @encrypted_file.read
ensure
FileUtils.rm_rf symlink_path
end
private
def encrypted_file(content_path, key_path: @key_path, env_key: "CONTENT_KEY")
ActiveSupport::EncryptedFile.new(content_path: @content_path, key_path: key_path,
env_key: env_key, raise_if_missing_key: true)
end
end