Passed
Push — master ( 4af9a6...57ed85 )
by Alexander
02:04
created

IpFilter   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 46
Duplicated Lines 0 %

Test Coverage

Coverage 72.21%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 18
c 1
b 0
f 0
dl 0
loc 46
ccs 13
cts 18
cp 0.7221
rs 10
wmc 6

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A process() 0 13 4
A withIpValidator() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Web\Middleware;
6
7
use Psr\Http\Message\ResponseFactoryInterface;
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\Http\Status;
13
use Yiisoft\Validator\Rule\Ip;
14
15
final class IpFilter implements MiddlewareInterface
16
{
17
    private Ip $ipValidator;
18
    private ResponseFactoryInterface $responseFactory;
19
    private ?string $clientIpAttribute;
20
21
    /**
22
     * @param Ip $ipValidator Client IP validator. The properties of the validator can be modified up to the moment of processing.
23
     * @param \Psr\Http\Message\ResponseFactoryInterface $responseFactory
24
     * @param string|null $clientIpAttribute Attribute name of client IP. If NULL, then 'REMOTE_ADDR' value of the server parameters is processed.
25
     * If the value is not null, then the attribute specified must have a value, otherwise the request will closed with forbidden.
26
     */
27 2
    public function __construct(Ip $ipValidator, ResponseFactoryInterface $responseFactory, ?string $clientIpAttribute = null)
28
    {
29 2
        $this->ipValidator = $ipValidator;
30 2
        $this->responseFactory = $responseFactory;
31 2
        $this->clientIpAttribute = $clientIpAttribute;
32 2
    }
33
34
    public function withIpValidator(Ip $ipValidator): self
35
    {
36
        $new = clone $this;
37
        $new->ipValidator = $ipValidator;
38
        return $new;
39
    }
40
41
    /**
42
     * Process an incoming server request.
43
     *
44
     * Processes an incoming server request in order to produce a response.
45
     * If unable to produce the response itself, it may delegate to the provided
46
     * request handler to do so.
47
     */
48 2
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
49
    {
50 2
        $clientIp = $request->getServerParams()['REMOTE_ADDR'] ?? null;
51 2
        if ($this->clientIpAttribute !== null) {
52
            $clientIp = $request->getAttribute($clientIp);
53
        }
54 2
        if ($clientIp === null || !$this->ipValidator->disallowNegation()->disallowSubnet()->validate($clientIp)->isValid()) {
55 1
            $response = $this->responseFactory->createResponse(Status::FORBIDDEN);
56 1
            $response->getBody()->write(Status::TEXTS[Status::FORBIDDEN]);
57 1
            return $response;
58
        }
59
60 1
        return $handler->handle($request);
61
    }
62
}
63