Completed
Pull Request — master (#157)
by Alexander
02:06 queued 16s
created

TrustedHostsNetworkResolverTest::testTrusted()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 33
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 3
eloc 19
c 3
b 0
f 0
nc 4
nop 8
dl 0
loc 33
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
    {
23
        $request = new ServerRequest('GET', '/', $headers, null, '1.1', $serverParams);
24
        $uri = $request->getUri()->withScheme($scheme);
25
        return $request->withUri($uri);
26
    }
27
28
    public function trustedDataProvider(): array
29
    {
30
        return [
31
            'xForwardLevel1' => [
32
                ['x-forwarded-for' => ['9.9.9.9', '5.5.5.5', '2.2.2.2']],
33
                ['REMOTE_ADDR' => '127.0.0.1'],
34
                [['hosts' => ['8.8.8.8', '127.0.0.1']]],
35
                '2.2.2.2',
36
            ],
37
            'xForwardLevel2' => [
38
                ['x-forwarded-for' => ['9.9.9.9', '5.5.5.5', '2.2.2.2']],
39
                ['REMOTE_ADDR' => '127.0.0.1'],
40
                [['hosts' => ['8.8.8.8', '127.0.0.1', '2.2.2.2']]],
41
                '5.5.5.5',
42
            ],
43
            'forwardLevel1' => [
44
                ['forward' => ['for=9.9.9.9', 'for=5.5.5.5', 'for=2.2.2.2']],
45
                ['REMOTE_ADDR' => '127.0.0.1'],
46
                [['hosts' => ['8.8.8.8', '127.0.0.1']]],
47
                '2.2.2.2',
48
            ],
49
            'forwardLevel2' => [
50
                ['forward' => ['for=9.9.9.9', 'for=5.5.5.5', 'for=2.2.2.2']],
51
                ['REMOTE_ADDR' => '127.0.0.1'],
52
                [['hosts' => ['8.8.8.8', '127.0.0.1', '2.2.2.2']]],
53
                '5.5.5.5',
54
            ],
55
            'forwardLevel2HostAndProtocol' => [
56
                ['forward' => ['for=9.9.9.9', 'proto=https;for=5.5.5.5;host=test', 'for=2.2.2.2']],
57
                ['REMOTE_ADDR' => '127.0.0.1'],
58
                [['hosts' => ['8.8.8.8', '127.0.0.1', '2.2.2.2']]],
59
                '5.5.5.5',
60
                'test',
61
                'https',
62
            ],
63
            'forwardLevel2HostAndProtocolAndUrl' => [
64
                [
65
                    'forward' => ['for=9.9.9.9', 'proto=https;for=5.5.5.5;host=test', 'for=2.2.2.2'],
66
                    'x-rewrite-url' => ['/test?test=test'],
67
                ],
68
                ['REMOTE_ADDR' => '127.0.0.1'],
69
                [['hosts' => ['8.8.8.8', '127.0.0.1', '2.2.2.2']]],
70
                '5.5.5.5',
71
                'test',
72
                'https',
73
                '/test',
74
                'test=test',
75
            ],
76
        ];
77
    }
78
79
    /**
80
     * @dataProvider trustedDataProvider
81
     */
82
    public function testTrusted(
83
        array $headers,
84
        array $serverParams,
85
        array $trustedHosts,
86
        string $expectedClientIp,
87
        ?string $expectedHttpHost = null,
88
        string $expectedHttpScheme = 'http',
89
        string $expectedPath = '/',
90
        string $expectedQuery = ''
91
    ): void
92
    {
93
        $request = $this->newRequestWithSchemaAndHeaders('http', $headers, $serverParams);
94
        $requestHandler = new MockRequestHandler();
95
96
        $middleware = new TrustedHostsNetworkResolver(new Psr17Factory());
97
        foreach ($trustedHosts as $data) {
98
            $middleware = $middleware->withAddedTrustedHosts(
99
                $data['hosts'],
100
                $data['ipHeaders'] ?? null,
101
                $data['protocolHeaders'] ?? null,
102
                null,
103
                null,
104
                $data['trustedHeaders'] ?? null);
105
        }
106
        $response = $middleware->process($request, $requestHandler);
107
        $this->assertSame(200, $response->getStatusCode());
108
        $this->assertSame($expectedClientIp, $requestHandler->processedRequest->getAttribute('requestClientIp'));
109
        if ($expectedHttpHost !== null) {
110
            $this->assertSame($expectedHttpHost, $requestHandler->processedRequest->getUri()->getHost());
111
        }
112
        $this->assertSame($expectedHttpScheme, $requestHandler->processedRequest->getUri()->getScheme());
113
        $this->assertSame($expectedPath, $requestHandler->processedRequest->getUri()->getPath());
114
        $this->assertSame($expectedQuery, $requestHandler->processedRequest->getUri()->getQuery());
115
    }
116
117
    public function notTrustedDataProvider(): array
118
    {
119
        return [
120
            'none' => [
121
                [],
122
                ['REMOTE_ADDR' => '127.0.0.1'],
123
                [],
124
            ],
125
            'x-forwarded-for' => [
126
                ['x-forwarded-for' => ['9.9.9.9', '5.5.5.5', '2.2.2.2']],
127
                ['REMOTE_ADDR' => '127.0.0.1'],
128
                [['hosts' => ['8.8.8.8']]],
129
            ],
130
            'forward' => [
131
                ['x-forwarded-for' => ['for=9.9.9.9', 'for=5.5.5.5', 'for=2.2.2.2']],
132
                ['REMOTE_ADDR' => '127.0.0.1'],
133
                [['hosts' => ['8.8.8.8']]],
134
            ],
135
        ];
136
    }
137
138
    /**
139
     * @dataProvider notTrustedDataProvider
140
     */
141
    public function testNotTrusted(array $headers, array $serverParams, array $trustedHosts): void
142
    {
143
        $request = $this->newRequestWithSchemaAndHeaders('http', $headers, $serverParams);
144
        $requestHandler = new MockRequestHandler();
145
146
        $middleware = new TrustedHostsNetworkResolver(new Psr17Factory());
147
        foreach ($trustedHosts as $data) {
148
            $middleware = $middleware->withAddedTrustedHosts(
149
                $data['hosts'],
150
                $data['ipHeaders'] ?? null,
151
                $data['protocolHeaders'] ?? null,
152
                null,
153
                null,
154
                $data['trustedHeaders'] ?? null);
155
        }
156
        $response = $middleware->process($request, $requestHandler);
157
        $this->assertSame(412, $response->getStatusCode());
158
    }
159
160
    public function testNotTrustedMiddleware(): void
161
    {
162
        $request = $this->newRequestWithSchemaAndHeaders('http', [], [
163
            'REMOTE_ADDR' => '127.0.0.1',
164
        ]);
165
        $requestHandler = new MockRequestHandler();
166
167
        $middleware = new TrustedHostsNetworkResolver(new Psr17Factory());
168
        $content = 'Another branch.';
169
        $middleware = $middleware->withNotTrustedBranch(new class($content) implements MiddlewareInterface {
170
            private $content;
171
172
            public function __construct(string $content)
173
            {
174
                $this->content = $content;
175
            }
176
177
            public function process(
178
                ServerRequestInterface $request,
179
                RequestHandlerInterface $handler
180
            ): ResponseInterface {
181
                $response = (new Psr17Factory())->createResponse(403);
182
                $response->getBody()->write($this->content);
183
                return $response;
184
            }
185
        });
186
        $response = $middleware->process($request, $requestHandler);
187
        $this->assertInstanceOf(ResponseInterface::class, $response);
188
        $this->assertSame(403, $response->getStatusCode());
189
        $body = $response->getBody();
190
        $body->rewind();
191
        $this->assertSame($content, $body->getContents());
192
    }
193
}
194