diff options
-rw-r--r-- | Gemfile | 1 | ||||
-rw-r--r-- | Gemfile.lock | 1 | ||||
-rw-r--r-- | activestorage/lib/active_storage/downloading.rb | 12 | ||||
-rw-r--r-- | activestorage/lib/active_storage/previewer.rb | 12 | ||||
-rw-r--r-- | activestorage/test/service/mirror_service_test.rb | 32 | ||||
-rw-r--r-- | guides/source/active_storage_overview.md | 2 | ||||
-rw-r--r-- | guides/source/configuring.md | 5 | ||||
-rw-r--r-- | guides/source/security.md | 5 |
8 files changed, 47 insertions, 23 deletions
@@ -110,7 +110,6 @@ local_gemfile = File.expand_path(".Gemfile", __dir__) instance_eval File.read local_gemfile if File.exist? local_gemfile group :test do - gem "minitest", "= 5.11.1" gem "minitest-bisect" platforms :mri do diff --git a/Gemfile.lock b/Gemfile.lock index 97f79a0112..2d4c3e1383 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -533,7 +533,6 @@ DEPENDENCIES libxml-ruby listen (>= 3.0.5, < 3.2) mini_magick - minitest (= 5.11.1) minitest-bisect mocha mysql2 (>= 0.4.4) diff --git a/activestorage/lib/active_storage/downloading.rb b/activestorage/lib/active_storage/downloading.rb index 295289c1e7..f2a1fffdcb 100644 --- a/activestorage/lib/active_storage/downloading.rb +++ b/activestorage/lib/active_storage/downloading.rb @@ -7,12 +7,22 @@ module ActiveStorage private # Opens a new tempfile in #tempdir and copies blob data into it. Yields the tempfile. def download_blob_to_tempfile #:doc: - Tempfile.open([ "ActiveStorage", blob.filename.extension_with_delimiter ], tempdir) do |file| + open_tempfile_for_blob do |file| download_blob_to file yield file end end + def open_tempfile_for_blob + tempfile = Tempfile.open([ "ActiveStorage", blob.filename.extension_with_delimiter ], tempdir) + + begin + yield tempfile + ensure + tempfile.close! + end + end + # Efficiently downloads blob data into the given file. def download_blob_to(file) #:doc: file.binmode diff --git a/activestorage/lib/active_storage/previewer.rb b/activestorage/lib/active_storage/previewer.rb index dacab1e7df..cf19987d72 100644 --- a/activestorage/lib/active_storage/previewer.rb +++ b/activestorage/lib/active_storage/previewer.rb @@ -44,13 +44,23 @@ module ActiveStorage # The output tempfile is opened in the directory returned by ActiveStorage::Downloading#tempdir. def draw(*argv) #:doc: ActiveSupport::Notifications.instrument("preview.active_storage") do - Tempfile.open("ActiveStorage", tempdir) do |file| + open_tempfile_for_drawing do |file| capture(*argv, to: file) yield file end end end + def open_tempfile_for_drawing + tempfile = Tempfile.open("ActiveStorage", tempdir) + + begin + yield tempfile + ensure + tempfile.close! + end + end + def capture(*argv, to:) to.binmode IO.popen(argv, err: File::NULL) { |out| IO.copy_stream(out, to) } diff --git a/activestorage/test/service/mirror_service_test.rb b/activestorage/test/service/mirror_service_test.rb index 40476d636e..87306644c5 100644 --- a/activestorage/test/service/mirror_service_test.rb +++ b/activestorage/test/service/mirror_service_test.rb @@ -19,11 +19,16 @@ class ActiveStorage::Service::MirrorServiceTest < ActiveSupport::TestCase test "uploading to all services" do begin - data = "Something else entirely!" - key = upload(data, to: @service) + key = SecureRandom.base58(24) + data = "Something else entirely!" + io = StringIO.new(data) + checksum = Digest::MD5.base64digest(data) - assert_equal data, SERVICE.primary.download(key) - SERVICE.mirrors.each do |mirror| + @service.upload key, io.tap(&:read), checksum: checksum + assert_predicate io, :eof? + + assert_equal data, @service.primary.download(key) + @service.mirrors.each do |mirror| assert_equal data, mirror.download(key) end ensure @@ -32,14 +37,18 @@ class ActiveStorage::Service::MirrorServiceTest < ActiveSupport::TestCase end test "downloading from primary service" do - data = "Something else entirely!" - key = upload(data, to: SERVICE.primary) + key = SecureRandom.base58(24) + data = "Something else entirely!" + checksum = Digest::MD5.base64digest(data) + + @service.primary.upload key, StringIO.new(data), checksum: checksum assert_equal data, @service.download(key) end test "deleting from all services" do @service.delete FIXTURE_KEY + assert_not SERVICE.primary.exist?(FIXTURE_KEY) SERVICE.mirrors.each do |mirror| assert_not mirror.exist?(FIXTURE_KEY) @@ -50,17 +59,8 @@ class ActiveStorage::Service::MirrorServiceTest < ActiveSupport::TestCase filename = ActiveStorage::Filename.new("test.txt") freeze_time do - assert_equal SERVICE.primary.url(FIXTURE_KEY, expires_in: 2.minutes, disposition: :inline, filename: filename, content_type: "text/plain"), + assert_equal @service.primary.url(FIXTURE_KEY, expires_in: 2.minutes, disposition: :inline, filename: filename, content_type: "text/plain"), @service.url(FIXTURE_KEY, expires_in: 2.minutes, disposition: :inline, filename: filename, content_type: "text/plain") end end - - private - def upload(data, to:) - SecureRandom.base58(24).tap do |key| - io = StringIO.new(data).tap(&:read) - @service.upload key, io, checksum: Digest::MD5.base64digest(data) - assert_predicate io, :eof? - end - end end diff --git a/guides/source/active_storage_overview.md b/guides/source/active_storage_overview.md index d9f5aa8385..97c56dfd93 100644 --- a/guides/source/active_storage_overview.md +++ b/guides/source/active_storage_overview.md @@ -175,7 +175,7 @@ google: Add the [`google-cloud-storage`](https://github.com/GoogleCloudPlatform/google-cloud-ruby/tree/master/google-cloud-storage) gem to your `Gemfile`: ```ruby -gem "google-cloud-storage", "~> 1.3", require: false +gem "google-cloud-storage", "~> 1.8", require: false ``` ### Mirror Service diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 36c2fdb0b8..a0bf6046da 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -462,7 +462,10 @@ The schema dumper adds one additional configuration option: config.action_dispatch.default_headers = { 'X-Frame-Options' => 'SAMEORIGIN', 'X-XSS-Protection' => '1; mode=block', - 'X-Content-Type-Options' => 'nosniff' + 'X-Content-Type-Options' => 'nosniff', + 'X-Download-Options' => 'noopen', + 'X-Permitted-Cross-Domain-Policies' => 'none', + 'Referrer-Policy' => 'strict-origin-when-cross-origin' } ``` diff --git a/guides/source/security.md b/guides/source/security.md index ab5a5a7a31..de0b523057 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -1070,7 +1070,10 @@ Every HTTP response from your Rails application receives the following default s config.action_dispatch.default_headers = { 'X-Frame-Options' => 'SAMEORIGIN', 'X-XSS-Protection' => '1; mode=block', - 'X-Content-Type-Options' => 'nosniff' + 'X-Content-Type-Options' => 'nosniff', + 'X-Download-Options' => 'noopen', + 'X-Permitted-Cross-Domain-Policies' => 'none', + 'Referrer-Policy' => 'strict-origin-when-cross-origin' } ``` |