1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-20 09:52:19 +01:00

WIP: enforce mime type checking for uploads

This commit is contained in:
Sylvain 2020-06-02 19:18:57 +02:00
parent 45013be950
commit ebe602ad1c
19 changed files with 58 additions and 86 deletions

View File

@ -56,7 +56,7 @@ class API::MembersController < API::ApiController
if members_service.update(user_params)
# Update password without logging out
sign_in(@member, bypass: true) unless current_user.id != params[:id].to_i
bypass_sign_in(@member) unless current_user.id != params[:id].to_i
render :show, status: :ok, location: member_path(@member)
else
render json: @member.errors, status: :unprocessable_entity

View File

@ -10,7 +10,6 @@ class Import < ApplicationRecord
belongs_to :user
validates :attachment, file_size: { maximum: Rails.application.secrets.max_import_size&.to_i || 5.megabytes.to_i }
validates :attachment, file_mime_type: { content_type: %w[text/csv text/comma-separated-values application/vnd.ms-excel] }
after_commit :proceed_import, on: [:create]

View File

@ -5,5 +5,4 @@ class ProjectCao < Asset
mount_uploader :attachment, ProjectCaoUploader
validates :attachment, file_size: { maximum: Rails.application.secrets.max_cao_size&.to_i || 5.megabytes.to_i }
validates :attachment, file_mime_type: { content_type: ENV['ALLOWED_MIME_TYPES'].split(' ') }
end

View File

@ -4,6 +4,4 @@
class ProjectImage < Asset
include ImageValidatorConcern
mount_uploader :attachment, ProjectImageUploader
validates :attachment, file_mime_type: { content_type: /image/ }
end

View File

@ -4,6 +4,4 @@
class ProjectStepImage < Asset
include ImageValidatorConcern
mount_uploader :attachment, ProjectImageUploader
validates :attachment, file_mime_type: { content_type: /image/ }
end

View File

@ -51,6 +51,10 @@ class CustomAssetsUploader < CarrierWave::Uploader::Base
%w[pdf png jpeg jpg ico]
end
def content_type_whitelist
[%r{image/}, 'application/pdf']
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename

View File

@ -44,6 +44,11 @@ class EventFileUploader < CarrierWave::Uploader::Base
%w[pdf]
end
def content_type_whitelist
%w[application/pdf]
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename

View File

@ -62,6 +62,11 @@ class EventImageUploader < CarrierWave::Uploader::Base
%w[jpg jpeg gif png]
end
def content_type_whitelist
[%r{image/}]
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename

View File

@ -25,4 +25,9 @@ class ImportUploader < CarrierWave::Uploader::Base
def extension_whitelist
%w[csv]
end
def content_type_whitelist
%w[text/csv]
end
end

View File

@ -44,6 +44,11 @@ class MachineFileUploader < CarrierWave::Uploader::Base
%w[pdf]
end
def content_type_whitelist
%w[application/pdf]
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename

View File

@ -54,6 +54,10 @@ class MachineImageUploader < CarrierWave::Uploader::Base
%w[jpg jpeg gif png]
end
def content_type_whitelist
[%r{image/}]
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename

View File

@ -44,6 +44,10 @@ class PlanFileUploader < CarrierWave::Uploader::Base
%w[pdf png jpeg jpg]
end
def content_type_whitelist
[%r{image/}, 'application/pdf']
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename

View File

@ -58,6 +58,10 @@ class ProfilImageUploader < CarrierWave::Uploader::Base
%w[jpg jpeg gif png]
end
def content_type_whitelist
[%r{image/}]
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename

View File

@ -25,4 +25,8 @@ class ProjectCaoUploader < CarrierWave::Uploader::Base
def extension_whitelist
ENV['ALLOWED_EXTENSIONS'].split(' ')
end
def content_type_whitelist
ENV['ALLOWED_MIME_TYPES'].split(' ')
end
end

View File

@ -32,6 +32,10 @@ class ProjectImageUploader < CarrierWave::Uploader::Base
%w[jpg jpeg gif png]
end
def content_type_whitelist
[%r{image/}]
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename

View File

@ -44,6 +44,11 @@ class SpaceFileUploader < CarrierWave::Uploader::Base
%w[pdf]
end
def content_type_whitelist
%w[application/pdf]
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename

View File

@ -54,6 +54,10 @@ class SpaceImageUploader < CarrierWave::Uploader::Base
%w[jpg jpeg gif png]
end
def content_type_whitelist
[%r{image/}]
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename

View File

@ -54,6 +54,10 @@ class TrainingImageUploader < CarrierWave::Uploader::Base
%w[jpg jpeg gif png]
end
def content_type_whitelist
[%r{image/}]
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
def filename

View File

@ -1,79 +0,0 @@
# frozen_string_literal: true
# Based on: https://gist.github.com/1298417
class FileMimeTypeValidator < ActiveModel::EachValidator
MESSAGES = { content_type: :wrong_content_type }.freeze
CHECKS = [:content_type].freeze
DEFAULT_TOKENIZER = ->(value) { value.split(//) }
RESERVED_OPTIONS = %i[content_type tokenizer].freeze
def initialize(options)
super
end
def check_validity!
keys = CHECKS & options.keys
raise ArgumentError, 'Patterns unspecified. Specify the :content_type option.' if keys.empty?
keys.each do |key|
value = options[key]
raise ArgumentError, ":#{key} must be a String or a Regexp or an Array" unless valid_content_type_option?(value)
next unless key.is_a?(Array) && key == :content_type
options[key].each do |val|
raise ArgumentError, "#{val} must be a String or a Regexp" unless val.is_a?(String) || val.is_a?(Regexp)
end
end
end
def validate_each(record, attribute, value)
raise(ArgumentError, 'A CarrierWave::Uploader::Base object was expected') unless value.is_a? CarrierWave::Uploader::Base
value = (options[:tokenizer] || DEFAULT_TOKENIZER).call(value) if value.is_a?(String)
return if value.length.zero?
CHECKS.each do |key|
next unless check_value = options[key]
do_validation(value, check_value, key, record, attribute) if key == :content_type
end
end
def help
Helper.instance
end
class Helper
include Singleton
include ActionView::Helpers::NumberHelper
end
private
def valid_content_type_option?(content_type)
return true if %w[Array String Regexp].include?(content_type.class.to_s)
false
end
def do_validation(value, pattern, key, record, attribute)
if pattern.is_a?(String) || pattern.is_a?(Regexp)
return if value.file.content_type.send((pattern.is_a?(String) ? '==' : '=~'), pattern)
else
valid_list = pattern.map do |p|
value.file.content_type.send((p.is_a?(String) ? '==' : '=~'), p)
end
return if valid_list.include?(true)
end
errors_options = options.except(*RESERVED_OPTIONS)
default_message = options[MESSAGES[key]]
errors_options[:message] ||= default_message if default_message
record.errors.add(attribute, MESSAGES[key], errors_options)
end
end