Passed
Pull Request — master (#157)
by
unknown
01:50
created

TrustedHostsNetworkResolverTest::testTrusted()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

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