mini_defender 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +70 -0
- data/LICENSE.md +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +33 -0
- data/RULES.md +92 -0
- data/Rakefile +12 -0
- data/lib/mini_defender/extensions/enumerable.rb +34 -0
- data/lib/mini_defender/extensions/hash.rb +28 -0
- data/lib/mini_defender/rule.rb +77 -0
- data/lib/mini_defender/rules/accepted.rb +17 -0
- data/lib/mini_defender/rules/accepted_if.rb +26 -0
- data/lib/mini_defender/rules/alpha.rb +15 -0
- data/lib/mini_defender/rules/alpha_dash.rb +15 -0
- data/lib/mini_defender/rules/alpha_num.rb +15 -0
- data/lib/mini_defender/rules/array.rb +15 -0
- data/lib/mini_defender/rules/bail.rb +19 -0
- data/lib/mini_defender/rules/between.rb +29 -0
- data/lib/mini_defender/rules/boolean.rb +26 -0
- data/lib/mini_defender/rules/confirmed.rb +24 -0
- data/lib/mini_defender/rules/country_code.rb +23 -0
- data/lib/mini_defender/rules/credit_card.rb +13 -0
- data/lib/mini_defender/rules/date.rb +27 -0
- data/lib/mini_defender/rules/date_eq.rb +43 -0
- data/lib/mini_defender/rules/date_format.rb +38 -0
- data/lib/mini_defender/rules/date_gt.rb +24 -0
- data/lib/mini_defender/rules/date_gte.rb +24 -0
- data/lib/mini_defender/rules/date_lt.rb +24 -0
- data/lib/mini_defender/rules/date_lte.rb +24 -0
- data/lib/mini_defender/rules/declined.rb +17 -0
- data/lib/mini_defender/rules/declined_if.rb +26 -0
- data/lib/mini_defender/rules/default.rb +33 -0
- data/lib/mini_defender/rules/different.rb +31 -0
- data/lib/mini_defender/rules/digits.rb +26 -0
- data/lib/mini_defender/rules/digits_between.rb +29 -0
- data/lib/mini_defender/rules/distinct.rb +18 -0
- data/lib/mini_defender/rules/email.rb +19 -0
- data/lib/mini_defender/rules/ending_with.rb +31 -0
- data/lib/mini_defender/rules/equal.rb +9 -0
- data/lib/mini_defender/rules/excluded.rb +15 -0
- data/lib/mini_defender/rules/excluded_if.rb +28 -0
- data/lib/mini_defender/rules/excluded_unless.rb +28 -0
- data/lib/mini_defender/rules/excluded_with.rb +27 -0
- data/lib/mini_defender/rules/excluded_without.rb +27 -0
- data/lib/mini_defender/rules/exists.rb +29 -0
- data/lib/mini_defender/rules/expiry_date.rb +28 -0
- data/lib/mini_defender/rules/file.rb +17 -0
- data/lib/mini_defender/rules/filled.rb +22 -0
- data/lib/mini_defender/rules/greater_than.rb +34 -0
- data/lib/mini_defender/rules/greater_than_or_equal.rb +34 -0
- data/lib/mini_defender/rules/hash.rb +15 -0
- data/lib/mini_defender/rules/image.rb +19 -0
- data/lib/mini_defender/rules/in.rb +27 -0
- data/lib/mini_defender/rules/in_field.rb +40 -0
- data/lib/mini_defender/rules/integer.rb +19 -0
- data/lib/mini_defender/rules/ip.rb +43 -0
- data/lib/mini_defender/rules/ipv4.rb +43 -0
- data/lib/mini_defender/rules/ipv6.rb +43 -0
- data/lib/mini_defender/rules/json.rb +19 -0
- data/lib/mini_defender/rules/less_than.rb +34 -0
- data/lib/mini_defender/rules/less_than_or_equal.rb +34 -0
- data/lib/mini_defender/rules/luhn.rb +33 -0
- data/lib/mini_defender/rules/mac_address.rb +39 -0
- data/lib/mini_defender/rules/max.rb +9 -0
- data/lib/mini_defender/rules/max_digits.rb +32 -0
- data/lib/mini_defender/rules/mime_types.rb +37 -0
- data/lib/mini_defender/rules/min.rb +9 -0
- data/lib/mini_defender/rules/min_digits.rb +32 -0
- data/lib/mini_defender/rules/national_id.rb +13 -0
- data/lib/mini_defender/rules/not_ending_with.rb +31 -0
- data/lib/mini_defender/rules/not_in.rb +27 -0
- data/lib/mini_defender/rules/not_regex.rb +27 -0
- data/lib/mini_defender/rules/not_starting_with.rb +31 -0
- data/lib/mini_defender/rules/numeric.rb +19 -0
- data/lib/mini_defender/rules/present.rb +19 -0
- data/lib/mini_defender/rules/prohibited.rb +15 -0
- data/lib/mini_defender/rules/prohibited_if.rb +32 -0
- data/lib/mini_defender/rules/prohibited_unless.rb +32 -0
- data/lib/mini_defender/rules/regex.rb +27 -0
- data/lib/mini_defender/rules/required.rb +32 -0
- data/lib/mini_defender/rules/required_if.rb +26 -0
- data/lib/mini_defender/rules/required_unless.rb +26 -0
- data/lib/mini_defender/rules/required_with.rb +27 -0
- data/lib/mini_defender/rules/required_with_all.rb +27 -0
- data/lib/mini_defender/rules/required_without.rb +27 -0
- data/lib/mini_defender/rules/required_without_all.rb +27 -0
- data/lib/mini_defender/rules/size.rb +45 -0
- data/lib/mini_defender/rules/starting_with.rb +31 -0
- data/lib/mini_defender/rules/string.rb +15 -0
- data/lib/mini_defender/rules/timezone.rb +19 -0
- data/lib/mini_defender/rules/unique.rb +37 -0
- data/lib/mini_defender/rules/url.rb +17 -0
- data/lib/mini_defender/rules/uuid.rb +37 -0
- data/lib/mini_defender/rules.rb +8 -0
- data/lib/mini_defender/rules_expander.rb +19 -0
- data/lib/mini_defender/rules_factory.rb +36 -0
- data/lib/mini_defender/validates_input.rb +12 -0
- data/lib/mini_defender/validation_error.rb +10 -0
- data/lib/mini_defender/validator.rb +127 -0
- data/lib/mini_defender/version.rb +5 -0
- data/lib/mini_defender.rb +24 -0
- data/mini_defender.gemspec +38 -0
- data/sig/mini_defender.rbs +4 -0
- metadata +206 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
class MiniDefender::Rules::Date < MiniDefender::Rule
|
6
|
+
def self.signature
|
7
|
+
'date'
|
8
|
+
end
|
9
|
+
|
10
|
+
def passes?(attribute, value, validator)
|
11
|
+
parse_date(value).is_a?(Time)
|
12
|
+
rescue ArgumentError
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
def message(attribute, value, validator)
|
17
|
+
'The given value is not a valid date.'
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def parse_date(date)
|
23
|
+
date = date.to_time if date.is_a?(Date)
|
24
|
+
date = Time.parse(date) unless date.is_a?(Time)
|
25
|
+
date
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
class MiniDefender::Rules::DateEq < MiniDefender::Rule
|
6
|
+
def initialize(target_date)
|
7
|
+
@target_date = parse_date(target_date)
|
8
|
+
@valid_value = false
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.signature
|
12
|
+
'date_eq'
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.make(args)
|
16
|
+
raise ArgumentError, 'Target date is required for date rules.' unless args == 1
|
17
|
+
|
18
|
+
self.new(args[0])
|
19
|
+
end
|
20
|
+
|
21
|
+
def passes?(attribute, value, validator)
|
22
|
+
value = parse_date(value)
|
23
|
+
@valid_value = true
|
24
|
+
|
25
|
+
value == @target_date
|
26
|
+
rescue ArgumentError
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
def message(attribute, value, validator)
|
31
|
+
return "The given value is not a valid date." unless @valid_value
|
32
|
+
|
33
|
+
"The value must be equal to #{@target_date}."
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
def parse_date(date)
|
39
|
+
date = date.to_time if date.is_a?(Date)
|
40
|
+
date = Time.parse(date) unless date.is_a?(Time)
|
41
|
+
date
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
class MiniDefender::Rules::DateFormat < MiniDefender::Rule
|
6
|
+
def initialize(format)
|
7
|
+
raise ArgumentError, 'Format must be a string' unless format.is_a?(String)
|
8
|
+
raise ArgumentError, 'Format is required for this rule' if format.empty?
|
9
|
+
|
10
|
+
@format = format
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.signature
|
14
|
+
'date_format'
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.make(args)
|
18
|
+
self.new(args[0])
|
19
|
+
end
|
20
|
+
|
21
|
+
def passes?(attribute, value, validator)
|
22
|
+
parse_date(value).is_a?(Time)
|
23
|
+
rescue ArgumentError
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
def message(attribute, value, validator)
|
28
|
+
'The given value is not a valid date.'
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def parse_date(date)
|
34
|
+
date = date.to_time if date.is_a?(Date)
|
35
|
+
date = Time.strptime(date, @format) unless date.is_a?(Time)
|
36
|
+
date
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'date_eq'
|
4
|
+
|
5
|
+
class MiniDefender::Rules::DateGt < MiniDefender::Rules::DateEq
|
6
|
+
def self.signature
|
7
|
+
'date_gt'
|
8
|
+
end
|
9
|
+
|
10
|
+
def passes?(attribute, value, validator)
|
11
|
+
value = parse_date(value)
|
12
|
+
@valid_value = true
|
13
|
+
|
14
|
+
value > @target_date
|
15
|
+
rescue ArgumentError
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def message(attribute, value, validator)
|
20
|
+
return "The given value is not a valid date." unless @valid_value
|
21
|
+
|
22
|
+
"The value must be greater than #{@target_date}."
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'date_eq'
|
4
|
+
|
5
|
+
class MiniDefender::Rules::DateGte < MiniDefender::Rules::DateEq
|
6
|
+
def self.signature
|
7
|
+
'date_gte'
|
8
|
+
end
|
9
|
+
|
10
|
+
def passes?(attribute, value, validator)
|
11
|
+
value = parse_date(value)
|
12
|
+
@valid_value = true
|
13
|
+
|
14
|
+
value >= @target_date
|
15
|
+
rescue ArgumentError
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def message(attribute, value, validator)
|
20
|
+
return "The given value is not a valid date." unless @valid_value
|
21
|
+
|
22
|
+
"The value must be greater than or equal to #{@target_date}."
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'date_eq'
|
4
|
+
|
5
|
+
class MiniDefender::Rules::DateLt < MiniDefender::Rules::DateEq
|
6
|
+
def self.signature
|
7
|
+
'date_lt'
|
8
|
+
end
|
9
|
+
|
10
|
+
def passes?(attribute, value, validator)
|
11
|
+
value = parse_date(value)
|
12
|
+
@valid_value = true
|
13
|
+
|
14
|
+
value < @target_date
|
15
|
+
rescue ArgumentError
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def message(attribute, value, validator)
|
20
|
+
return "The given value is not a valid date." unless @valid_value
|
21
|
+
|
22
|
+
"The value must be less than #{@target_date}."
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'date_eq'
|
4
|
+
|
5
|
+
class MiniDefender::Rules::DateLte < MiniDefender::Rules::DateEq
|
6
|
+
def self.signature
|
7
|
+
'date_lte'
|
8
|
+
end
|
9
|
+
|
10
|
+
def passes?(attribute, value, validator)
|
11
|
+
value = parse_date(value)
|
12
|
+
@valid_value = true
|
13
|
+
|
14
|
+
value <= @target_date
|
15
|
+
rescue ArgumentError
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def message(attribute, value, validator)
|
20
|
+
return "The given value is not a valid date." unless @valid_value
|
21
|
+
|
22
|
+
"The value must be less than or equal to #{@target_date}."
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::Declined < MiniDefender::Rule
|
4
|
+
ALLOWED_VALUES = ['no', 'off', 0, false]
|
5
|
+
|
6
|
+
def self.signature
|
7
|
+
'declined'
|
8
|
+
end
|
9
|
+
|
10
|
+
def passes?(attribute, value, validator)
|
11
|
+
!value.nil? && ALLOWED_VALUES.include?(value)
|
12
|
+
end
|
13
|
+
|
14
|
+
def message(attribute, value, validator)
|
15
|
+
"Must be declined."
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'declined'
|
4
|
+
|
5
|
+
class MiniDefender::Rules::DeclinedIf < MiniDefender::Rules::Declined
|
6
|
+
def initialize(target, value)
|
7
|
+
raise ArgumentError, 'Target must be a string' unless target.is_a?(String)
|
8
|
+
|
9
|
+
@target = target
|
10
|
+
@value = value
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.signature
|
14
|
+
'declined_if'
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.make(args)
|
18
|
+
raise ArgumentError, 'Target and expected value are required.' unless args.length == 2
|
19
|
+
|
20
|
+
self.new(args[0], args[1])
|
21
|
+
end
|
22
|
+
|
23
|
+
def active?(validator)
|
24
|
+
validator.data[@target] == @value
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::Default < MiniDefender::Rule
|
4
|
+
def initialize(value)
|
5
|
+
@default = value
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.signature
|
9
|
+
'default'
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.make(args)
|
13
|
+
raise ArgumentError, 'Expected exactly one argument.' unless args.length == 1
|
14
|
+
|
15
|
+
new(args[0])
|
16
|
+
end
|
17
|
+
|
18
|
+
def defaults?(validator)
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
def default_value(validator)
|
23
|
+
@default
|
24
|
+
end
|
25
|
+
|
26
|
+
def passes?(attribute, value, validator)
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
def message(attribute, value, validator)
|
31
|
+
"i can haz valuo?."
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::Different < MiniDefender::Rule
|
4
|
+
def initialize(other_field)
|
5
|
+
raise ArgumentError, 'Other field must be a string' unless other_field.is_a?(String)
|
6
|
+
|
7
|
+
@found = false
|
8
|
+
@other_field = other_field
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.signature
|
12
|
+
'different'
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.make(args)
|
16
|
+
self.new(args[0])
|
17
|
+
end
|
18
|
+
|
19
|
+
def passes?(attribute, value, validator)
|
20
|
+
@found, @other = validator.data.key?(@other_field), validator.data[@other_field]
|
21
|
+
@found && value == @other
|
22
|
+
end
|
23
|
+
|
24
|
+
def message(attribute, value, validator)
|
25
|
+
if @found
|
26
|
+
"The field does not match \"#{@other}\"."
|
27
|
+
else
|
28
|
+
"The field must match #{@other_field}."
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::Digits < MiniDefender::Rule
|
4
|
+
def initialize(size)
|
5
|
+
raise ArgumentError, 'Size must be a positive integer' unless size.is_a?(Integer) && size > 0
|
6
|
+
|
7
|
+
@size = size
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.signature
|
11
|
+
'digits'
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.make(args)
|
15
|
+
self.new(args[0].to_i)
|
16
|
+
end
|
17
|
+
|
18
|
+
def passes?(attribute, value, validator)
|
19
|
+
value = value&.to_s
|
20
|
+
value.is_a?(String) && /\A[0-9]+\z/.match?(value) && value.length == @size
|
21
|
+
end
|
22
|
+
|
23
|
+
def message(attribute, value, validator)
|
24
|
+
"The field must contain #{size} digits."
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::DigitsBetween < MiniDefender::Rule
|
4
|
+
def initialize(min, max)
|
5
|
+
raise ArgumentError, 'Min must be a positive integer' unless min.is_a?(Integer) && min > 0
|
6
|
+
raise ArgumentError, 'Max must be a positive integer' unless max.is_a?(Integer) && max > 0
|
7
|
+
|
8
|
+
@min = min
|
9
|
+
@max = max
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.signature
|
13
|
+
'digits_between'
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.make(args)
|
17
|
+
self.new(args[0].to_i, args[1].to_i)
|
18
|
+
end
|
19
|
+
|
20
|
+
def passes?(attribute, value, validator)
|
21
|
+
value = value&.to_s
|
22
|
+
|
23
|
+
value.is_a?(String) && /\A[0-9]+\z/.match?(value) && value.length >= @min && value.length <= @max
|
24
|
+
end
|
25
|
+
|
26
|
+
def message(attribute, value, validator)
|
27
|
+
"The field must contain digits between #{min} and #{max}."
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::Distinct < MiniDefender::Rule
|
4
|
+
def self.signature
|
5
|
+
'distinct'
|
6
|
+
end
|
7
|
+
|
8
|
+
def passes?(attribute, value, validator)
|
9
|
+
validator
|
10
|
+
.neighbors(attribute)
|
11
|
+
.reject { |k, v| k == attribute }
|
12
|
+
.none? { |_, v| v == value }
|
13
|
+
end
|
14
|
+
|
15
|
+
def message(attribute, value, validator)
|
16
|
+
'The value should be unique.'
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::Email < MiniDefender::Rule
|
4
|
+
def self.signature
|
5
|
+
'email'
|
6
|
+
end
|
7
|
+
|
8
|
+
def coerce(value)
|
9
|
+
value.strip.downcase
|
10
|
+
end
|
11
|
+
|
12
|
+
def passes?(attribute, value, validator)
|
13
|
+
value.to_s.match?(URI::MailTo::EMAIL_REGEXP)
|
14
|
+
end
|
15
|
+
|
16
|
+
def message(attribute, value, validator)
|
17
|
+
"The value should be a valid email address."
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::EndingWith < MiniDefender::Rule
|
4
|
+
def initialize(fragments)
|
5
|
+
unless fragments.is_a?(Array) && !fragments.empty? && fragments.all? { |f| f.is_a?(String) }
|
6
|
+
raise ArgumentError, 'Expected an array of strings.'
|
7
|
+
end
|
8
|
+
|
9
|
+
@fragments = fragments
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.signature
|
13
|
+
'ending_with'
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.make(args)
|
17
|
+
new(args)
|
18
|
+
end
|
19
|
+
|
20
|
+
def passes?(attribute, value, validator)
|
21
|
+
@fragments.any? { |f| value.to_s.end_with?(f) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def message(attribute, value, validator)
|
25
|
+
if @fragments.length == 1
|
26
|
+
"The value should end with #{@fragments[0]}."
|
27
|
+
else
|
28
|
+
"The value should end with one of the following #{@fragments.join(', ')}."
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::ExcludedIf < MiniDefender::Rule
|
4
|
+
def initialize(target, value)
|
5
|
+
raise ArgumentError, 'Target must be a string' unless target.is_a?(String)
|
6
|
+
|
7
|
+
@target = target
|
8
|
+
@value = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.signature
|
12
|
+
'excluded_if'
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.make(args)
|
16
|
+
raise ArgumentError, 'Target and expected value are required.' unless args.length == 2
|
17
|
+
|
18
|
+
self.new(args[0], args[1])
|
19
|
+
end
|
20
|
+
|
21
|
+
def excluded?(validator)
|
22
|
+
validator.data.key?(@target) && validator.data[@target] == @value
|
23
|
+
end
|
24
|
+
|
25
|
+
def passes?(attribute, value, validator)
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::ExcludedUnless < MiniDefender::Rule
|
4
|
+
def initialize(target, value)
|
5
|
+
raise ArgumentError, 'Target must be a string' unless target.is_a?(String)
|
6
|
+
|
7
|
+
@target = target
|
8
|
+
@value = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.signature
|
12
|
+
'excluded_unless'
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.make(args)
|
16
|
+
raise ArgumentError, 'Target and expected value are required.' unless args.length == 2
|
17
|
+
|
18
|
+
self.new(args[0], args[1])
|
19
|
+
end
|
20
|
+
|
21
|
+
def excluded?(validator)
|
22
|
+
! (validator.data.key?(@target) && validator.data[@target] == @value)
|
23
|
+
end
|
24
|
+
|
25
|
+
def passes?(attribute, value, validator)
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::ExcludedWith < MiniDefender::Rule
|
4
|
+
def initialize(target)
|
5
|
+
raise ArgumentError, 'Target must be a string' unless target.is_a?(String)
|
6
|
+
|
7
|
+
@target = target
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.signature
|
11
|
+
'excluded_with'
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.make(args)
|
15
|
+
raise ArgumentError, 'Target and expected value are required.' unless args.length == 1
|
16
|
+
|
17
|
+
self.new(args[0])
|
18
|
+
end
|
19
|
+
|
20
|
+
def excluded?(validator)
|
21
|
+
validator.data.key?(@target)
|
22
|
+
end
|
23
|
+
|
24
|
+
def passes?(attribute, value, validator)
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::ExcludedWithout < MiniDefender::Rule
|
4
|
+
def initialize(target)
|
5
|
+
raise ArgumentError, 'Target must be a string' unless target.is_a?(String)
|
6
|
+
|
7
|
+
@target = target
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.signature
|
11
|
+
'excluded_without'
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.make(args)
|
15
|
+
raise ArgumentError, 'Target and expected value are required.' unless args.length == 1
|
16
|
+
|
17
|
+
self.new(args[0])
|
18
|
+
end
|
19
|
+
|
20
|
+
def excluded?(validator)
|
21
|
+
!validator.data.key?(@target)
|
22
|
+
end
|
23
|
+
|
24
|
+
def passes?(attribute, value, validator)
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::Exists < MiniDefender::Rule
|
4
|
+
def initialize(model, column)
|
5
|
+
raise ArgumentError, 'model name must be a string or ActiveRecord::Base' unless model.is_a?(String)
|
6
|
+
raise ArgumentError, 'Column name must be a string' unless column.is_a?(String)
|
7
|
+
|
8
|
+
@model = model.camelcase.constantize
|
9
|
+
@column = column
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.signature
|
13
|
+
'exists'
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.make(args)
|
17
|
+
raise ArgumentError, 'Model and column are required.' unless args.length == 2
|
18
|
+
|
19
|
+
self.new(args[0], args[1])
|
20
|
+
end
|
21
|
+
|
22
|
+
def passes?(attribute, value, validator)
|
23
|
+
@model.where(@column => value).exists?
|
24
|
+
end
|
25
|
+
|
26
|
+
def message(attribute, value, validator)
|
27
|
+
"The value does not exists."
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MiniDefender::Rules::ExpiryDate < MiniDefender::Rule
|
4
|
+
def self.signature
|
5
|
+
'expiry_date'
|
6
|
+
end
|
7
|
+
|
8
|
+
def coerce(value)
|
9
|
+
"#{@month}/#{@year}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def passes?(attribute, value, validator)
|
13
|
+
return false unless value.is_a?(String)
|
14
|
+
|
15
|
+
matches = /(\d{2})\s*\/\s*(\d{2,4})/.match(value.strip)
|
16
|
+
return false unless matches
|
17
|
+
|
18
|
+
@month = matches[1].to_i
|
19
|
+
@year = matches[2].to_i
|
20
|
+
@year += 2000 if year < 100
|
21
|
+
|
22
|
+
@month >= 1 && @month <= 12 && @year >= 1900
|
23
|
+
end
|
24
|
+
|
25
|
+
def message(attribute, value, validator)
|
26
|
+
'Invalid expiry date.'
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'action_dispatch'
|
4
|
+
|
5
|
+
class MiniDefender::Rules::File < MiniDefender::Rule
|
6
|
+
def self.signature
|
7
|
+
'file'
|
8
|
+
end
|
9
|
+
|
10
|
+
def passes?(attribute, value, validator)
|
11
|
+
value.is_a?(ActionDispatch::Http::UploadedFile)
|
12
|
+
end
|
13
|
+
|
14
|
+
def message(attribute, value, validator)
|
15
|
+
"The field should be a file."
|
16
|
+
end
|
17
|
+
end
|