From e2a779ccfe6a988b73c4aeece0e15d936e4ab8ef Mon Sep 17 00:00:00 2001 From: Urban Rotnik Date: Wed, 2 Oct 2019 13:54:16 +0200 Subject: [PATCH 1/3] Activestorage fix for disk storage [SCI-3947] --- .../active_storage/disk_controller.rb | 64 +++++++++++++++++++ app/models/asset.rb | 6 ++ app/models/temp_file.rb | 6 ++ app/models/tiny_mce_asset.rb | 6 ++ app/services/reports/docx/private_methods.rb | 7 +- app/services/spreadsheet_parser.rb | 2 +- 6 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 app/controllers/active_storage/disk_controller.rb diff --git a/app/controllers/active_storage/disk_controller.rb b/app/controllers/active_storage/disk_controller.rb new file mode 100644 index 000000000..5c95db131 --- /dev/null +++ b/app/controllers/active_storage/disk_controller.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +module ActiveStorage + class DiskController < ActiveStorage::BaseController + skip_forgery_protection + skip_before_action :authenticate_user!, :authenticate_user_from_token!, only: :show # Skip authentication + + def show + if (key = decode_verified_key) + serve_file disk_service.path_for(key[:key]), content_type: key[:content_type], disposition: key[:disposition] + else + head :not_found + end + rescue Errno::ENOENT + head :not_found + end + + def update + if (token = decode_verified_token) + if acceptable_content?(token) + disk_service.upload token[:key], request.body, checksum: token[:checksum] + else + head :unprocessable_entity + end + else + head :not_found + end + rescue ActiveStorage::IntegrityError + head :unprocessable_entity + end + + private + + def disk_service + ActiveStorage::Blob.service + end + + def decode_verified_key + ActiveStorage.verifier.verified(params[:encoded_key], purpose: :blob_key) + end + + def serve_file(path, content_type:, disposition:) + Rack::File.new(nil).serving(request, path).tap do |(status, headers, body)| + self.status = status + self.response_body = body + + headers.each do |name, value| + response.headers[name] = value + end + + response.headers['Content-Type'] = content_type || DEFAULT_SEND_FILE_TYPE + response.headers['Content-Disposition'] = disposition || DEFAULT_SEND_FILE_DISPOSITION + end + end + + def decode_verified_token + ActiveStorage.verifier.verified(params[:encoded_token], purpose: :blob_token) + end + + def acceptable_content?(token) + token[:content_type] == request.content_mime_type && token[:content_length] == request.content_length + end + end +end diff --git a/app/models/asset.rb b/app/models/asset.rb index 1335624fb..62487b0ce 100644 --- a/app/models/asset.rb +++ b/app/models/asset.rb @@ -243,6 +243,12 @@ class Asset < ApplicationRecord to_asset.post_process_file(to_asset.team) end + def file_service_url + ActiveStorage::Current.set(host: Rails.application.secrets.mail_server_url) do + file.service_url + end + end + def extract_image_quality return unless ['image/jpeg', 'image/pjpeg'].include? content_type diff --git a/app/models/temp_file.rb b/app/models/temp_file.rb index 8ed198c35..0ead177a0 100644 --- a/app/models/temp_file.rb +++ b/app/models/temp_file.rb @@ -5,6 +5,12 @@ class TempFile < ApplicationRecord has_one_attached :file + def file_service_url + ActiveStorage::Current.set(host: Rails.application.secrets.mail_server_url) do + file.service_url + end + end + class << self def destroy_obsolete(temp_file_id) temp_file = find_by_id(temp_file_id) diff --git a/app/models/tiny_mce_asset.rb b/app/models/tiny_mce_asset.rb index e9ecf058b..e5470f192 100644 --- a/app/models/tiny_mce_asset.rb +++ b/app/models/tiny_mce_asset.rb @@ -102,6 +102,12 @@ class TinyMceAsset < ApplicationRecord image.variant(resize_to_limit: Constants::LARGE_PIC_FORMAT) end + def file_service_url + ActiveStorage::Current.set(host: Rails.application.secrets.mail_server_url) do + image.service_url + end + end + def self.delete_unsaved_image(id) asset = find_by(id: id) asset.destroy if asset && !asset.saved diff --git a/app/services/reports/docx/private_methods.rb b/app/services/reports/docx/private_methods.rb index 375fc1652..cbd18dddc 100644 --- a/app/services/reports/docx/private_methods.rb +++ b/app/services/reports/docx/private_methods.rb @@ -293,12 +293,7 @@ module Reports::Docx::PrivateMethods end def image_path(asset) - image = if asset.class == Asset - asset.file - else - asset.image - end - image.service_url + asset.file_service_url end def calculate_color_hsp(color) diff --git a/app/services/spreadsheet_parser.rb b/app/services/spreadsheet_parser.rb index 700697169..9f7ff7c35 100644 --- a/app/services/spreadsheet_parser.rb +++ b/app/services/spreadsheet_parser.rb @@ -8,7 +8,7 @@ class SpreadsheetParser file_path = file.path else filename = file.filename.to_s - file_path = file.service_url + file_path = file.file_service_url end case File.extname(filename) From 9c88327a16424b450651124a0c523fc0868c968d Mon Sep 17 00:00:00 2001 From: Urban Rotnik Date: Thu, 3 Oct 2019 11:00:59 +0200 Subject: [PATCH 2/3] Rename ActiveStorage base controller --- .../active_storage/blobs_controller.rb | 2 +- ...ontroller.rb => custom_base_controller.rb} | 2 +- .../active_storage/disk_controller.rb | 64 ------------------- .../representations_controller.rb | 2 +- 4 files changed, 3 insertions(+), 67 deletions(-) rename app/controllers/active_storage/{base_controller.rb => custom_base_controller.rb} (81%) delete mode 100644 app/controllers/active_storage/disk_controller.rb diff --git a/app/controllers/active_storage/blobs_controller.rb b/app/controllers/active_storage/blobs_controller.rb index a8077b0bb..f91541300 100644 --- a/app/controllers/active_storage/blobs_controller.rb +++ b/app/controllers/active_storage/blobs_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module ActiveStorage - class BlobsController < BaseController + class BlobsController < CustomBaseController include ActiveStorage::SetBlob include ActiveStorage::CheckBlobPermissions diff --git a/app/controllers/active_storage/base_controller.rb b/app/controllers/active_storage/custom_base_controller.rb similarity index 81% rename from app/controllers/active_storage/base_controller.rb rename to app/controllers/active_storage/custom_base_controller.rb index b9a3163ac..d5d8ce46f 100644 --- a/app/controllers/active_storage/base_controller.rb +++ b/app/controllers/active_storage/custom_base_controller.rb @@ -2,7 +2,7 @@ # The base controller for all ActiveStorage controllers. module ActiveStorage - class BaseController < ApplicationController + class CustomBaseController < ApplicationController include ActiveStorage::SetCurrent before_action do diff --git a/app/controllers/active_storage/disk_controller.rb b/app/controllers/active_storage/disk_controller.rb deleted file mode 100644 index 5c95db131..000000000 --- a/app/controllers/active_storage/disk_controller.rb +++ /dev/null @@ -1,64 +0,0 @@ -# frozen_string_literal: true - -module ActiveStorage - class DiskController < ActiveStorage::BaseController - skip_forgery_protection - skip_before_action :authenticate_user!, :authenticate_user_from_token!, only: :show # Skip authentication - - def show - if (key = decode_verified_key) - serve_file disk_service.path_for(key[:key]), content_type: key[:content_type], disposition: key[:disposition] - else - head :not_found - end - rescue Errno::ENOENT - head :not_found - end - - def update - if (token = decode_verified_token) - if acceptable_content?(token) - disk_service.upload token[:key], request.body, checksum: token[:checksum] - else - head :unprocessable_entity - end - else - head :not_found - end - rescue ActiveStorage::IntegrityError - head :unprocessable_entity - end - - private - - def disk_service - ActiveStorage::Blob.service - end - - def decode_verified_key - ActiveStorage.verifier.verified(params[:encoded_key], purpose: :blob_key) - end - - def serve_file(path, content_type:, disposition:) - Rack::File.new(nil).serving(request, path).tap do |(status, headers, body)| - self.status = status - self.response_body = body - - headers.each do |name, value| - response.headers[name] = value - end - - response.headers['Content-Type'] = content_type || DEFAULT_SEND_FILE_TYPE - response.headers['Content-Disposition'] = disposition || DEFAULT_SEND_FILE_DISPOSITION - end - end - - def decode_verified_token - ActiveStorage.verifier.verified(params[:encoded_token], purpose: :blob_token) - end - - def acceptable_content?(token) - token[:content_type] == request.content_mime_type && token[:content_length] == request.content_length - end - end -end diff --git a/app/controllers/active_storage/representations_controller.rb b/app/controllers/active_storage/representations_controller.rb index 1f652ce82..e1a1a4fa8 100644 --- a/app/controllers/active_storage/representations_controller.rb +++ b/app/controllers/active_storage/representations_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module ActiveStorage - class RepresentationsController < BaseController + class RepresentationsController < CustomBaseController include ActiveStorage::SetBlob include ActiveStorage::CheckBlobPermissions From 81d66ceedd433dc38386798aa143eb089688a22e Mon Sep 17 00:00:00 2001 From: Urban Rotnik Date: Thu, 3 Oct 2019 12:48:37 +0200 Subject: [PATCH 3/3] Add CustomDisk Service for ActiveStorage --- app/models/asset.rb | 6 ------ app/models/temp_file.rb | 6 ------ app/models/tiny_mce_asset.rb | 6 ------ app/services/reports/docx/private_methods.rb | 8 ++++---- app/services/spreadsheet_parser.rb | 2 +- config/storage.yml | 4 ++-- lib/active_storage/service/custom_disk_service.rb | 14 ++++++++++++++ 7 files changed, 21 insertions(+), 25 deletions(-) create mode 100644 lib/active_storage/service/custom_disk_service.rb diff --git a/app/models/asset.rb b/app/models/asset.rb index 62487b0ce..1335624fb 100644 --- a/app/models/asset.rb +++ b/app/models/asset.rb @@ -243,12 +243,6 @@ class Asset < ApplicationRecord to_asset.post_process_file(to_asset.team) end - def file_service_url - ActiveStorage::Current.set(host: Rails.application.secrets.mail_server_url) do - file.service_url - end - end - def extract_image_quality return unless ['image/jpeg', 'image/pjpeg'].include? content_type diff --git a/app/models/temp_file.rb b/app/models/temp_file.rb index 0ead177a0..8ed198c35 100644 --- a/app/models/temp_file.rb +++ b/app/models/temp_file.rb @@ -5,12 +5,6 @@ class TempFile < ApplicationRecord has_one_attached :file - def file_service_url - ActiveStorage::Current.set(host: Rails.application.secrets.mail_server_url) do - file.service_url - end - end - class << self def destroy_obsolete(temp_file_id) temp_file = find_by_id(temp_file_id) diff --git a/app/models/tiny_mce_asset.rb b/app/models/tiny_mce_asset.rb index e5470f192..e9ecf058b 100644 --- a/app/models/tiny_mce_asset.rb +++ b/app/models/tiny_mce_asset.rb @@ -102,12 +102,6 @@ class TinyMceAsset < ApplicationRecord image.variant(resize_to_limit: Constants::LARGE_PIC_FORMAT) end - def file_service_url - ActiveStorage::Current.set(host: Rails.application.secrets.mail_server_url) do - image.service_url - end - end - def self.delete_unsaved_image(id) asset = find_by(id: id) asset.destroy if asset && !asset.saved diff --git a/app/services/reports/docx/private_methods.rb b/app/services/reports/docx/private_methods.rb index cbd18dddc..292c6f00f 100644 --- a/app/services/reports/docx/private_methods.rb +++ b/app/services/reports/docx/private_methods.rb @@ -98,7 +98,7 @@ module Reports::Docx::PrivateMethods image = TinyMceAsset.find_by(id: Base62.decode(elem.attributes['data-mce-token'].value)) next unless image - image_path = image_path(image) + image_path = image_path(image.image) dimension = FastImage.size(image_path) style = image_styling(elem, dimension) @@ -204,7 +204,7 @@ module Reports::Docx::PrivateMethods def asset_image_preparing(asset) return unless asset - image_path = image_path(asset) + image_path = image_path(asset.file) dimension = FastImage.size(image_path) x = dimension[0] @@ -292,8 +292,8 @@ module Reports::Docx::PrivateMethods } end - def image_path(asset) - asset.file_service_url + def image_path(attachment) + attachment.service_url end def calculate_color_hsp(color) diff --git a/app/services/spreadsheet_parser.rb b/app/services/spreadsheet_parser.rb index 9f7ff7c35..700697169 100644 --- a/app/services/spreadsheet_parser.rb +++ b/app/services/spreadsheet_parser.rb @@ -8,7 +8,7 @@ class SpreadsheetParser file_path = file.path else filename = file.filename.to_s - file_path = file.file_service_url + file_path = file.service_url end case File.extname(filename) diff --git a/config/storage.yml b/config/storage.yml index fa3150876..964c17ebe 100644 --- a/config/storage.yml +++ b/config/storage.yml @@ -1,9 +1,9 @@ test: - service: Disk + service: CustomDisk root: <%= Rails.root.join("tmp/storage") %> local: - service: Disk + service: CustomDisk root: <%= Rails.root.join("storage") %> amazon: diff --git a/lib/active_storage/service/custom_disk_service.rb b/lib/active_storage/service/custom_disk_service.rb new file mode 100644 index 000000000..02119e0b2 --- /dev/null +++ b/lib/active_storage/service/custom_disk_service.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'active_storage/service/disk_service' + +module ActiveStorage + class Service::CustomDiskService < Service::DiskService + def current_host + host = ActiveStorage::Current.host + host ||= Rails.application.secrets.mail_server_url + host = "http://#{host}" unless host.match?(/^http/) + host + end + end +end