scinote-web/config/initializers/paperclip.rb
Matej Zrimšek e3a7f45fdf Merge branch 'master' into mz_file_upload_and_client_side_upgrade
Conflicts:
	app/assets/javascripts/application.js
	app/views/results/_result_asset.html.erb
	app/views/steps/_step.html.erb
2016-08-26 11:13:40 +02:00

172 lines
5.5 KiB
Ruby

if ENV['PAPERCLIP_HASH_SECRET'].nil?
puts "WARNING! Environment variable PAPERCLIP_HASH_SECRET must be set."
exit 1
end
Paperclip::Attachment.default_options.merge!({
hash_data: ':class/:attachment/:id/:style',
hash_secret: ENV['PAPERCLIP_HASH_SECRET'],
preserve_files: false,
url: '/system/:class/:attachment/:id_partition/:hash/:style/:filename'
})
if ENV['PAPERCLIP_STORAGE'] == "s3"
if ENV['S3_BUCKET'].nil? or ENV['AWS_REGION'].nil? or
ENV['AWS_ACCESS_KEY_ID'].nil? or ENV['AWS_SECRET_ACCESS_KEY'].nil?
puts "WARNING! Environment variables S3_BUCKET, AWS_REGION, " +
"AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY must be set."
exit 1
end
Paperclip::Attachment.default_options.merge!({
url: ':s3_domain_url',
path: '/:class/:attachment/:id_partition/:hash/:style/:filename',
storage: :s3,
s3_host_name: "s3.#{ENV['AWS_REGION']}.amazonaws.com",
s3_protocol: 'https',
s3_credentials: {
bucket: ENV['S3_BUCKET'],
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
},
s3_permissions: {
original: :private,
medium: :private
},
s3_storage_class: {
medium: :reduced_redundancy,
thumb: :reduced_redundancy,
icon: :reduced_redundancy,
icon_small: :reduced_redundancy
}
})
elsif ENV['PAPERCLIP_STORAGE'] == "filesystem"
Paperclip::Attachment.default_options.merge!({
storage: :filesystem
})
end
Paperclip::Attachment.class_eval do
def is_stored_on_s3?
options[:storage].to_sym == :s3
end
def fetch
Paperclip.io_adapters.for self
end
end
module Paperclip
# Checks file for spoofing
class MediaTypeSpoofDetector
def spoofed?
if has_name? && has_extension? && (media_type_mismatch? ||
mapping_override_mismatch?)
Paperclip.log("Content Type Spoof: Filename #{File.basename(@name)} "\
"(#{supplied_content_type} from Headers, #{content_types_from_name} "\
"from Extension), content type discovered: "\
"#{calculated_content_type}. See documentation to allow this "\
"combination.")
true
else
false
end
end
private
# Determine file content type from its name
def content_types_from_name
@content_types_from_name ||=
Paperclip.run('mimetype', '-b :file_name', file_name: @name).chomp
end
# Determine file media type from its name
def media_types_from_name
@media_types_from_name ||= extract_media_type content_types_from_name
end
# Determine file content type from mimetype command
def type_from_mimetype_command
@type_from_mimetype_command ||=
Paperclip.run('mimetype', '-b :file', file: @file.path).chomp
end
# Determine file media type from mimetype command
def media_type_from_mimetype_command
@media_type_from_mimetype_command ||=
extract_media_type type_from_mimetype_command
end
# Determine file content type from it's content (file and mimetype command)
def type_from_file_command
unless defined? @type_from_file_command
@type_from_file_command =
Paperclip.run('file', '-b --mime :file', file: @file.path)
.split(/[:;]\s+/).first
if allowed_spoof_exception?(@type_from_file_command,
media_type_from_file_command) ||
(@type_from_file_command.in?(%w(text/plain text/html)) &&
media_type_from_mimetype_command.in?(%w(text application)))
# File content type is generalized, so rely on file extension for
# correct/more specific content type
@type_from_file_command = type_from_mimetype_command
end
end
@type_from_file_command
rescue Cocaine::CommandLineError
''
end
# Determine file media type from it's content (file and mimetype command)
def media_type_from_file_command
@media_type_from_file_command ||=
extract_media_type type_from_file_command
end
def extract_media_type(content_type)
if content_type.empty?
''
else
content_type.split('/').first
end
end
# Checks file media type mismatch between file's name and header
def supplied_type_mismatch?
!allowed_spoof_exception?(supplied_content_type, supplied_media_type) &&
media_types_from_name != supplied_media_type
end
# Checks file media type mismatch between file's name and content
def calculated_type_mismatch?
!allowed_spoof_exception?(calculated_content_type,
calculated_media_type) &&
media_types_from_name != calculated_media_type
end
# Checks file content type mismatch between file's name and content
def mapping_override_mismatch?
!allowed_spoof_exception?(calculated_content_type,
calculated_media_type) &&
content_types_from_name != calculated_content_type
end
# Check if we have a file spoof exception which is allowed/safe
def allowed_spoof_exception?(content_type, media_type)
content_type == 'application/octet-stream' ||
(content_type == 'inode/x-empty' && @file.size.zero?) ||
(content_type == 'text/x-c' &&
content_types_from_name == 'text/x-java') ||
(media_type.in?(%w(image audio video)) &&
media_type == media_types_from_name) ||
(content_types_from_name.in? %W(#{}
text/plain
application/octet-stream))
end
end
end