Completed
Pull Request — master (#157)
by
unknown
10:28
created

TrustedHostsNetworkResolverTest::testTrusted()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 35
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 1
Metric Value
cc 3
eloc 21
c 6
b 0
f 1
nc 4
nop 9
dl 0
loc 35
rs 9.584

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace Yiisoft\Yii\Web\Tests\Middleware;
4
5
use Nyholm\Psr7\Factory\Psr17Factory;
6
use Nyholm\Psr7\ServerRequest;
7
use PHPUnit\Framework\TestCase;
8
use Psr\Http\Message\ServerRequestInterface;
9
use Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver;
10
use Yiisoft\Yii\Web\Tests\Middleware\Mock\MockRequestHandler;
11
12
class TrustedHostsNetworkResolverTest extends TestCase
13
{
14
    protected function newRequestWithSchemaAndHeaders(
15
        string $scheme = 'http',
16
        array $headers = [],
17
        array $serverParams = []
18
    ): ServerRequestInterface {
19
        $request = new ServerRequest('GET', '/', $headers, null, '1.1', $serverParams);
20
        $uri = $request->getUri()->withScheme($scheme);
21
        return $request->withUri($uri);
22
    }
23
24
    public function trustedDataProvider(): array
25
    {
26
        return [
27
            'xForwardLevel1' => [
28
                ['x-forwarded-for' => ['9.9.9.9', '5.5.5.5', '2.2.2.2']],
29
                ['REMOTE_ADDR' => '127.0.0.1'],
30
                [
31
                    ['hosts' => ['8.8.8.8', '127.0.0.1'], 'ipHeaders' => ['x-forwarded-for']]
32
                ],
33
                '2.2.2.2',
34
            ],
35
            'xForwardLevel2' => [
36
                ['x-forwarded-for' => ['9.9.9.9', '5.5.5.5', '2.2.2.2']],
37
                ['REMOTE_ADDR' => '127.0.0.1'],
38
                [
39
                    ['hosts' => ['8.8.8.8', '127.0.0.1', '2.2.2.2'], 'ipHeaders' => ['x-forwarded-for']],
40
                ],
41
                '5.5.5.5',
42
            ],
43
            'rfc7239Level1' => [
44
                ['forwarded' => ['for=9.9.9.9', 'for=5.5.5.5', 'for=2.2.2.2']],
45
                ['REMOTE_ADDR' => '127.0.0.1'],
46
                [
47
                    [
48
                        'hosts' => ['8.8.8.8', '127.0.0.1'],
49
                        'ipHeaders' => [[TrustedHostsNetworkResolver::IP_HEADER_TYPE_RFC7239, 'forwarded']],
50
                    ]
51
                ],
52
                '2.2.2.2',
53
            ],
54
            'rfc7239Level2' => [
55
                ['forwarded' => ['for=9.9.9.9', 'for=5.5.5.5', 'for=2.2.2.2']],
56
                ['REMOTE_ADDR' => '127.0.0.1'],
57
                [
58
                    [
59
                        'hosts' => ['8.8.8.8', '127.0.0.1', '2.2.2.2'],
60
                        'ipHeaders' => [[TrustedHostsNetworkResolver::IP_HEADER_TYPE_RFC7239, 'forwarded']],
61
                    ],
62
63
                ],
64
                '5.5.5.5',
65
            ],
66
            'rfc7239Level2HostAndProtocol' => [
67
                ['forwarded' => ['for=9.9.9.9', 'proto=https;for=5.5.5.5;host=test', 'for=2.2.2.2']],
68
                ['REMOTE_ADDR' => '127.0.0.1'],
69
                [
70
                    [
71
                        'hosts' => ['8.8.8.8', '127.0.0.1', '2.2.2.2'],
72
                        'ipHeaders' => [[TrustedHostsNetworkResolver::IP_HEADER_TYPE_RFC7239, 'forwarded']],
73
                        'hostHeaders' => ['forwarded'],
74
                        'protocolHeaders' => ['forwarded' => ['http' => 'http', 'https' => 'https']],
75
                    ],
76
                ],
77
                '5.5.5.5',
78
                'test',
79
                'https',
80
            ],
81
            'rfc7239Level2HostAndProtocolAndUrl' => [
82
                [
83
                    'forwarded' => ['for=9.9.9.9', 'proto=https;for=5.5.5.5;host=test', 'for=2.2.2.2'],
84
                    'x-rewrite-url' => ['/test?test=test'],
85
                ],
86
                ['REMOTE_ADDR' => '127.0.0.1'],
87
                [
88
                    [
89
                        'hosts' => ['8.8.8.8', '127.0.0.1', '2.2.2.2'],
90
                        'ipHeaders' => [[TrustedHostsNetworkResolver::IP_HEADER_TYPE_RFC7239, 'forwarded']],
91
                        'hostHeaders' => ['forwarded'],
92
                        'protocolHeaders' => ['forwarded' => ['http' => 'http', 'https' => 'https']],
93
                        'urlHeaders' => ['x-rewrite-url'],
94
                    ],
95
                ],
96
                '5.5.5.5',
97
                'test',
98
                'https',
99
                '/test',
100
                'test=test',
101
            ],
102
            'rfc7239Level2AnotherHost&AnotherProtocol&Url' => [
103
                [
104
                    'forwarded' => ['for=9.9.9.9', 'proto=https;for=5.5.5.5;host=test', 'for=2.2.2.2'],
105
                    'x-rewrite-url' => ['/test?test=test'],
106
                    'x-forwarded-host' => ['test.another'],
107
                    'x-forwarded-proto' => ['on']
108
                ],
109
                ['REMOTE_ADDR' => '127.0.0.1'],
110
                [
111
                    [
112
                        'hosts' => ['8.8.8.8', '127.0.0.1', '2.2.2.2'],
113
                        'ipHeaders' => [[TrustedHostsNetworkResolver::IP_HEADER_TYPE_RFC7239, 'forwarded']],
114
                        'hostHeaders' => ['x-forwarded-host', 'forwarded'],
115
                        'protocolHeaders' => [
116
                            'x-forwarded-proto' => ['http' => 'http', 'httpsss' => 'on'],
117
                            'forwarded' => ['http' => 'http', 'https' => 'https']
118
                        ],
119
                        'urlHeaders' => ['x-rewrite-url'],
120
                    ],
121
                ],
122
                '5.5.5.5',
123
                'test.another',
124
                'httpsss',
125
                '/test',
126
                'test=test',
127
            ],
128
            'rfc7239Level2AnotherHost&AnotherProtocol&Url&Port' => [
129
                [
130
                    'forwarded' => ['for=9.9.9.9', 'proto=https;for="5.5.5.5:123";host=test', 'for=2.2.2.2'],
131
                    'x-rewrite-url' => ['/test?test=test'],
132
                    'x-forwarded-host' => ['test.another'],
133
                    'x-forwarded-proto' => ['on']
134
                ],
135
                ['REMOTE_ADDR' => '127.0.0.1'],
136
                [
137
                    [
138
                        'hosts' => ['8.8.8.8', '127.0.0.1', '2.2.2.2'],
139
                        'ipHeaders' => [[TrustedHostsNetworkResolver::IP_HEADER_TYPE_RFC7239, 'forwarded']],
140
                        'hostHeaders' => ['x-forwarded-host', 'forwarded'],
141
                        'protocolHeaders' => [
142
                            'x-forwarded-proto' => ['http' => 'http', 'httpsss' => 'on'],
143
                            'forwarded' => ['http' => 'http', 'https' => 'https']
144
                        ],
145
                        'urlHeaders' => ['x-rewrite-url'],
146
                        'portHeaders' => ['forwarded'],
147
                    ],
148
                ],
149
                '5.5.5.5',
150
                'test.another',
151
                'httpsss',
152
                '/test',
153
                'test=test',
154
                123,
155
            ],
156
        ];
157
    }
158
159
    /**
160
     * @dataProvider trustedDataProvider
161
     */
162
    public function testTrusted(
163
        array $headers,
164
        array $serverParams,
165
        array $trustedHosts,
166
        string $expectedClientIp,
167
        ?string $expectedHttpHost = null,
168
        string $expectedHttpScheme = 'http',
169
        string $expectedPath = '/',
170
        string $expectedQuery = '',
171
        ?int $expectedPort = null
172
    ): void {
173
        $request = $this->newRequestWithSchemaAndHeaders('http', $headers, $serverParams);
174
        $requestHandler = new MockRequestHandler();
175
176
        $middleware = new TrustedHostsNetworkResolver(new Psr17Factory());
177
        foreach ($trustedHosts as $data) {
178
            $middleware = $middleware->withAddedTrustedHosts(
179
                $data['hosts'],
180
                $data['ipHeaders'] ?? [],
181
                $data['protocolHeaders'] ?? [],
182
                $data['hostHeaders'] ?? [],
183
                $data['urlHeaders'] ?? [],
184
                $data['portHeaders'] ?? [],
185
                $data['trustedHeaders'] ?? null);
186
        }
187
        $response = $middleware->process($request, $requestHandler);
188
        $this->assertSame(200, $response->getStatusCode());
189
        $this->assertSame($expectedClientIp, $requestHandler->processedRequest->getAttribute('requestClientIp'));
190
        if ($expectedHttpHost !== null) {
191
            $this->assertSame($expectedHttpHost, $requestHandler->processedRequest->getUri()->getHost());
192
        }
193
        $this->assertSame($expectedHttpScheme, $requestHandler->processedRequest->getUri()->getScheme());
194
        $this->assertSame($expectedPath, $requestHandler->processedRequest->getUri()->getPath());
195
        $this->assertSame($expectedQuery, $requestHandler->processedRequest->getUri()->getQuery());
196
        $this->assertSame($expectedPort, $requestHandler->processedRequest->getUri()->getPort());
197
    }
198
199
    public function notTrustedDataProvider(): array
200
    {
201
        return [
202
            'none' => [
203
                [],
204
                ['REMOTE_ADDR' => '127.0.0.1'],
205
                [],
206
            ],
207
            'x-forwarded-for' => [
208
                ['x-forwarded-for' => ['9.9.9.9', '5.5.5.5', '2.2.2.2']],
209
                ['REMOTE_ADDR' => '127.0.0.1'],
210
                [['hosts' => ['8.8.8.8'], 'ipHeaders' => ['x-forwarded-for']]],
211
            ],
212
            'rfc7239' => [
213
                ['x-forwarded-for' => ['for=9.9.9.9', 'for=5.5.5.5', 'for=2.2.2.2']],
214
                ['REMOTE_ADDR' => '127.0.0.1'],
215
                [['hosts' => ['8.8.8.8'], 'ipHeaders' => ['x-forwarded-for']]],
216
            ],
217
        ];
218
    }
219
220
    /**
221
     * @dataProvider notTrustedDataProvider
222
     */
223
    public function testNotTrusted(array $headers, array $serverParams, array $trustedHosts): void
224
    {
225
        $request = $this->newRequestWithSchemaAndHeaders('http', $headers, $serverParams);
226
        $requestHandler = new MockRequestHandler();
227
228
        $middleware = new TrustedHostsNetworkResolver(new Psr17Factory());
229
        foreach ($trustedHosts as $data) {
230
            $middleware = $middleware->withAddedTrustedHosts(
231
                $data['hosts'],
232
                $data['ipHeaders'] ?? [],
233
                $data['protocolHeaders'] ?? [],
234
                [],
235
                [],
236
                [],
237
                $data['trustedHeaders'] ?? []);
238
        }
239
        $middleware->process($request, $requestHandler);
240
        $this->assertNull($request->getAttribute('requestClientIp'));
241
    }
242
243
    public function addedTrustedHostsInvalidParameterDataProvider(): array
244
    {
245
        return [
246
            'hostsEmpty' => ['hosts' => []],
247
            'hostsEmptyString' => ['hosts' => ['']],
248
            'hostsNumeric' => ['hosts' => [888]],
249
            'hostsSpaces' => ['hosts' => ['    ']],
250
            'hostsNotDomain' => ['host' => ['-apple']],
251
            'urlHeadersEmpty' => ['urlHeaders' => ['']],
252
            'urlHeadersNumeric' => ['urlHeaders' => [888]],
253
            'urlHeadersSpaces' => ['urlHeaders' => ['   ']],
254
            'trustedHeadersEmpty' => ['trustedHeaders' => ['']],
255
            'trustedHeadersNumeric' => ['trustedHeaders' => [888]],
256
            'trustedHeadersSpaces' => ['trustedHeaders' => ['   ']],
257
            'protocolHeadersNumeric' => ['protocolHeaders' => ['http' => 888]],
258
            'ipHeadersEmptyString' => ['ipHeaders' => [' ']],
259
            'ipHeadersNumeric' => ['ipHeaders' => [888]],
260
            'ipHeadersInvalidType' => ['ipHeaders' => [['---', 'aaa']]],
261
            'ipHeadersInvalidTypeValue' => [
262
                'ipHeaders' => [
263
                    [
264
                        TrustedHostsNetworkResolver::IP_HEADER_TYPE_RFC7239,
265
                        888
266
                    ]
267
                ]
268
            ],
269
        ];
270
    }
271
272
    /**
273
     * @dataProvider addedTrustedHostsInvalidParameterDataProvider
274
     */
275
    public function testAddedTrustedHostsInvalidParameter(array $data): void
276
    {
277
        $this->expectException(\InvalidArgumentException::class);
278
        (new TrustedHostsNetworkResolver(new Psr17Factory()))
279
            ->withAddedTrustedHosts($data['hosts'] ?? [],
280
                $data['ipHeaders'] ?? [],
281
                $data['protocolHeaders'] ?? [],
282
                $data['hostHeaders'] ?? [],
283
                $data['urlHeaders'] ?? [],
284
                $data['portHeaders'] ?? [],
285
                $data['trustedHeaders'] ?? null
286
            );
287
    }
288
}
289