class ActiveModel::Validations::FileContentTypeValidator

Constants

CHECKS
SUPPORTED_MODES

Public Class Methods

helper_method_name() click to toggle source
# File lib/file_validators/validators/file_content_type_validator.rb, line 9
def self.helper_method_name
  :validates_file_content_type
end

Public Instance Methods

check_validity!() click to toggle source
# File lib/file_validators/validators/file_content_type_validator.rb, line 36
def check_validity!
  unless (CHECKS & options.keys).present?
    raise ArgumentError, 'You must at least pass in :allow or :exclude option'
  end

  options.slice(*CHECKS).each do |option, value|
    unless value.is_a?(String) || value.is_a?(Array) || value.is_a?(Regexp) || value.is_a?(Proc)
      raise ArgumentError, ":#{option} must be a string, an array, a regex or a proc"
    end
  end
end
validate_each(record, attribute, value) click to toggle source
# File lib/file_validators/validators/file_content_type_validator.rb, line 13
def validate_each(record, attribute, value)
  begin
    values = parse_values(value)
  rescue JSON::ParserError
    record.errors.add attribute, :invalid
    return
  end

  return if values.empty?

  mode = option_value(record, :mode)
  tool = option_value(record, :tool) || SUPPORTED_MODES[mode]

  allowed_types = option_content_types(record, :allow)
  forbidden_types = option_content_types(record, :exclude)

  values.each do |val|
    content_type = get_content_type(val, tool)
    validate_whitelist(record, attribute, content_type, allowed_types)
    validate_blacklist(record, attribute, content_type, forbidden_types)
  end
end

Private Instance Methods

get_content_type(value, tool) click to toggle source
# File lib/file_validators/validators/file_content_type_validator.rb, line 58
def get_content_type(value, tool)
  if tool.present?
    FileValidators::MimeTypeAnalyzer.new(tool).call(value)
  else
    value = OpenStruct.new(value) if value.is_a?(Hash)
    value.content_type
  end
end
mark_invalid(record, attribute, error, option_types) click to toggle source
# File lib/file_validators/validators/file_content_type_validator.rb, line 87
def mark_invalid(record, attribute, error, option_types)
  error_options = options.merge(types: option_types.join(', '))
  unless record.errors.added?(attribute, error, error_options)
    record.errors.add attribute, error, **error_options
  end
end
option_content_types(record, key) click to toggle source
# File lib/file_validators/validators/file_content_type_validator.rb, line 67
def option_content_types(record, key)
  [option_value(record, key)].flatten.compact
end
option_value(record, key) click to toggle source
# File lib/file_validators/validators/file_content_type_validator.rb, line 71
def option_value(record, key)
  options[key].is_a?(Proc) ? options[key].call(record) : options[key]
end
parse_values(value) click to toggle source
# File lib/file_validators/validators/file_content_type_validator.rb, line 50
def parse_values(value)
  return [] unless value.present?

  value = JSON.parse(value) if value.is_a?(String)

  Array.wrap(value).reject(&:blank?)
end
validate_blacklist(record, attribute, content_type, forbidden_types) click to toggle source
# File lib/file_validators/validators/file_content_type_validator.rb, line 81
def validate_blacklist(record, attribute, content_type, forbidden_types)
  if forbidden_types.any? { |type| type === content_type }
    mark_invalid record, attribute, :excluded_file_content_types, forbidden_types
  end
end
validate_whitelist(record, attribute, content_type, allowed_types) click to toggle source
# File lib/file_validators/validators/file_content_type_validator.rb, line 75
def validate_whitelist(record, attribute, content_type, allowed_types)
  if allowed_types.present? && allowed_types.none? { |type| type === content_type }
    mark_invalid record, attribute, :allowed_file_content_types, allowed_types
  end
end