Passed
Pull Request — master (#52)
by Alexander
07:04
created

IpTest::testNetworkAliasException()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 8
rs 10
1
<?php
2
3
namespace Yiisoft\Validator\Tests\Rule;
4
5
use PHPUnit\Framework\TestCase;
6
use Yiisoft\Validator\Rule\Ip;
7
8
/**
9
 * @group validators
10
 */
11
class IpTest extends TestCase
12
{
13
    public function testInitException(): void
14
    {
15
        $this->expectException(\RuntimeException::class);
16
        $this->expectExceptionMessage('Both IPv4 and IPv6 checks can not be disabled at the same time');
17
        (new Ip())->disallowIpv4()->disallowIpv6()->validate('');
18
    }
19
20
    public function provideRangesForSubstitution(): array
21
    {
22
        return [
23
            'ipv4' => [['10.0.0.1'], ['10.0.0.1']],
24
            'any' => [['192.168.0.32', 'fa::/32', 'any'], ['192.168.0.32', 'fa::/32', '0.0.0.0/0', '::/0']],
25
            'ipv4+!private' => [
26
                ['10.0.0.1', '!private'],
27
                ['10.0.0.1', '!10.0.0.0/8', '!172.16.0.0/12', '!192.168.0.0/16', '!fd00::/8']
28
            ],
29
            'private+!system' => [
30
                ['private', '!system'],
31
                [
32
                    '10.0.0.0/8',
33
                    '172.16.0.0/12',
34
                    '192.168.0.0/16',
35
                    'fd00::/8',
36
                    '!224.0.0.0/4',
37
                    '!ff00::/8',
38
                    '!169.254.0.0/16',
39
                    '!fe80::/10',
40
                    '!127.0.0.0/8',
41
                    '!::1',
42
                    '!192.0.2.0/24',
43
                    '!198.51.100.0/24',
44
                    '!203.0.113.0/24',
45
                    '!2001:db8::/32'
46
                ]
47
            ],
48
        ];
49
    }
50
51
    /**
52
     * @dataProvider provideRangesForSubstitution
53
     */
54
    public function testRangesSubstitution(array $range, array $expectedRange): void
55
    {
56
        $validator = (new Ip())->ranges($range);
57
        $this->assertEquals($expectedRange, $validator->getRanges());
58
    }
59
60
61
    public function testValidateOrder(): void
62
    {
63
        $validator = (new Ip())->ranges(['10.0.0.1', '!10.0.0.0/8', '!babe::/8', 'any']);
64
65
        $this->assertTrue($validator->validate('10.0.0.1')->isValid());
66
        $this->assertFalse($validator->validate('10.0.0.2')->isValid());
67
        $this->assertTrue($validator->validate('192.168.5.101')->isValid());
68
        $this->assertTrue($validator->validate('cafe::babe')->isValid());
69
        $this->assertFalse($validator->validate('babe::cafe')->isValid());
70
    }
71
72
    public function provideBadIps(): array
73
    {
74
        return [
75
            'notIpString' => ['not.an.ip'],
76
            'notIpString2' => ['bad:forSure'],
77
            'array' => [['what an array', '??']],
78
            'int' => [123456],
79
            'boolTrue' => [true],
80
            'boolFalse' => [false],
81
        ];
82
    }
83
84
    /**
85
     * @dataProvider provideBadIps
86
     */
87
    public function testValidateNotAnIP($badIp): void
88
    {
89
        $validator = new Ip();
90
        $this->assertFalse($validator->validate($badIp)->isValid());
91
    }
92
93
    public function testValidateIPv4()
94
    {
95
        $validator = new Ip();
96
97
        $this->assertTrue($validator->validate('192.168.10.11')->isValid());
98
        $this->assertFalse($validator->validate('192.168.005.001')->isValid()); // leading zero not supported
99
        $this->assertFalse($validator->validate('192.168.5.321')->isValid());
100
        $this->assertFalse($validator->validate('!192.168.5.32')->isValid());
101
        $this->assertFalse($validator->validate('192.168.5.32/11')->isValid());
102
103
        $validator->disallowIpv4();
104
        $this->assertFalse($validator->validate('192.168.10.11')->isValid());
105
106
        $validator->allowIpv4();
107
        $validator->allowSubnet();
108
109
        $this->assertTrue($validator->validate('192.168.5.32/11')->isValid());
110
        $this->assertTrue($validator->validate('192.168.5.32/32')->isValid());
111
        $this->assertTrue($validator->validate('0.0.0.0/0')->isValid());
112
        $this->assertFalse($validator->validate('192.168.5.32/33')->isValid());
113
        $this->assertFalse($validator->validate('192.168.5.32/33')->isValid());
114
        $this->assertFalse($validator->validate('192.168.5.32/af')->isValid());
115
        $this->assertFalse($validator->validate('192.168.5.32/11/12')->isValid());
116
117
        $validator->requireSubnet();
118
        $this->assertTrue($validator->validate('10.0.0.1/24')->isValid());
119
        $this->assertTrue($validator->validate('10.0.0.1/0')->isValid());
120
        $this->assertFalse($validator->validate('10.0.0.1')->isValid());
121
122
        $validator->allowNegation();
123
        $this->assertTrue($validator->validate('!192.168.5.32/32')->isValid());
124
        $this->assertFalse($validator->validate('!!192.168.5.32/32')->isValid());
125
    }
126
127
128
    public function testValidateIPv6()
129
    {
130
        $validator = new Ip();
131
132
        $this->assertTrue($validator->validate('2008:fa::1')->isValid());
133
        $this->assertTrue($validator->validate('2008:00fa::0001')->isValid());
134
        $this->assertFalse($validator->validate('2008:fz::0')->isValid());
135
        $this->assertFalse($validator->validate('2008:fa::0::1')->isValid());
136
        $this->assertFalse($validator->validate('!2008:fa::0::1')->isValid());
137
        $this->assertFalse($validator->validate('2008:fa::0:1/64')->isValid());
138
139
        $validator->disallowIpv4();
140
        $this->assertTrue($validator->validate('2008:fa::1')->isValid());
141
142
        $validator->allowIpv6();
143
        $validator->allowSubnet();
144
145
        $this->assertTrue($validator->validate('2008:fa::0:1/64')->isValid());
146
        $this->assertTrue($validator->validate('2008:fa::0:1/128')->isValid());
147
        $this->assertTrue($validator->validate('2008:fa::0:1/0')->isValid());
148
        $this->assertFalse($validator->validate('!2008:fa::0:1/0')->isValid());
149
        $this->assertFalse($validator->validate('2008:fz::0/129')->isValid());
150
151
        $validator->requireSubnet();
152
        $this->assertTrue($validator->validate('2008:db0::1/64')->isValid());
153
        $this->assertFalse($validator->validate('2008:db0::1')->isValid());
154
155
        $validator->allowNegation();
156
        $this->assertTrue($validator->validate('!2008:fa::0:1/64')->isValid());
157
        $this->assertFalse($validator->validate('!!2008:fa::0:1/64')->isValid());
158
    }
159
160
    public function testValidateIPvBoth()
161
    {
162
        $validator = new Ip();
163
164
        $this->assertTrue($validator->validate('192.168.10.11')->isValid());
165
        $this->assertTrue($validator->validate('2008:fa::1')->isValid());
166
        $this->assertTrue($validator->validate('2008:00fa::0001')->isValid());
167
        $this->assertFalse($validator->validate('192.168.005.001')->isValid()); // leading zero not allowed
168
        $this->assertFalse($validator->validate('192.168.5.321')->isValid());
169
        $this->assertFalse($validator->validate('!192.168.5.32')->isValid());
170
        $this->assertFalse($validator->validate('192.168.5.32/11')->isValid());
171
        $this->assertFalse($validator->validate('2008:fz::0')->isValid());
172
        $this->assertFalse($validator->validate('2008:fa::0::1')->isValid());
173
        $this->assertFalse($validator->validate('!2008:fa::0::1')->isValid());
174
        $this->assertFalse($validator->validate('2008:fa::0:1/64')->isValid());
175
176
        $validator->disallowIpv4();
177
        $this->assertFalse($validator->validate('192.168.10.11')->isValid());
178
        $this->assertTrue($validator->validate('2008:fa::1')->isValid());
179
180
        $validator->disallowIpv6();
181
        $validator->allowIpv4();
182
        $this->assertTrue($validator->validate('192.168.10.11')->isValid());
183
        $this->assertFalse($validator->validate('2008:fa::1')->isValid());
184
185
        $validator->allowIpv6();
186
        $validator->requireSubnet();
187
188
        $this->assertTrue($validator->validate('192.168.5.32/11')->isValid());
189
        $this->assertTrue($validator->validate('192.168.5.32/32')->isValid());
190
        $this->assertTrue($validator->validate('0.0.0.0/0')->isValid());
191
        $this->assertTrue($validator->validate('2008:fa::0:1/64')->isValid());
192
        $this->assertTrue($validator->validate('2008:fa::0:1/128')->isValid());
193
        $this->assertTrue($validator->validate('2008:fa::0:1/0')->isValid());
194
        $this->assertFalse($validator->validate('!2008:fa::0:1/0')->isValid());
195
        $this->assertFalse($validator->validate('192.168.5.32/33')->isValid());
196
        $this->assertFalse($validator->validate('2008:fz::0/129')->isValid());
197
        $this->assertFalse($validator->validate('192.168.5.32/33')->isValid());
198
        $this->assertFalse($validator->validate('192.168.5.32/af')->isValid());
199
        $this->assertFalse($validator->validate('192.168.5.32/11/12')->isValid());
200
201
        $validator->requireSubnet();
202
        $this->assertTrue($validator->validate('10.0.0.1/24')->isValid());
203
        $this->assertTrue($validator->validate('10.0.0.1/0')->isValid());
204
        $this->assertTrue($validator->validate('2008:db0::1/64')->isValid());
205
        $this->assertFalse($validator->validate('2008:db0::1')->isValid());
206
        $this->assertFalse($validator->validate('10.0.0.1')->isValid());
207
208
        $validator->allowNegation();
209
210
        $this->assertTrue($validator->validate('!192.168.5.32/32')->isValid());
211
        $this->assertTrue($validator->validate('!2008:fa::0:1/64')->isValid());
212
        $this->assertFalse($validator->validate('!!192.168.5.32/32')->isValid());
213
        $this->assertFalse($validator->validate('!!2008:fa::0:1/64')->isValid());
214
    }
215
216
    public function testValidateRangeIPv4()
217
    {
218
        $validator = (new Ip())->ranges(['10.0.1.0/24']);
219
        $this->assertTrue($validator->validate('10.0.1.2')->isValid());
220
        $this->assertFalse($validator->validate('192.5.1.1')->isValid());
221
222
        $validator->ranges(['10.0.1.0/24']);
223
        $this->assertTrue($validator->validate('10.0.1.2')->isValid());
224
        $this->assertFalse($validator->validate('10.0.3.2')->isValid());
225
226
        $validator->ranges(['!10.0.1.0/24', '10.0.0.0/8', 'localhost']);
227
        $this->assertFalse($validator->validate('10.0.1.2')->isValid());
228
        $this->assertTrue($validator->validate('127.0.0.1')->isValid());
229
230
        $validator->allowSubnet();
231
        $validator->ranges(['10.0.1.0/24', '!10.0.0.0/8', 'localhost']);
232
        $this->assertTrue($validator->validate('10.0.1.2')->isValid());
233
        $this->assertTrue($validator->validate('127.0.0.1')->isValid());
234
        $this->assertTrue($validator->validate('10.0.1.28/28')->isValid());
235
        $this->assertFalse($validator->validate('10.2.2.2')->isValid());
236
        $this->assertFalse($validator->validate('10.0.1.1/22')->isValid());
237
    }
238
239
    public function testValidateRangeIPv6()
240
    {
241
        $validator = (new Ip())->ranges(['2001:db0:1:1::/64']);
242
        $this->assertTrue($validator->validate('2001:db0:1:1::6')->isValid());
243
        $this->assertFalse($validator->validate('2001:db0:1:2::7')->isValid());
244
245
        $validator->ranges(['2001:db0:1:2::/64']);
246
        $this->assertTrue($validator->validate('2001:db0:1:2::7')->isValid());
247
248
        $validator->ranges(['!2001:db0::/32', '2001:db0:1:2::/64']);
249
        $this->assertFalse($validator->validate('2001:db0:1:2::7')->isValid());
250
251
        $validator->allowSubnet();
252
        $validator->ranges(array_reverse($validator->getRanges()));
253
        $this->assertTrue($validator->validate('2001:db0:1:2::7')->isValid());
254
    }
255
256
    public function testValidateRangeIPvBoth()
257
    {
258
        $validator = (new Ip())->ranges(['10.0.1.0/24']);
259
        $this->assertTrue($validator->validate('10.0.1.2')->isValid());
260
        $this->assertFalse($validator->validate('192.5.1.1')->isValid());
261
        $this->assertFalse($validator->validate('2001:db0:1:2::7')->isValid());
262
263
        $validator->ranges(['10.0.1.0/24', '2001:db0:1:2::/64', '127.0.0.1']);
264
        $this->assertTrue($validator->validate('2001:db0:1:2::7')->isValid());
265
        $this->assertTrue($validator->validate('10.0.1.2')->isValid());
266
        $this->assertFalse($validator->validate('10.0.3.2')->isValid());
267
268
        $validator->ranges(['!system', 'any']);
269
        $this->assertFalse($validator->validate('127.0.0.1')->isValid());
270
        $this->assertFalse($validator->validate('fe80::face')->isValid());
271
        $this->assertTrue($validator->validate('8.8.8.8')->isValid());
272
273
        $validator->allowSubnet();
274
        $validator->ranges(['10.0.1.0/24', '2001:db0:1:2::/64', 'localhost', '!any']);
275
        $this->assertTrue($validator->validate('10.0.1.2')->isValid());
276
        $this->assertTrue($validator->validate('2001:db0:1:2::7')->isValid());
277
        $this->assertTrue($validator->validate('127.0.0.1')->isValid());
278
        $this->assertTrue($validator->validate('10.0.1.28/28')->isValid());
279
        $this->assertFalse($validator->validate('10.2.2.2')->isValid());
280
        $this->assertFalse($validator->validate('10.0.1.1/22')->isValid());
281
    }
282
283
    public function testIpv4LeadingZero(): void
284
    {
285
        $this->assertFalse((new Ip())->validate('01.01.01.01')->isValid());
286
        $this->assertFalse((new Ip())->validate('010.010.010.010')->isValid());
287
        $this->assertFalse((new Ip())->validate('001.001.001.001')->isValid());
288
    }
289
290
    public function testNetworkAliase(): void
291
    {
292
        $validator = (new Ip())->network('myNetworkEu', ['1.2.3.4/10', '5.6.7.8'])
293
            ->ranges(['myNetworkEu']);
294
        $this->assertTrue($validator->validate('1.2.3.4')->isValid());
295
        $this->assertTrue($validator->validate('5.6.7.8')->isValid());
296
    }
297
298
    public function testNetworkAliasException(): void
299
    {
300
        $validator = (new Ip())->network('myNetworkEu', ['1.2.3.4/10', '5.6.7.8'])
301
            ->ranges(['myNetworkEu']);
302
303
        $this->expectException(\RuntimeException::class);
304
        $this->expectExceptionMessage('Network alias "myNetworkEu" already set');
305
        $validator->network('myNetworkEu', ['!1.2.3.4/10', '!5.6.7.8']);
306
    }
307
}
308