Class: UploaderContentTypeValidator

Inherits:
ActiveModel::Validations::FileContentTypeValidator 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.

Instance Method Summary collapse

Methods inherited from ActiveModel::Validations::FileContentTypeValidator

#mark_invalid_original

Instance Method Details

#check_validity!Object

rubocop: enable Metrics/CyclomaticComplexity



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

def check_validity!; end

#validate_each(record, attribute, value) ⇒ Object

rubocop: disable Metrics/CyclomaticComplexity



7
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
# File 'app/validators/uploader_content_type_validator.rb', line 7

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.attached_uploader(attribute) || record.send(attribute)
  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