Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace core;
18
 
19
/**
20
 * This tests the static helper functions contained in the class '\core\ip_utils'.
21
 *
22
 * @package    core
23
 * @covers     \core\ip_utils
24
 * @copyright  2016 Jake Dallimore <jrhdallimore@gmail.com>
25
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26
 */
1441 ariadna 27
final class ip_utils_test extends \basic_testcase {
1 efrain 28
    /**
29
     * Test for \core\ip_utils::is_domain_name().
30
     *
31
     * @param string $domainname the domain name to validate.
32
     * @param bool $expected the expected result.
33
     * @dataProvider domain_name_data_provider
34
     */
11 efrain 35
    public function test_is_domain_name($domainname, $expected): void {
1 efrain 36
        $this->assertEquals($expected, \core\ip_utils::is_domain_name($domainname));
37
    }
38
 
39
    /**
40
     * Data provider for test_is_domain_name().
41
     *
42
     * @return array
43
     */
1441 ariadna 44
    public static function domain_name_data_provider(): array {
1 efrain 45
        return [
46
            ["com", true],
47
            ["i.net", true], // Single char, alpha tertiary domain.
48
            ["0.org", true], // Single char, non-alpha tertiary domain.
49
            ["0.a", true], // Single char, alpha top level domain.
50
            ["0.1", false], // Single char, non-alpha top level domain.
51
            ["example.com", true],
52
            ["sub.example.com", true],
53
            ["sub-domain.example-domain.net", true],
54
            ["123.com", true],
55
            ["123.a11", true],
56
            [str_repeat('sub.', 60) . "1-example.com", true], // Max length without null label is 253 octets = 253 ascii chars.
57
            [str_repeat('example', 9) . ".com", true], // Max number of octets per label is 63  = 63 ascii chars.
58
            ["localhost", true],
59
            [" example.com", false],
60
            ["example.com ", false],
61
            ["example.com/", false],
62
            ["*.example.com", false],
63
            ["*example.com", false],
64
            ["example.123", false],
65
            ["-example.com", false],
66
            ["example-.com", false],
67
            [".example.com", false],
68
            ["127.0.0.1", false],
69
            [str_repeat('sub.', 60) . "11-example.com", false], // Name length is 254 chars, which exceeds the max allowed.
70
            [str_repeat('example', 9) . "1.com", false], // Label length is 64 chars, which exceed the max allowed.
71
            ["example.com.", true], // Null label explicitly provided - this is valid.
72
            [".example.com.", false],
73
            ["見.香港", false], // IDNs are invalid.
74
            [null, false], // Non-strings are invalid.
75
        ];
76
    }
77
 
78
    /**
79
     * Test for \core\ip_utils::is_domain_matching_pattern().
80
     *
81
     * @param string $str the string to evaluate.
82
     * @param bool $expected the expected result.
83
     * @dataProvider domain_matching_patterns_data_provider
84
     */
11 efrain 85
    public function test_is_domain_matching_pattern($str, $expected): void {
1 efrain 86
        $this->assertEquals($expected, \core\ip_utils::is_domain_matching_pattern($str));
87
    }
88
 
89
    /**
90
     * Data provider for test_is_domain_matching_pattern().
91
     *
92
     * @return array
93
     */
1441 ariadna 94
    public static function domain_matching_patterns_data_provider(): array {
1 efrain 95
        return [
96
            ["*.com", true],
97
            ["*.example.com", true],
98
            ["*.example.com", true],
99
            ["*.sub.example.com", true],
100
            ["*.sub-domain.example-domain.com", true],
101
            ["*." . str_repeat('sub.', 60) . "example.com", true], // Max number of domain name chars = 253.
102
            ["*." . str_repeat('example', 9) . ".com", true], // Max number of domain name label chars = 63.
103
            ["*com", false],
104
            ["*example.com", false],
105
            [" *.example.com", false],
106
            ["*.example.com ", false],
107
            ["*-example.com", false],
108
            ["*.-example.com", false],
109
            ["*.example.com/", false],
110
            ["sub.*.example.com", false],
111
            ["sub.*example.com", false],
112
            ["*.*.example.com", false],
113
            ["example.com", false],
114
            ["*." . str_repeat('sub.', 60) . "1example.com", false], // Name length is 254 chars, which exceeds the max allowed.
115
            ["*." . str_repeat('example', 9) . "1.com", false], // Label length is 64 chars, which exceed the max allowed.
116
            ["*.example.com.", true], // Null label explicitly provided - this is valid.
117
            [".*.example.com.", false],
118
            ["*.香港", false], // IDNs are invalid.
119
            [null, false], // None-strings are invalid.
120
        ];
121
    }
122
 
123
    /**
124
     * Test for \core\ip_utils::is_ip_address().
125
     *
126
     * @param string $address the address to validate.
127
     * @param bool $expected the expected result.
128
     * @dataProvider ip_address_data_provider
129
     */
11 efrain 130
    public function test_is_ip_address($address, $expected): void {
1 efrain 131
        $this->assertEquals($expected, \core\ip_utils::is_ip_address($address));
132
    }
133
 
134
    /**
135
     * Data provider for test_is_ip_address().
136
     *
137
     * @return array
138
     */
1441 ariadna 139
    public static function ip_address_data_provider(): array {
1 efrain 140
        return [
141
            ["127.0.0.1", true],
142
            ["10.1", false],
143
            ["0.0.0.0", true],
144
            ["255.255.255.255", true],
145
            ["256.0.0.1", false],
146
            ["256.0.0.1", false],
147
            ["127.0.0.0/24", false],
148
            ["127.0.0.0-255", false],
149
            ["::", true],
150
            ["::0", true],
151
            ["0::", true],
152
            ["0::0", true],
153
            ["fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80", true],
154
            ["fe80::ffff", true],
155
            ["fe80::f", true],
156
            ["fe80::", true],
157
            ["0", false],
158
            ["127.0.0.0/24", false],
159
            ["fe80::fe80/128", false],
160
            ["fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80/128", false],
161
            ["fe80:", false],
162
            ["fe80:: ", false],
163
            [" fe80::", false],
164
            ["fe80::ddddd", false],
165
            ["fe80::gggg", false],
166
            ["fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80", false],
167
        ];
168
    }
169
 
170
    /**
171
     * Test for \core\ip_utils::is_ipv4_address().
172
     *
173
     * @param string $address the address to validate.
174
     * @param bool $expected the expected result.
175
     * @dataProvider ipv4_address_data_provider
176
     */
11 efrain 177
    public function test_is_ipv4_address($address, $expected): void {
1 efrain 178
        $this->assertEquals($expected, \core\ip_utils::is_ipv4_address($address));
179
    }
180
 
181
    /**
182
     * Data provider for test_is_ipv4_address().
183
     *
184
     * @return array
185
     */
1441 ariadna 186
    public static function ipv4_address_data_provider(): array {
1 efrain 187
        return [
188
            ["127.0.0.1", true],
189
            ["0.0.0.0", true],
190
            ["255.255.255.255", true],
191
            [" 127.0.0.1", false],
192
            ["127.0.0.1 ", false],
193
            ["-127.0.0.1", false],
194
            ["127.0.1", false],
195
            ["127.0.0.0.1", false],
196
            ["a.b.c.d", false],
197
            ["localhost", false],
198
            ["fe80::1", false],
199
            ["256.0.0.1", false],
200
            ["256.0.0.1", false],
201
            ["127.0.0.0/24", false],
202
            ["127.0.0.0-255", false],
203
        ];
204
    }
205
 
206
    /**
207
     * Test for \core\ip_utils::is_ipv4_range().
208
     *
209
     * @param string $addressrange the address range to validate.
210
     * @param bool $expected the expected result.
211
     * @dataProvider ipv4_range_data_provider
212
     */
11 efrain 213
    public function test_is_ipv4_range($addressrange, $expected): void {
1 efrain 214
        $this->assertEquals($expected, \core\ip_utils::is_ipv4_range($addressrange));
215
    }
216
 
217
    /**
218
     * Data provider for test_is_ipv4_range().
219
     *
220
     * @return array
221
     */
1441 ariadna 222
    public static function ipv4_range_data_provider(): array {
1 efrain 223
        return [
224
            ["127.0.0.1/24", true],
225
            ["127.0.0.20-20", true],
226
            ["127.0.0.20-50", true],
227
            ["127.0.0.0-255", true],
228
            ["127.0.0.1-1", true],
229
            ["255.255.255.0-255", true],
230
            ["127.0.0.1", false],
231
            ["127.0", false],
232
            [" 127.0.0.0/24", false],
233
            ["127.0.0.0/24 ", false],
234
            ["a.b.c.d/24", false],
235
            ["256.0.0.0-80", false],
236
            ["127.0.0.0/a", false],
237
            ["256.0.0.0/24", false],
238
            ["127.0.0.0/-1", false],
239
            ["127.0.0.0/33", false],
240
            ["127.0.0.0-127.0.0.10", false],
241
            ["127.0.0.30-20", false],
242
            ["127.0.0.0-256", false],
243
            ["fe80::fe80/64", false],
244
        ];
245
    }
246
 
247
    /**
248
     * Test for \core\ip_utils::is_ipv6_address().
249
     *
250
     * @param string $address the address to validate.
251
     * @param bool $expected the expected result.
252
     * @dataProvider ipv6_address_data_provider
253
     */
11 efrain 254
    public function test_is_ipv6_address($address, $expected): void {
1 efrain 255
        $this->assertEquals($expected, \core\ip_utils::is_ipv6_address($address));
256
    }
257
 
258
    /**
259
     * Data provider for test_is_ipv6_address().
260
     *
261
     * @return array
262
     */
1441 ariadna 263
    public static function ipv6_address_data_provider(): array {
1 efrain 264
        return [
265
            ["::", true],
266
            ["::0", true],
267
            ["0::", true],
268
            ["0::0", true],
269
            ["fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80", true],
270
            ["fe80::ffff", true],
271
            ["fe80::f", true],
272
            ["fe80::", true],
273
            ["0", false],
274
            ["127.0.0.0", false],
275
            ["127.0.0.0/24", false],
276
            ["fe80::fe80/128", false],
277
            ["fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80/128", false],
278
            ["fe80:", false],
279
            ["fe80:: ", false],
280
            [" fe80::", false],
281
            ["fe80::ddddd", false],
282
            ["fe80::gggg", false],
283
            ["fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80", false],
284
        ];
285
    }
286
 
287
    /**
288
     * Test for \core\ip_utils::is_ipv6_range().
289
     *
290
     * @param string $addressrange the address range to validate.
291
     * @param bool $expected the expected result.
292
     * @dataProvider ipv6_range_data_provider
293
     */
11 efrain 294
    public function test_is_ipv6_range($addressrange, $expected): void {
1 efrain 295
        $this->assertEquals($expected, \core\ip_utils::is_ipv6_range($addressrange));
296
    }
297
 
298
    /**
299
     * Data provider for test_is_ipv6_range().
300
     *
301
     * @return array
302
     */
1441 ariadna 303
    public static function ipv6_range_data_provider(): array {
1 efrain 304
        return [
305
            ["::/128", true],
306
            ["::1/128", true],
307
            ["fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80/128", true],
308
            ["fe80::dddd/128", true],
309
            ["fe80::/64", true],
310
            ["fe80::dddd-ffff", true],
311
            ["::0-ffff", true],
312
            ["::a-ffff", true],
313
            ["0", false],
314
            ["::1", false],
315
            ["fe80::fe80", false],
316
            ["::/128 ", false],
317
            [" ::/128", false],
318
            ["::/a", false],
319
            ["::/-1", false],
320
            ["fe80::fe80/129", false],
321
            ["fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80", false],
322
            ["fe80::bbbb-aaaa", false],
323
            ["fe80::0-fffg", false],
324
            ["fe80::0-fffff", false],
325
            ["fe80::0 - ffff", false],
326
            [" fe80::0-ffff", false],
327
            ["fe80::0-ffff ", false],
328
            ["192.0.0.0/24", false],
329
            ["fe80:::fe80/128", false],
330
            ["fe80:::aaaa-dddd", false],
331
        ];
332
    }
333
 
334
    /**
335
     * Test checking domains against a list of allowed domains.
336
     *
337
     * @param  bool $expected Expected result
338
     * @param  string $domain domain address
339
     * @dataProvider data_domain_addresses
340
     */
11 efrain 341
    public function test_check_domain_against_allowed_domains($expected, $domain): void {
1 efrain 342
        $alloweddomains = ['example.com',
343
                           '*.moodle.com',
344
                           '*.per.this.penny-arcade.com',
345
                           'bad.*.url.com',
346
                           ' trouble.com.au'];
347
        $this->assertEquals($expected, \core\ip_utils::is_domain_in_allowed_list($domain, $alloweddomains));
348
    }
349
 
350
    /**
351
     * Data provider for test_check_domain_against_allowed_domains.
352
     *
353
     * @return array
354
     */
1441 ariadna 355
    public static function data_domain_addresses(): array {
1 efrain 356
        return [
357
            [true, 'example.com'],
358
            [true, 'ExAmPle.com'],
359
            [false, 'sub.example.com'],
360
            [false, 'example.com.au'],
361
            [false, ' example.com'], // A space at the front of the domain is invalid.
362
            [false, 'example.123'], // Numbers at the end is invalid.
363
            [false, 'test.example.com'],
364
            [false, 'moodle.com'],
365
            [true, 'test.moodle.com'],
366
            [true, 'TeSt.moodle.com'],
367
            [true, 'test.MoOdLe.com'],
368
            [false, 'test.moodle.com.au'],
369
            [true, 'nice.address.per.this.penny-arcade.com'],
370
            [false, 'normal.per.this.penny-arcade.com.au'],
371
            [false, 'bad.thing.url.com'], // The allowed domain (above) has a bad wildcard and so this address will return false.
372
            [false, 'trouble.com.au'] // The allowed domain (above) has a space at the front and so will return false.
373
        ];
374
    }
375
 
376
    /**
377
     * Data provider for test_is_ip_in_subnet_list.
378
     *
379
     * @return array
380
     */
1441 ariadna 381
    public static function data_is_ip_in_subnet_list(): array {
1 efrain 382
        return [
383
            [true, '1.1.1.1', '1.1.1.1', "\n"],
384
            [false, '1.1.1.1', '2.2.2.2', "\n"],
385
            [true, '1.1.1.1', "1.1.1.5\n1.1.1.1", "\n"],
386
            [true, '1.1.1.1', "1.1.1.5,1.1.1.1", ","],
387
        ];
388
    }
389
 
390
    /**
391
     * Test checking ips against a list of allowed domains.
392
     *
393
     * @param  bool $expected Expected result
394
     * @param  string $ip IP address
395
     * @param  string $list list of  IP subnets
396
     * @param  string $delim delimiter of list
397
     * @dataProvider data_is_ip_in_subnet_list
398
     */
11 efrain 399
    public function test_is_ip_in_subnet_list($expected, $ip, $list, $delim): void {
1 efrain 400
        $this->assertEquals($expected, \core\ip_utils::is_ip_in_subnet_list($ip, $list, $delim));
401
    }
402
 
1441 ariadna 403
    /**
404
     * Data provider for test_normalize_internet_address.
405
     *
406
     * @return array
407
     */
408
    public static function normalize_internet_address_provider(): array {
409
        return [
410
            'Strip all white spaces on IP address' => [
411
                '   192.168.5.5  ',
412
                '192.168.5.5',
413
            ],
414
            'Strip all white spaces on domain name' => [
415
                ' www.moodle.org   ',
416
                'www.moodle.org',
417
            ],
418
            'Preserve IPv4 address' => [
419
                '127.0.0.1',
420
                '127.0.0.1',
421
            ],
422
            'Preserve IPv4 address range' => [
423
                '192.168.0.0/16',
424
                '192.168.0.0/16',
425
            ],
426
            'Preserve IPv6 address' => [
427
                'fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80',
428
                'fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80',
429
            ],
430
            'Preserve IPv6 address range' => [
431
                'fe80::ffff',
432
                'fe80::ffff',
433
            ],
434
            'Preserve valid domain' => [
435
                'localhost',
436
                'localhost',
437
            ],
438
            'Preserve valid FQDN' => [
439
                'www.moodle.org',
440
                'www.moodle.org',
441
            ],
442
            'Preserve valid FQDN with trailing dot' => [
443
                'www.moodle.com.',
444
                'www.moodle.com',
445
            ],
446
            'Preserve valid domain with wildcard' => [
447
                '*.moodledev.io',
448
                '*.moodledev.io',
449
            ],
450
            'Convert previous allowed "127." format to CIDR format (127.0.0.0/8)' => [
451
                '127.',
452
                '127.0.0.0/8',
453
            ],
454
            'Convert previous allowed "169.8." format to CIDR format (169.8.0.0/16)' => [
455
                '169.8.',
456
                '169.8.0.0/16',
457
            ],
458
            'Convert previous allowed "192.168.10." format to CIDR format (192.168.10.0/24)' => [
459
                '192.168.10.',
460
                '192.168.10.0/24',
461
            ],
462
            'Convert previous allowed ".moodle.org" subdomain format to new format (*.moodle.org)' => [
463
                '.moodle.org',
464
                '*.moodle.org',
465
            ],
466
            'Ignore invalid IPv4' => [
467
                '327.0.0.1',
468
                '',
469
            ],
470
            'Ignore invalid IPv4 range' => [
471
                '192.168',
472
                '',
473
            ],
474
            'Ignore invalid IPv6' => [
475
                'fe80::ddddd',
476
                '',
477
            ],
478
            'Ignore invalid IPv6 range' => [
479
                'fe80:',
480
                '',
481
            ],
482
            'Ignore invalid domain' => [
483
                '-example.com',
484
                '',
485
            ],
486
        ];
487
    }
488
 
489
    /**
490
     * Test if input address value is correctly normalized.
491
     *
492
     * @covers ::normalize_internet_address
493
     *
494
     * @dataProvider normalize_internet_address_provider
495
     *
496
     * @param string $input    Raw input value.
497
     * @param string $expected Expected value after normalization.
498
     */
499
    public function test_normalize_internet_address(string $input, string $expected): void {
500
        $this->assertEquals($expected, \core\ip_utils::normalize_internet_address($input));
501
    }
502
 
503
    /**
504
     * Data provider for test_normalize_internet_address_list.
505
     *
506
     * @return array
507
     */
508
    public static function normalize_internet_address_list_provider(): array {
509
        return [
510
            'Strip all white spaces' => [
511
                '   192.168.5.5, 127.0.0.1,    www.moodle.org   ',
512
                '192.168.5.5,127.0.0.1,www.moodle.org',
513
            ],
514
            'Trim input' => [
515
                '    192.168.5.5,127.0.0.1,www.moodle.org   ',
516
                '192.168.5.5,127.0.0.1,www.moodle.org',
517
            ],
518
            'Preserve valid full and partial IP' => [
519
                '127.0.0.1,192.168.0.0/16,fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80,fe80::ffff',
520
                '127.0.0.1,192.168.0.0/16,fe80:fe80:fe80:fe80:fe80:fe80:fe80:fe80,fe80::ffff',
521
            ],
522
            'Convert previous allowed format to new allowed format' => [
523
                '127.,169.8.,192.168.10.,.moodle.org',
524
                '127.0.0.0/8,169.8.0.0/16,192.168.10.0/24,*.moodle.org',
525
            ],
526
            'Preserve valid domain and pattern domain' => [
527
                'localhost,www.moodle.org,.moodle.com,*.moodledev.io',
528
                'localhost,www.moodle.org,*.moodle.com,*.moodledev.io',
529
            ],
530
            'Remove all invalid IP and domains' => [
531
                '327.0.0.1,192.168,fe80::ddddd,fe80:,-example.com',
532
                '',
533
            ],
534
            'Remove duplicate values' => [
535
                '.moodle.org,*.moodle.org,*.moodle.org,.moodle.org',
536
                '*.moodle.org',
537
            ],
538
        ];
539
    }
540
 
541
    /**
542
     * Test if input address list is correctly normalized.
543
     *
544
     * @covers ::normalize_internet_address_list
545
     *
546
     * @dataProvider normalize_internet_address_list_provider
547
     *
548
     * @param string $input    Raw input value.
549
     * @param string $expected Expected value after normalization.
550
     */
551
    public function test_normalize_internet_address_list(string $input, string $expected): void {
552
        $this->assertEquals($expected, \core\ip_utils::normalize_internet_address_list($input));
553
    }
1 efrain 554
}