line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mojolicious::Plugin::AdditionalValidationChecks; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# ABSTRACT: Add additional validation checks |
4
|
|
|
|
|
|
|
|
5
|
29
|
|
|
29
|
|
24197
|
use Mojo::Base 'Mojolicious::Plugin'; |
|
29
|
|
|
|
|
89
|
|
|
29
|
|
|
|
|
253
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.18'; |
8
|
|
|
|
|
|
|
|
9
|
29
|
|
|
29
|
|
25467
|
use Email::Valid; |
|
29
|
|
|
|
|
1906876
|
|
|
29
|
|
|
|
|
3905
|
|
10
|
29
|
|
|
29
|
|
625
|
use Scalar::Util qw(looks_like_number); |
|
29
|
|
|
|
|
267
|
|
|
29
|
|
|
|
|
4634
|
|
11
|
29
|
|
|
29
|
|
20481
|
use Time::Piece; |
|
29
|
|
|
|
|
262098
|
|
|
29
|
|
|
|
|
279
|
|
12
|
29
|
|
|
29
|
|
3047
|
use Mojo::URL; |
|
29
|
|
|
|
|
134
|
|
|
29
|
|
|
|
|
1165
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
sub register { |
15
|
29
|
|
|
29
|
1
|
5887
|
my ($self, $app) = @_; |
16
|
|
|
|
|
|
|
|
17
|
29
|
|
|
|
|
546
|
my $email = Email::Valid->new( |
18
|
|
|
|
|
|
|
allow_ip => 1, |
19
|
|
|
|
|
|
|
); |
20
|
|
|
|
|
|
|
|
21
|
29
|
|
|
|
|
4568
|
my $validator = $app->validator; |
22
|
|
|
|
|
|
|
$validator->add_check( email => sub { |
23
|
3
|
|
|
3
|
|
47988
|
my ($self, $field, $value, @params) = @_; |
24
|
3
|
|
|
|
|
47
|
my $address = $email->address( @params, -address => $value ); |
25
|
3
|
100
|
|
|
|
95855
|
return $address ? 0 : 1; |
26
|
29
|
|
|
|
|
19521
|
}); |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
$validator->add_check( int => sub { |
29
|
22
|
|
|
22
|
|
70293
|
my ($nr) = $_[2] =~ m{\A ([\+-]? [0-9]+) \z}x; |
30
|
22
|
100
|
|
|
|
95
|
my $return = defined $nr ? 0 : 1; |
31
|
22
|
|
|
|
|
69
|
return $return; |
32
|
29
|
|
|
|
|
2066
|
}); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
$validator->add_check( min => sub { |
35
|
6
|
100
|
|
6
|
|
74374
|
return 1 if !looks_like_number( $_[2] ); |
36
|
5
|
100
|
|
|
|
47
|
return if !length $_[3]; |
37
|
4
|
|
|
|
|
22
|
return $_[2] < $_[3]; |
38
|
29
|
|
|
|
|
1981
|
}); |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
$validator->add_check( max => sub { |
41
|
6
|
100
|
|
6
|
|
71044
|
return 1 if !looks_like_number( $_[2] ); |
42
|
5
|
100
|
|
|
|
38
|
return if !length $_[3]; |
43
|
4
|
|
|
|
|
18
|
return $_[2] > $_[3]; |
44
|
29
|
|
|
|
|
1427
|
}); |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
$validator->add_check( phone => sub { |
47
|
16
|
100
|
|
16
|
|
215456
|
return 0 if $_[2] =~ m{\A |
48
|
|
|
|
|
|
|
((?: \+ | 00 ) [1-9]{1}[0-9]{0,2})? # country |
49
|
|
|
|
|
|
|
\s*? [0-9]{2,5} \s*? # local |
50
|
|
|
|
|
|
|
[/-]? |
51
|
|
|
|
|
|
|
\s*? [0-9]{2,12} # phone |
52
|
|
|
|
|
|
|
\z}x; |
53
|
5
|
|
|
|
|
45
|
return 1; |
54
|
29
|
|
|
|
|
1734
|
}); |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
$validator->add_check( length => sub { |
57
|
8
|
|
|
8
|
|
89959
|
my ($self, $field, $value, $min, $max) = @_; |
58
|
|
|
|
|
|
|
|
59
|
8
|
|
|
|
|
54
|
my $length = length $value; |
60
|
|
|
|
|
|
|
|
61
|
8
|
100
|
100
|
|
|
39
|
return 0 if !$min && !$max; |
62
|
|
|
|
|
|
|
|
63
|
7
|
100
|
100
|
|
|
37
|
return 1 if $min && $length < $min; |
64
|
4
|
100
|
100
|
|
|
18
|
return 1 if $max && $length > $max; |
65
|
|
|
|
|
|
|
|
66
|
3
|
|
|
|
|
16
|
return 0; |
67
|
29
|
|
|
|
|
1446
|
}); |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
$validator->add_check( http_url => sub { |
70
|
7
|
|
|
7
|
|
79320
|
my $url = Mojo::URL->new( $_[2] ); |
71
|
7
|
100
|
|
|
|
1234
|
return 1 if !$url->is_abs; |
72
|
4
|
100
|
|
|
|
41
|
return 1 if !grep{ $url->scheme eq $_ }qw(http https); |
|
8
|
|
|
|
|
33
|
|
73
|
3
|
|
|
|
|
29
|
return 0; |
74
|
29
|
|
|
|
|
1342
|
}); |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
$validator->add_check( not => sub { |
77
|
5
|
|
|
5
|
|
60673
|
my ($validation, @tmp) = (shift, shift, shift); |
78
|
5
|
100
|
|
|
|
49
|
return 0 if !@_; |
79
|
|
|
|
|
|
|
|
80
|
4
|
|
|
|
|
12
|
my $field = $validation->topic; |
81
|
4
|
|
|
|
|
29
|
$validation->in( @_ ); |
82
|
|
|
|
|
|
|
|
83
|
4
|
100
|
|
|
|
248
|
if ( $validation->has_error($field) ) { |
84
|
2
|
|
|
|
|
15
|
delete $validation->{error}->{$field}; |
85
|
2
|
|
|
|
|
5
|
return 0; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
2
|
|
|
|
|
17
|
return 1; |
89
|
29
|
|
|
|
|
1583
|
}); |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
$validator->add_check( color => sub { |
92
|
149
|
|
|
149
|
|
1601193
|
my ($validation, $field, $value, $type) = @_; |
93
|
|
|
|
|
|
|
|
94
|
149
|
|
|
|
|
592
|
state $rgb_int = qr{ |
95
|
|
|
|
|
|
|
\s* (?: 25[0-5] | 2[0-4][0-9] | 1[0-9][0-9] | [1-9][0-9] | [0-9] ) |
96
|
|
|
|
|
|
|
}x; |
97
|
|
|
|
|
|
|
|
98
|
149
|
|
|
|
|
333
|
state $rgb_percent = qr{ |
99
|
|
|
|
|
|
|
\s* (?: 100 | [1-9][0-9] | [0-9] ) \% |
100
|
|
|
|
|
|
|
}x; |
101
|
|
|
|
|
|
|
|
102
|
149
|
|
|
|
|
304
|
state $alpha = qr{ |
103
|
|
|
|
|
|
|
\s* (?: 0 | 0?\.[0-9]+ | 1(?:\.0)? ) |
104
|
|
|
|
|
|
|
}x; |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
state $types = { |
107
|
|
|
|
|
|
|
rgb => qr{ |
108
|
|
|
|
|
|
|
\A |
109
|
|
|
|
|
|
|
rgb\( |
110
|
|
|
|
|
|
|
(?: |
111
|
|
|
|
|
|
|
(?: |
112
|
|
|
|
|
|
|
(?:$rgb_int,){2} $rgb_int |
113
|
|
|
|
|
|
|
) | |
114
|
|
|
|
|
|
|
(?: |
115
|
|
|
|
|
|
|
(?:$rgb_percent,){2} $rgb_percent |
116
|
|
|
|
|
|
|
) |
117
|
|
|
|
|
|
|
) |
118
|
|
|
|
|
|
|
\) |
119
|
|
|
|
|
|
|
\z |
120
|
|
|
|
|
|
|
}x, |
121
|
|
|
|
|
|
|
rgba => qr{ |
122
|
|
|
|
|
|
|
\A |
123
|
|
|
|
|
|
|
rgba\( |
124
|
|
|
|
|
|
|
(?: |
125
|
|
|
|
|
|
|
(?: |
126
|
|
|
|
|
|
|
(?:$rgb_int,){3} $alpha |
127
|
|
|
|
|
|
|
) | |
128
|
|
|
|
|
|
|
(?: |
129
|
|
|
|
|
|
|
(?:$rgb_percent,){3} $alpha |
130
|
|
|
|
|
|
|
) |
131
|
|
|
|
|
|
|
) |
132
|
|
|
|
|
|
|
\) |
133
|
|
|
|
|
|
|
\z |
134
|
|
|
|
|
|
|
}xms, |
135
|
|
|
|
|
|
|
hex => qr{ |
136
|
|
|
|
|
|
|
\A |
137
|
|
|
|
|
|
|
\# |
138
|
|
|
|
|
|
|
(?: (?:[0-9A-Fa-f]){3} ){1,2} |
139
|
|
|
|
|
|
|
\z |
140
|
|
|
|
|
|
|
}xms, |
141
|
|
|
|
|
|
|
hsl => qr{ |
142
|
|
|
|
|
|
|
\A |
143
|
|
|
|
|
|
|
hsla?\( |
144
|
|
|
|
|
|
|
(?: |
145
|
|
|
|
|
|
|
-? [0-9]+ \s* (?:deg|g?rad|turn)? |
146
|
|
|
|
|
|
|
(?[, ]) \s* |
147
|
|
|
|
|
|
|
$rgb_percent \g{sep} \s* |
148
|
|
|
|
|
|
|
$rgb_percent \s* |
149
|
|
|
|
|
|
|
(?: |
150
|
48
|
|
|
|
|
680
|
(?(?{$+{sep} eq ','}) , | / ) \s* |
151
|
|
|
|
|
|
|
(?:$alpha|$rgb_percent) |
152
|
|
|
|
|
|
|
)? |
153
|
|
|
|
|
|
|
) |
154
|
|
|
|
|
|
|
\) |
155
|
|
|
|
|
|
|
\z |
156
|
|
|
|
|
|
|
}xms, |
157
|
|
|
|
|
|
|
|
158
|
149
|
|
|
|
|
2203
|
}; |
159
|
|
|
|
|
|
|
|
160
|
149
|
100
|
|
|
|
683
|
return 1 if !$types->{$type}; |
161
|
|
|
|
|
|
|
|
162
|
148
|
|
|
|
|
2093
|
my $found = $value =~ $types->{$type}; |
163
|
148
|
|
|
|
|
687
|
return !$found; |
164
|
29
|
|
|
|
|
1917
|
}); |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
$validator->add_check( uuid => sub { |
167
|
47
|
|
|
47
|
|
507752
|
my ($validation, $field, $value, $type) = @_; |
168
|
|
|
|
|
|
|
|
169
|
47
|
|
|
|
|
550
|
my %regexes = ( |
170
|
|
|
|
|
|
|
3 => qr/\A[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}\z/i, |
171
|
|
|
|
|
|
|
4 => qr/\A[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\z/i, |
172
|
|
|
|
|
|
|
5 => qr/\A[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\z/i, |
173
|
|
|
|
|
|
|
all => qr/\A[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\z/i, |
174
|
|
|
|
|
|
|
); |
175
|
|
|
|
|
|
|
|
176
|
47
|
|
100
|
|
|
217
|
$type ||= 'all'; |
177
|
47
|
|
|
|
|
112
|
my $regex = $regexes{$type}; |
178
|
47
|
100
|
|
|
|
131
|
$regex = $regexes{all} if !$regex; |
179
|
|
|
|
|
|
|
|
180
|
47
|
|
|
|
|
524
|
return $value !~ $regex; |
181
|
29
|
|
|
|
|
1951
|
}); |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
$validator->add_check( hex => sub { |
184
|
9
|
|
|
9
|
|
103010
|
my ($validation, $field, $value, $type) = @_; |
185
|
|
|
|
|
|
|
|
186
|
9
|
|
|
|
|
89
|
return $value !~ m{\A [0-9A-Fa-f]+ \z}xms; |
187
|
29
|
|
|
|
|
1672
|
}); |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
$validator->add_check( float => sub { |
190
|
27
|
|
|
27
|
|
214452
|
my ($validation, $field, $value) = @_; |
191
|
|
|
|
|
|
|
|
192
|
27
|
|
|
|
|
274
|
return $value !~ m{ |
193
|
|
|
|
|
|
|
\A |
194
|
|
|
|
|
|
|
(?: |
195
|
|
|
|
|
|
|
[+-]? |
196
|
|
|
|
|
|
|
(?:[0-9]+) |
197
|
|
|
|
|
|
|
)? |
198
|
|
|
|
|
|
|
(?: |
199
|
|
|
|
|
|
|
\. |
200
|
|
|
|
|
|
|
[0-9]* |
201
|
|
|
|
|
|
|
) |
202
|
|
|
|
|
|
|
(?: |
203
|
|
|
|
|
|
|
[eE] |
204
|
|
|
|
|
|
|
[\+\-]? |
205
|
|
|
|
|
|
|
(?:[0-9]+) |
206
|
|
|
|
|
|
|
)? |
207
|
|
|
|
|
|
|
\z |
208
|
|
|
|
|
|
|
}xms; |
209
|
29
|
|
|
|
|
1597
|
}); |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
$validator->add_check( ip => sub { |
212
|
61
|
|
|
61
|
|
668544
|
my ($validation, $field, $value, $type) = @_; |
213
|
|
|
|
|
|
|
|
214
|
61
|
|
100
|
|
|
368
|
$type //= 4; |
215
|
|
|
|
|
|
|
|
216
|
61
|
|
|
|
|
145
|
state $octett = qr{ |
217
|
|
|
|
|
|
|
(?: 25[0-5] | 2[0-4][0-9] | 1[0-9][0-9] | [1-9][0-9] | [0-9] ) |
218
|
|
|
|
|
|
|
}xms; |
219
|
|
|
|
|
|
|
|
220
|
61
|
|
|
|
|
153
|
my $ipv4 = "((25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))"; |
221
|
61
|
|
|
|
|
135
|
my $g = "[0-9a-fA-F]{1,4}"; |
222
|
|
|
|
|
|
|
|
223
|
61
|
|
|
|
|
657
|
my @tail = ( |
224
|
|
|
|
|
|
|
":", |
225
|
|
|
|
|
|
|
"(:($g)?|$ipv4)", |
226
|
|
|
|
|
|
|
":($ipv4|$g(:$g)?|)", |
227
|
|
|
|
|
|
|
"(:$ipv4|:$g(:$ipv4|(:$g){0,2})|:)", |
228
|
|
|
|
|
|
|
"((:$g){0,2}(:$ipv4|(:$g){1,2})|:)", |
229
|
|
|
|
|
|
|
"((:$g){0,3}(:$ipv4|(:$g){1,2})|:)", |
230
|
|
|
|
|
|
|
"((:$g){0,4}(:$ipv4|(:$g){1,2})|:)", |
231
|
|
|
|
|
|
|
); |
232
|
|
|
|
|
|
|
|
233
|
61
|
|
|
|
|
132
|
my $ipv6 = $g; |
234
|
61
|
|
|
|
|
617
|
$ipv6 = "$g:($ipv6|$_)" for @tail; |
235
|
61
|
|
|
|
|
279
|
$ipv6 = qq/:(:$g){0,5}((:$g){1,2}|:$ipv4)|$ipv6/; |
236
|
61
|
|
|
|
|
1346
|
$ipv6 =~ s/\(/(?:/g; |
237
|
|
|
|
|
|
|
|
238
|
61
|
|
|
|
|
3397
|
my %regexes = ( |
239
|
|
|
|
|
|
|
4 => qr/\A (?: $octett \. ){3} $octett \z/xms, |
240
|
|
|
|
|
|
|
6 => qr/\A$ipv6\z/, |
241
|
|
|
|
|
|
|
); |
242
|
|
|
|
|
|
|
|
243
|
61
|
|
|
|
|
259
|
my $regex = $regexes{$type}; |
244
|
61
|
100
|
|
|
|
216
|
$regex = $regexes{4} if !$regex; |
245
|
|
|
|
|
|
|
|
246
|
61
|
|
|
|
|
907
|
return $value !~ $regex; |
247
|
29
|
|
|
|
|
2112
|
}); |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
$validator->add_check( between => sub { |
250
|
12
|
100
|
100
|
12
|
|
160321
|
my $op = (looks_like_number( $_[3] ) and looks_like_number( $_[4] ) ) ? 'n' : 's'; |
251
|
|
|
|
|
|
|
|
252
|
12
|
|
|
|
|
65
|
my $result; |
253
|
12
|
100
|
|
|
|
63
|
if ( $op eq 'n' ) { |
254
|
3
|
|
100
|
|
|
33
|
$result = $_[2] < $_[3] || $_[2] > $_[4]; |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
else { |
257
|
9
|
|
100
|
|
|
59
|
$result = ( |
258
|
|
|
|
|
|
|
( ( $_[2] cmp $_[3] ) == -1 ) || |
259
|
|
|
|
|
|
|
( ( $_[4] cmp $_[2] ) == -1 ) |
260
|
|
|
|
|
|
|
); |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
|
263
|
12
|
|
|
|
|
60
|
return $result; |
264
|
29
|
|
|
|
|
1728
|
}); |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
$validator->add_check( number => sub { |
267
|
19
|
|
|
19
|
|
190261
|
my ($validation, @tmp) = (shift, shift, shift); |
268
|
|
|
|
|
|
|
|
269
|
19
|
100
|
|
|
|
142
|
return 1 if !looks_like_number( $tmp[1] ); |
270
|
|
|
|
|
|
|
|
271
|
16
|
|
|
|
|
51
|
my $field = $validation->topic; |
272
|
16
|
|
|
|
|
111
|
$validation->check( 'int', $tmp[1] ); |
273
|
|
|
|
|
|
|
|
274
|
16
|
100
|
|
|
|
256
|
return 0 if !$validation->has_error($field); |
275
|
|
|
|
|
|
|
|
276
|
12
|
|
|
|
|
76
|
$validation->output->{$field} = $tmp[1]; |
277
|
12
|
|
|
|
|
62
|
delete $validation->{error}->{$field}; |
278
|
|
|
|
|
|
|
|
279
|
12
|
|
|
|
|
44
|
$validation->check( 'float', $tmp[1] ); |
280
|
|
|
|
|
|
|
|
281
|
12
|
100
|
|
|
|
98
|
return 0 if !$validation->has_error($field); |
282
|
|
|
|
|
|
|
|
283
|
2
|
|
|
|
|
13
|
delete $validation->{error}->{$field}; |
284
|
|
|
|
|
|
|
|
285
|
2
|
|
|
|
|
6
|
return 1; |
286
|
29
|
|
|
|
|
1643
|
}); |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
$validator->add_check( date => sub { |
289
|
22
|
100
|
|
22
|
|
281249
|
return 1 if !$_[2]; |
290
|
21
|
100
|
|
|
|
193
|
return 1 if $_[2] !~ m{\A[0-9]{4}-[0-9]{2}-[0-9]{2}\z}; |
291
|
|
|
|
|
|
|
|
292
|
13
|
|
|
|
|
36
|
my $date; |
293
|
13
|
100
|
|
|
|
36
|
eval { |
294
|
13
|
|
|
|
|
128
|
$date = Time::Piece->strptime( $_[2], '%Y-%m-%d' ); |
295
|
11
|
|
|
|
|
1221
|
1; |
296
|
|
|
|
|
|
|
} or return 1; |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
# this is needed as 2013-02-31 is parsed, but will return 2013-03-03 for ymd() |
299
|
11
|
100
|
|
|
|
72
|
return 1 if $_[2] ne $date->ymd; |
300
|
|
|
|
|
|
|
|
301
|
6
|
|
|
|
|
276
|
return 0; |
302
|
29
|
|
|
|
|
1812
|
}); |
303
|
|
|
|
|
|
|
} |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
1; |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
__END__ |