diff --git a/app/controllers/assets_controller.rb b/app/controllers/assets_controller.rb index 1c56ef088..7c7ddbb1c 100644 --- a/app/controllers/assets_controller.rb +++ b/app/controllers/assets_controller.rb @@ -48,7 +48,7 @@ class AssetsController < ApplicationController def preview if @asset.is_image? - redirect_to @asset.presigned_url(:medium), status: 307 + redirect_to @asset.url(:medium), status: 307 else render_400 end diff --git a/app/helpers/reports_helper.rb b/app/helpers/reports_helper.rb index 383f10b29..51b90e7a1 100644 --- a/app/helpers/reports_helper.rb +++ b/app/helpers/reports_helper.rb @@ -81,7 +81,7 @@ end def report_image_asset_url(asset) prefix = (ENV["PAPERCLIP_STORAGE"].present? && ENV["MAIL_SERVER_URL"].present? && ENV["PAPERCLIP_STORAGE"] == "filesystem") ? ENV["MAIL_SERVER_URL"] : "" prefix = (!prefix.empty? && !prefix.include?("http://") && !prefix.include?("https://")) ? "http://#{prefix}" : prefix - url = prefix + asset.presigned_url(:medium, time: 86_400) + url = prefix + asset.url(:medium, timeout: 86_400) image_tag(url) end diff --git a/app/models/asset.rb b/app/models/asset.rb index 8327e21bf..ec6566f86 100644 --- a/app/models/asset.rb +++ b/app/models/asset.rb @@ -215,23 +215,12 @@ class Asset < ActiveRecord::Base end def destroy - # Delete files from S3 (when updating an existing file, paperclip does - # this automatically, so this is not needed in such cases) - key = file.path[1..-1] - S3_BUCKET.object(key).delete - Rails.logger.info "Asset #{id} (original): Asset file "\ - "successfully deleted from S3 (" + key.to_s + ')' - if (file_content_type =~ %r{^image\/}) == 0 - file.options[:styles].each do |style, _| - key = file.path(style)[1..-1] - S3_BUCKET.object(key).delete - Rails.logger.info "Asset #{id} (" + style.to_s + '): Asset file '\ - 'successfully deleted from S3 (' + key.to_s + ')' - end - end - report_elements.destroy_all asset_text_datum.destroy if asset_text_datum.present? + + # Nullify needed to force paperclip file deletion + self.file = nil + save delete end @@ -259,7 +248,16 @@ class Asset < ActiveRecord::Base end end - def presigned_url(style = :original, download: false, time: 30) + def url(style = :original, timeout: 30) + if file.is_stored_on_s3? + presigned_url(style, timeout: timeout) + else + file.url(style) + end + end + + # When using S3 file upload, we can limit file accessibility with url signing + def presigned_url(style = :original, download: false, timeout: 30) if file.is_stored_on_s3? if download download_arg = 'attachment; filename=' + URI.escape(file_file_name) @@ -271,12 +269,20 @@ class Asset < ActiveRecord::Base signer.presigned_url(:get_object, bucket: S3_BUCKET.name, key: file.path(style)[1..-1], - expires_in: time, + expires_in: timeout, # this response header forces object download response_content_disposition: download_arg) end end + def open + if file.is_stored_on_s3? + Kernel.open(presigned_url, "rb") + else + File.open(file.path, "rb") + end + end + # Preserving attachments (on client-side) between failed validations (only usable for small/few files!) # Needs to be called before save method and view needs to have :file_content and :file_info hidden field # If file is an image, it can be viewed on front-end using @preview_cached with image_tag tag diff --git a/app/utilities/protocols_exporter.rb b/app/utilities/protocols_exporter.rb index e31aca1d1..6a1fa5129 100644 --- a/app/utilities/protocols_exporter.rb +++ b/app/utilities/protocols_exporter.rb @@ -53,11 +53,7 @@ module ProtocolsExporter asset_json["fileType"] = asset_json.delete("file_content_type") # Retrieve file contents - if asset.file.is_stored_on_s3? - file = open(asset.presigned_url, "rb") - else - file = File.open(asset.file.path, "rb") - end + file = asset.open asset_json["bytes"] = Base64.encode64(file.read) file.close