Class: UploaderContentTypeValidator

Inherits:
ActiveModel::Validations::FileContentTypeValidator
  • Object
show all
Defined in:
app/validators/uploader_content_type_validator.rb

Overview

This validator ensures the files to be uploaded match the attached uploader’s content types. This prevents CarrierWave from uploading the records before they pass the content type validations.

Instance Method Summary collapse

Instance Method Details

#check_validity!Object

rubocop: enable Metrics/CyclomaticComplexity



45
# File 'app/validators/uploader_content_type_validator.rb', line 45

def check_validity!; end

#validate_each(record, attribute, value) ⇒ Object

rubocop: disable Metrics/CyclomaticComplexity



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'app/validators/uploader_content_type_validator.rb', line 8

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?

  uploader = record.send(attribute)
  return unless uploader
  return unless uploader.is_a?(Decidim::ApplicationUploader)

  mode = option_value(record, :mode)
  allowed_types = uploader.content_type_allowlist || []
  forbidden_types = uploader.content_type_denylist || []

  values.each do |val|
    val_mode = mode

    # The :strict mode would be more robust for the content type detection if
    # the value does not know its own content type. However, this would
    # require the command line utility named `file` which is only available in
    # *nix. This would also require adding a new gem dependency for running
    # the CLI utility, Terrapin or Cocaine in older versions of the
    # file_validators gem. The :relaxed mode detects the content type based on
    # the file extension through the mime-types gem.
    val_mode = :relaxed if val_mode.blank? && !val.respond_to?(:content_type)

    content_type = get_content_type(val, val_mode)
    validate_whitelist(record, attribute, content_type, allowed_types)
    validate_blacklist(record, attribute, content_type, forbidden_types)
  end
end