Class: MiniDefender::Rules::Url

Inherits:
MiniDefender::Rule show all
Defined in:
lib/mini_defender/rules/url.rb

Constant Summary collapse

ALLOWED_MODIFIERS =
%w[https public not_ip not_private]

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from MiniDefender::Rule

#active?, available?, #bails?, #coerce, #default_value, #defaults?, #error_message, #excluded?, #force_coerce?, #implicit?, #priority, #stops?, #with_message

Constructor Details

#initialize(modifiers = []) ⇒ Url

Returns a new instance of Url.



10
11
12
13
14
15
16
17
18
# File 'lib/mini_defender/rules/url.rb', line 10

def initialize(modifiers = [])
  @modifiers = Array(modifiers).map(&:to_s)

  unless @modifiers.empty?
    validate_modifiers!
  end

  @validation_error = nil
end

Class Method Details

.make(modifiers) ⇒ Object

no need to raise an error when no modifier is entered; as ‘url’ rule checks URL structure on its own



24
25
26
# File 'lib/mini_defender/rules/url.rb', line 24

def self.make(modifiers) # no need to raise an error when no modifier is entered; as 'url' rule checks URL structure on its own
  new(modifiers)
end

.signatureObject



20
21
22
# File 'lib/mini_defender/rules/url.rb', line 20

def self.signature
  'url'
end

Instance Method Details

#message(attribute, value, validator) ⇒ Object



78
79
80
# File 'lib/mini_defender/rules/url.rb', line 78

def message(attribute, value, validator)
  @validation_error || 'The field must contain a valid URL.'
end

#passes?(attribute, value, validator) ⇒ Boolean

Returns:



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/mini_defender/rules/url.rb', line 28

def passes?(attribute, value, validator)
  unless value.is_a?(String)
    return false
  end

  begin
    uri = URI.parse(value)

    if uri.host.blank? || uri.scheme.blank?
      return false
    end

    unless %w[http https].include?(uri.scheme)
      @validation_error = 'URL protocol must be HTTP or HTTPS.'
      return false
    end

    if @modifiers.empty?
      return true
    end

    if @modifiers.include?('https') && uri.scheme != 'https'
      @validation_error = 'The URL must use HTTPS.'
      return false
    end

    if @modifiers.include?('public') && (!PublicSuffix.valid?(uri.host) || private_network?(uri.host))
      @validation_error = 'The URL must use a valid public domain.'
      return false
    end

    if @modifiers.include?('not_ip') && ip_address?(uri.host)
      @validation_error = 'IP addresses are not allowed in URLs.'
      return false
    end

    if @modifiers.include?('not_private') && private_network?(uri.host)
      @validation_error = 'Private or reserved resources are not allowed.'
      return false
    end

    true
  rescue URI::InvalidURIError
    @validation_error = 'The field must contain a valid URL.'
    false
  rescue PublicSuffix::Error
    false
  end
end

#private_network?(host) ⇒ Boolean

Returns:



82
83
84
85
86
87
88
89
90
# File 'lib/mini_defender/rules/url.rb', line 82

def private_network?(host)
  unless host
    return false
  end

  host = host.downcase

  private_patterns.any? { |pattern| pattern.match?(host) }
end