line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mojolicious::Plugin::AdditionalValidationChecks; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# ABSTRACT: Add additional validation checks |
4
|
|
|
|
|
|
|
|
5
|
28
|
|
|
28
|
|
22311
|
use Mojo::Base 'Mojolicious::Plugin'; |
|
28
|
|
|
|
|
76
|
|
|
28
|
|
|
|
|
227
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.17'; |
8
|
|
|
|
|
|
|
|
9
|
28
|
|
|
28
|
|
23884
|
use Email::Valid; |
|
28
|
|
|
|
|
1686558
|
|
|
28
|
|
|
|
|
3624
|
|
10
|
28
|
|
|
28
|
|
559
|
use Scalar::Util qw(looks_like_number); |
|
28
|
|
|
|
|
224
|
|
|
28
|
|
|
|
|
4362
|
|
11
|
28
|
|
|
28
|
|
17327
|
use Time::Piece; |
|
28
|
|
|
|
|
230290
|
|
|
28
|
|
|
|
|
257
|
|
12
|
28
|
|
|
28
|
|
2844
|
use Mojo::URL; |
|
28
|
|
|
|
|
165
|
|
|
28
|
|
|
|
|
1283
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
sub register { |
15
|
28
|
|
|
28
|
1
|
5823
|
my ($self, $app) = @_; |
16
|
|
|
|
|
|
|
|
17
|
28
|
|
|
|
|
491
|
my $email = Email::Valid->new( |
18
|
|
|
|
|
|
|
allow_ip => 1, |
19
|
|
|
|
|
|
|
); |
20
|
|
|
|
|
|
|
|
21
|
28
|
|
|
|
|
4494
|
my $validator = $app->validator; |
22
|
|
|
|
|
|
|
$validator->add_check( email => sub { |
23
|
3
|
|
|
3
|
|
44724
|
my ($self, $field, $value, @params) = @_; |
24
|
3
|
|
|
|
|
47
|
my $address = $email->address( @params, -address => $value ); |
25
|
3
|
100
|
|
|
|
12161
|
return $address ? 0 : 1; |
26
|
28
|
|
|
|
|
18254
|
}); |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
$validator->add_check( int => sub { |
29
|
22
|
|
|
22
|
|
73930
|
my ($nr) = $_[2] =~ m{\A ([\+-]? [0-9]+) \z}x; |
30
|
22
|
100
|
|
|
|
110
|
my $return = defined $nr ? 0 : 1; |
31
|
22
|
|
|
|
|
64
|
return $return; |
32
|
28
|
|
|
|
|
1641
|
}); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
$validator->add_check( min => sub { |
35
|
6
|
100
|
|
6
|
|
75351
|
return 1 if !looks_like_number( $_[2] ); |
36
|
5
|
100
|
|
|
|
53
|
return if !length $_[3]; |
37
|
4
|
|
|
|
|
27
|
return $_[2] < $_[3]; |
38
|
28
|
|
|
|
|
1935
|
}); |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
$validator->add_check( max => sub { |
41
|
6
|
100
|
|
6
|
|
79042
|
return 1 if !looks_like_number( $_[2] ); |
42
|
5
|
100
|
|
|
|
59
|
return if !length $_[3]; |
43
|
4
|
|
|
|
|
25
|
return $_[2] > $_[3]; |
44
|
28
|
|
|
|
|
1371
|
}); |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
$validator->add_check( phone => sub { |
47
|
16
|
100
|
|
16
|
|
161275
|
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
|
28
|
|
|
|
|
1703
|
}); |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
$validator->add_check( length => sub { |
57
|
8
|
|
|
8
|
|
90064
|
my ($self, $field, $value, $min, $max) = @_; |
58
|
|
|
|
|
|
|
|
59
|
8
|
|
|
|
|
47
|
my $length = length $value; |
60
|
|
|
|
|
|
|
|
61
|
8
|
100
|
100
|
|
|
49
|
return 0 if !$min && !$max; |
62
|
|
|
|
|
|
|
|
63
|
7
|
100
|
100
|
|
|
48
|
return 1 if $min && $length < $min; |
64
|
4
|
100
|
100
|
|
|
19
|
return 1 if $max && $length > $max; |
65
|
|
|
|
|
|
|
|
66
|
3
|
|
|
|
|
10
|
return 0; |
67
|
28
|
|
|
|
|
1399
|
}); |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
$validator->add_check( http_url => sub { |
70
|
7
|
|
|
7
|
|
85583
|
my $url = Mojo::URL->new( $_[2] ); |
71
|
7
|
100
|
|
|
|
1260
|
return 1 if !$url->is_abs; |
72
|
4
|
100
|
|
|
|
42
|
return 1 if !grep{ $url->scheme eq $_ }qw(http https); |
|
8
|
|
|
|
|
32
|
|
73
|
3
|
|
|
|
|
28
|
return 0; |
74
|
28
|
|
|
|
|
1262
|
}); |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
$validator->add_check( not => sub { |
77
|
5
|
|
|
5
|
|
63207
|
my ($validation, @tmp) = (shift, shift, shift); |
78
|
5
|
100
|
|
|
|
86
|
return 0 if !@_; |
79
|
|
|
|
|
|
|
|
80
|
4
|
|
|
|
|
12
|
my $field = $validation->topic; |
81
|
4
|
|
|
|
|
32
|
$validation->in( @_ ); |
82
|
|
|
|
|
|
|
|
83
|
4
|
100
|
|
|
|
239
|
if ( $validation->has_error($field) ) { |
84
|
2
|
|
|
|
|
21
|
delete $validation->{error}->{$field}; |
85
|
2
|
|
|
|
|
8
|
return 0; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
2
|
|
|
|
|
17
|
return 1; |
89
|
28
|
|
|
|
|
1493
|
}); |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
$validator->add_check( color => sub { |
92
|
83
|
|
|
83
|
|
897972
|
my ($validation, $field, $value, $type) = @_; |
93
|
|
|
|
|
|
|
|
94
|
83
|
|
|
|
|
384
|
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
|
83
|
|
|
|
|
195
|
state $rgb_percent = qr{ |
99
|
|
|
|
|
|
|
\s* (?: 100 | [1-9][0-] | [0-9] ) \% |
100
|
|
|
|
|
|
|
}x; |
101
|
|
|
|
|
|
|
|
102
|
83
|
|
|
|
|
173
|
state $alpha = qr{ |
103
|
|
|
|
|
|
|
\s* (?: (?: 0 (?:\.[0-9]+)? )| (?: 1 (?:\.0)? ) ) |
104
|
|
|
|
|
|
|
}x; |
105
|
|
|
|
|
|
|
|
106
|
83
|
|
|
|
|
1297
|
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
|
|
|
|
|
|
|
}; |
142
|
|
|
|
|
|
|
|
143
|
83
|
100
|
|
|
|
389
|
return 1 if !$types->{$type}; |
144
|
|
|
|
|
|
|
|
145
|
82
|
|
|
|
|
975
|
my $found = $value =~ $types->{$type}; |
146
|
82
|
|
|
|
|
334
|
return !$found; |
147
|
28
|
|
|
|
|
1898
|
}); |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
$validator->add_check( uuid => sub { |
150
|
47
|
|
|
47
|
|
529166
|
my ($validation, $field, $value, $type) = @_; |
151
|
|
|
|
|
|
|
|
152
|
47
|
|
|
|
|
648
|
my %regexes = ( |
153
|
|
|
|
|
|
|
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, |
154
|
|
|
|
|
|
|
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, |
155
|
|
|
|
|
|
|
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, |
156
|
|
|
|
|
|
|
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, |
157
|
|
|
|
|
|
|
); |
158
|
|
|
|
|
|
|
|
159
|
47
|
|
100
|
|
|
240
|
$type ||= 'all'; |
160
|
47
|
|
|
|
|
125
|
my $regex = $regexes{$type}; |
161
|
47
|
100
|
|
|
|
165
|
$regex = $regexes{all} if !$regex; |
162
|
|
|
|
|
|
|
|
163
|
47
|
|
|
|
|
605
|
return $value !~ $regex; |
164
|
28
|
|
|
|
|
1421
|
}); |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
$validator->add_check( hex => sub { |
167
|
9
|
|
|
9
|
|
106139
|
my ($validation, $field, $value, $type) = @_; |
168
|
|
|
|
|
|
|
|
169
|
9
|
|
|
|
|
89
|
return $value !~ m{\A [0-9A-Fa-f]+ \z}xms; |
170
|
28
|
|
|
|
|
1420
|
}); |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
$validator->add_check( float => sub { |
173
|
27
|
|
|
27
|
|
158117
|
my ($validation, $field, $value) = @_; |
174
|
|
|
|
|
|
|
|
175
|
27
|
|
|
|
|
225
|
return $value !~ m{ |
176
|
|
|
|
|
|
|
\A |
177
|
|
|
|
|
|
|
(?: |
178
|
|
|
|
|
|
|
[+-]? |
179
|
|
|
|
|
|
|
(?:[0-9]+) |
180
|
|
|
|
|
|
|
)? |
181
|
|
|
|
|
|
|
(?: |
182
|
|
|
|
|
|
|
\. |
183
|
|
|
|
|
|
|
[0-9]* |
184
|
|
|
|
|
|
|
) |
185
|
|
|
|
|
|
|
(?: |
186
|
|
|
|
|
|
|
[eE] |
187
|
|
|
|
|
|
|
[\+\-]? |
188
|
|
|
|
|
|
|
(?:[0-9]+) |
189
|
|
|
|
|
|
|
)? |
190
|
|
|
|
|
|
|
\z |
191
|
|
|
|
|
|
|
}xms; |
192
|
28
|
|
|
|
|
1715
|
}); |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
$validator->add_check( ip => sub { |
195
|
61
|
|
|
61
|
|
556893
|
my ($validation, $field, $value, $type) = @_; |
196
|
|
|
|
|
|
|
|
197
|
61
|
|
100
|
|
|
345
|
$type //= 4; |
198
|
|
|
|
|
|
|
|
199
|
61
|
|
|
|
|
127
|
state $octett = qr{ |
200
|
|
|
|
|
|
|
(?: 25[0-5] | 2[0-4][0-9] | 1[0-9][0-9] | [1-9][0-9] | [0-9] ) |
201
|
|
|
|
|
|
|
}xms; |
202
|
|
|
|
|
|
|
|
203
|
61
|
|
|
|
|
121
|
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}))"; |
204
|
61
|
|
|
|
|
102
|
my $g = "[0-9a-fA-F]{1,4}"; |
205
|
|
|
|
|
|
|
|
206
|
61
|
|
|
|
|
516
|
my @tail = ( |
207
|
|
|
|
|
|
|
":", |
208
|
|
|
|
|
|
|
"(:($g)?|$ipv4)", |
209
|
|
|
|
|
|
|
":($ipv4|$g(:$g)?|)", |
210
|
|
|
|
|
|
|
"(:$ipv4|:$g(:$ipv4|(:$g){0,2})|:)", |
211
|
|
|
|
|
|
|
"((:$g){0,2}(:$ipv4|(:$g){1,2})|:)", |
212
|
|
|
|
|
|
|
"((:$g){0,3}(:$ipv4|(:$g){1,2})|:)", |
213
|
|
|
|
|
|
|
"((:$g){0,4}(:$ipv4|(:$g){1,2})|:)", |
214
|
|
|
|
|
|
|
); |
215
|
|
|
|
|
|
|
|
216
|
61
|
|
|
|
|
120
|
my $ipv6 = $g; |
217
|
61
|
|
|
|
|
534
|
$ipv6 = "$g:($ipv6|$_)" for @tail; |
218
|
61
|
|
|
|
|
218
|
$ipv6 = qq/:(:$g){0,5}((:$g){1,2}|:$ipv4)|$ipv6/; |
219
|
61
|
|
|
|
|
1139
|
$ipv6 =~ s/\(/(?:/g; |
220
|
|
|
|
|
|
|
|
221
|
61
|
|
|
|
|
2808
|
my %regexes = ( |
222
|
|
|
|
|
|
|
4 => qr/\A (?: $octett \. ){3} $octett \z/xms, |
223
|
|
|
|
|
|
|
6 => qr/\A$ipv6\z/, |
224
|
|
|
|
|
|
|
); |
225
|
|
|
|
|
|
|
|
226
|
61
|
|
|
|
|
221
|
my $regex = $regexes{$type}; |
227
|
61
|
100
|
|
|
|
178
|
$regex = $regexes{4} if !$regex; |
228
|
|
|
|
|
|
|
|
229
|
61
|
|
|
|
|
749
|
return $value !~ $regex; |
230
|
28
|
|
|
|
|
1616
|
}); |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
$validator->add_check( between => sub { |
233
|
12
|
100
|
100
|
12
|
|
137172
|
my $op = (looks_like_number( $_[3] ) and looks_like_number( $_[4] ) ) ? 'n' : 's'; |
234
|
|
|
|
|
|
|
|
235
|
12
|
|
|
|
|
64
|
my $result; |
236
|
12
|
100
|
|
|
|
49
|
if ( $op eq 'n' ) { |
237
|
3
|
|
100
|
|
|
31
|
$result = $_[2] < $_[3] || $_[2] > $_[4]; |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
else { |
240
|
9
|
|
100
|
|
|
49
|
$result = ( |
241
|
|
|
|
|
|
|
( ( $_[2] cmp $_[3] ) == -1 ) || |
242
|
|
|
|
|
|
|
( ( $_[4] cmp $_[2] ) == -1 ) |
243
|
|
|
|
|
|
|
); |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
|
246
|
12
|
|
|
|
|
42
|
return $result; |
247
|
28
|
|
|
|
|
1697
|
}); |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
$validator->add_check( number => sub { |
250
|
19
|
|
|
19
|
|
193533
|
my ($validation, @tmp) = (shift, shift, shift); |
251
|
|
|
|
|
|
|
|
252
|
19
|
100
|
|
|
|
150
|
return 1 if !looks_like_number( $tmp[1] ); |
253
|
|
|
|
|
|
|
|
254
|
16
|
|
|
|
|
50
|
my $field = $validation->topic; |
255
|
16
|
|
|
|
|
111
|
$validation->check( 'int', $tmp[1] ); |
256
|
|
|
|
|
|
|
|
257
|
16
|
100
|
|
|
|
274
|
return 0 if !$validation->has_error($field); |
258
|
|
|
|
|
|
|
|
259
|
12
|
|
|
|
|
89
|
$validation->output->{$field} = $tmp[1]; |
260
|
12
|
|
|
|
|
74
|
delete $validation->{error}->{$field}; |
261
|
|
|
|
|
|
|
|
262
|
12
|
|
|
|
|
59
|
$validation->check( 'float', $tmp[1] ); |
263
|
|
|
|
|
|
|
|
264
|
12
|
100
|
|
|
|
91
|
return 0 if !$validation->has_error($field); |
265
|
|
|
|
|
|
|
|
266
|
2
|
|
|
|
|
14
|
delete $validation->{error}->{$field}; |
267
|
|
|
|
|
|
|
|
268
|
2
|
|
|
|
|
7
|
return 1; |
269
|
28
|
|
|
|
|
1534
|
}); |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
$validator->add_check( date => sub { |
272
|
22
|
100
|
|
22
|
|
238021
|
return 1 if !$_[2]; |
273
|
21
|
100
|
|
|
|
191
|
return 1 if $_[2] !~ m{\A[0-9]{4}-[0-9]{2}-[0-9]{2}\z}; |
274
|
|
|
|
|
|
|
|
275
|
13
|
|
|
|
|
33
|
my $date; |
276
|
13
|
100
|
|
|
|
35
|
eval { |
277
|
13
|
|
|
|
|
92
|
$date = Time::Piece->strptime( $_[2], '%Y-%m-%d' ); |
278
|
11
|
|
|
|
|
1181
|
1; |
279
|
|
|
|
|
|
|
} or return 1; |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
# this is needed as 2013-02-31 is parsed, but will return 2013-03-03 for ymd() |
282
|
11
|
100
|
|
|
|
59
|
return 1 if $_[2] ne $date->ymd; |
283
|
|
|
|
|
|
|
|
284
|
6
|
|
|
|
|
243
|
return 0; |
285
|
28
|
|
|
|
|
1895
|
}); |
286
|
|
|
|
|
|
|
} |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
1; |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
__END__ |