Completed
Pull Request — master (#157)
by
unknown
02:10
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
            private $content;
190
191
            public function __construct(string $content)
192
            {
193
                $this->content = $content;
194
            }
195
196
            public function process(
197
                ServerRequestInterface $request,
198
                RequestHandlerInterface $handler
199
            ): ResponseInterface {
200
                $response = (new Psr17Factory())->createResponse(403);
201
                $response->getBody()->write($this->content);
202
                return $response;
203
            }
204
        });
205
        $response = $middleware->process($request, $requestHandler);
206
        $this->assertInstanceOf(ResponseInterface::class, $response);
207
        $this->assertSame(403, $response->getStatusCode());
208
        $body = $response->getBody();
209
        $body->rewind();
210
        $this->assertSame($content, $body->getContents());
211
    }
212
213
    public function addedTrustedHostsInvalidParameterDataProvider(): array
214
    {
215
        return [
216
            'hostsEmpty' => ['hosts' => []],
217
            'hostsEmptyString' => ['hosts' => ['']],
218
            'hostsNumeric' => ['hosts' => [888]],
219
            'hostsSpaces' => ['hosts' => ['    ']],
220
            'hostsNotDomain' => ['host' => ['-apple']],
221
            'urlHeadersEmpty' => ['urlHeaders' => ['']],
222
            'urlHeadersNumeric' => ['urlHeaders' => [888]],
223
            'urlHeadersSpaces' => ['urlHeaders' => ['   ']],
224
            'trustedHeadersEmpty' => ['trustedHeaders' => ['']],
225
            'trustedHeadersNumeric' => ['trustedHeaders' => [888]],
226
            'trustedHeadersSpaces' => ['trustedHeaders' => ['   ']],
227
            'protocolHeadersNumeric' => ['protocolHeaders' => ['http' => 888]],
228
            'ipHeadersEmptyString' => ['ipHeaders' => [' ']],
229
            'ipHeadersNumeric' => ['ipHeaders' => [888]],
230
            'ipHeadersInvalidType' => ['ipHeaders' => [['---', 'aaa']]],
231
            'ipHeadersInvalidTypeValue' => [
232
                'ipHeaders' => [
233
                    [
234
                        TrustedHostsNetworkResolver::IP_HEADER_TYPE_RFC7239,
235
                        888
236
                    ]
237
                ]
238
            ],
239
        ];
240
    }
241
242
    /**
243
     * @dataProvider addedTrustedHostsInvalidParameterDataProvider
244
     */
245
    public function testAddedTrustedHostsInvalidParameter(array $data): void
246
    {
247
        $this->expectException(\InvalidArgumentException::class);
248
        (new TrustedHostsNetworkResolver(new Psr17Factory()))
249
            ->withAddedTrustedHosts($data['hosts'] ?? [],
250
                $data['ipHeaders'] ?? null,
251
                $data['protocolHeaders'] ?? null,
252
                $data['hostHeaders'] ?? null,
253
                $data['urlHeaders'] ?? null,
254
                $data['trustedHeaders'] ?? null
255
            );
256
    }
257
}
258