Passed
Pull Request — master (#157)
by
unknown
02:27
created

TrustedHostsNetworkResolverTest::testTrusted()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 3
eloc 19
c 5
b 0
f 0
nc 4
nop 8
dl 0
loc 32
rs 9.6333

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