diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index b5ffa5e6c8f6b620e5eb070e54354103a4dae6db..d2f6575749c898aa74919f8ce5e9ea8f0d594927 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -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. diff --git a/activesupport/lib/active_support/encrypted_file.rb b/activesupport/lib/active_support/encrypted_file.rb index 544dacb7e541d328614556f64c7fafb71a1ad7bf..b7435f946f46aab7202e2ac4029d293c04ac6c18 100644 --- a/activesupport/lib/active_support/encrypted_file.rb +++ b/activesupport/lib/active_support/encrypted_file.rb @@ -30,7 +30,8 @@ def self.generate_key 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 diff --git a/activesupport/test/encrypted_file_test.rb b/activesupport/test/encrypted_file_test.rb index ba3bbef903c204d77e899c5fc92bb59acbfae990..0954448cdd7e628ce00ca4634e1ea1f34ffa32de 100644 --- a/activesupport/test/encrypted_file_test.rb +++ b/activesupport/test/encrypted_file_test.rb @@ -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