Passed
Push — master ( 08487a...efba4c )
by Eugene
07:28
created

FirewallMiddleware   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 13
eloc 28
dl 0
loc 71
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A withBlacklist() 0 6 1
A whitelist() 0 3 1
A add() 0 10 3
A blacklist() 0 3 1
A process() 0 13 4
A withWhitelist() 0 6 1
A readOnly() 0 6 1
A __construct() 0 4 1
1
<?php
2
3
/**
4
 * This file is part of the Tarantool Client package.
5
 *
6
 * (c) Eugene Leonovich <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Tarantool\Client\Middleware;
15
16
use Tarantool\Client\Exception\RequestForbidden;
17
use Tarantool\Client\Handler\Handler;
18
use Tarantool\Client\Request\AuthenticateRequest;
19
use Tarantool\Client\Request\PingRequest;
20
use Tarantool\Client\Request\Request;
21
use Tarantool\Client\Request\SelectRequest;
22
use Tarantool\Client\Response;
23
24
final class FirewallMiddleware implements Middleware
25
{
26
    private $whitelist;
27
    private $blacklist;
28
29
    public function __construct(array $whitelist, array $blacklist)
30
    {
31
        $this->whitelist = self::add($whitelist);
32
        $this->blacklist = self::add($blacklist);
33
    }
34
35
    public static function whitelist(string ...$requestClasses) : self
36
    {
37
        return new self($requestClasses, []);
38
    }
39
40
    public static function blacklist(string ...$requestClasses) : self
41
    {
42
        return new self([], $requestClasses);
43
    }
44
45
    public static function readOnly() : self
46
    {
47
        return self::whitelist(
48
            AuthenticateRequest::class,
49
            PingRequest::class,
50
            SelectRequest::class
51
        );
52
    }
53
54
    public function withWhitelist(string ...$requestClasses) : self
55
    {
56
        $new = clone $this;
57
        $new->whitelist = self::add($requestClasses, $new->whitelist);
58
59
        return $new;
60
    }
61
62
    public function withBlacklist(string ...$requestClasses) : self
63
    {
64
        $new = clone $this;
65
        $new->blacklist = self::add($requestClasses, $new->blacklist);
66
67
        return $new;
68
    }
69
70
    public function process(Request $request, Handler $handler) : Response
71
    {
72
        $requestClass = \get_class($request);
73
74
        if (isset($this->blacklist[$requestClass])) {
75
            throw RequestForbidden::fromClass($requestClass);
76
        }
77
78
        if ([] !== $this->whitelist && !isset($this->whitelist[$requestClass])) {
79
            throw RequestForbidden::fromClass($requestClass);
80
        }
81
82
        return $handler->handle($request);
83
    }
84
85
    private static function add(array $requestClasses, array $list = []) : array
86
    {
87
        foreach ($requestClasses as $requestClass) {
88
            if (!\is_subclass_of($requestClass, Request::class)) {
89
                throw new \TypeError(\sprintf('Class "%s" should implement %s.', $requestClass, Request::class));
90
            }
91
            $list[$requestClass] = true;
92
        }
93
94
        return $list;
95
    }
96
}
97