Passed
Push — 2.x ( d40732...596a61 )
by Terry
01:44
created

Firewall::setChannel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the Shieldon package.
4
 *
5
 * (c) Terry L. <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * php version 7.1.0
11
 *
12
 * @category  Web-security
13
 * @package   Shieldon
14
 * @author    Terry Lin <[email protected]>
15
 * @copyright 2019 terrylinooo
16
 * @license   https://github.com/terrylinooo/shieldon/blob/2.x/LICENSE MIT
17
 * @link      https://github.com/terrylinooo/shieldon
18
 * @see       https://shieldon.io
19
 */
20
21
declare(strict_types=1);
22
23
namespace Shieldon\Firewall;
24
25
use Psr\Http\Message\ServerRequestInterface;
26
use Psr\Http\Message\ResponseInterface;
27
use Psr\Http\Server\MiddlewareInterface;
28
use Shieldon\Firewall\Kernel;
29
use Shieldon\Firewall\Utils\Container;
30
use Shieldon\Firewall\FirewallTrait;
31
use Shieldon\Firewall\Firewall\MainTrait;
32
use Shieldon\Firewall\Firewall\Messenger\MessengerTrait;
33
use Shieldon\Firewall\Firewall\XssProtectionTrait;
34
use Shieldon\Psr15\RequestHandler;
35
use function Shieldon\Firewall\get_request;
36
use function defined;
37
use function file_exists;
38
use function file_get_contents;
39
use function json_decode;
40
use function rtrim;
41
42
/**
43
 * Managed Firewall.
44
 */
45
class Firewall
46
{
47
    use FirewallTrait;
48
    use MainTrait;
1 ignored issue
show
introduced by
The trait Shieldon\Firewall\Firewall\MainTrait requires some properties which are not provided by Shieldon\Firewall\Firewall: $component, $driver
Loading history...
49
    use XssProtectionTrait;
50
    use MessengerTrait;
51
52
    /**
53
     * Collection of PSR-7 or PSR-15 middlewares.
54
     *
55
     * @var array
56
     */
57
    protected $middlewares = [];
58
59
    /**
60
     * Constructor.
61
     * 
62
     * @param ServerRequestInterface|null $request  A PSR-7 server request.
63
     * @param ResponseInterface|null      $response A PSR-7 server response.
64
     */
65
    public function __construct(?ServerRequestInterface $request = null, ?ResponseInterface $response = null)
66
    {
67
        Container::set('firewall', $this);
68
69
        $this->kernel = new Kernel($request, $response);
70
    }
71
72
    /**
73
     * Setup everything we need.
74
     *
75
     * @return void
76
     */
77
    public function setup(): void
78
    {
79
        $this->status = $this->getOption('daemon');
80
81
        $this->setDriver();
82
83
        $this->setChannel();
84
85
        $this->setFilters();
86
87
        $this->setComponents();
88
89
        $this->setIpSource();
90
91
        $this->setLogger();
92
93
        $this->setSessionLimit();
94
95
        $this->setCronJob();
96
97
        $this->setExcludedUrls();
98
99
        $this->setXssProtection();
100
101
        $this->setPageAuthentication();
102
103
        $this->setDialogUserInterface();
104
105
        $this->setMessengers();
106
107
        $this->setCaptchas();
108
109
        $this->setMessageEvents();
110
111
        $this->setDenyTooManyAttempts();
112
113
        $this->setIptablesBridgeDirectory();
114
    }
115
116
    /**
117
     * Set up the path of the configuration file.
118
     *
119
     * @param string $source The path.
120
     * @param string $type   The type.
121
     * 
122
     * @return void
123
     */
124
    public function configure(string $source, string $type = 'json'): void
125
    {
126
        if ($type === 'json') {
127
            $this->directory = rtrim($source, '\\/');
128
            $configFilePath = $this->directory . '/' . $this->filename;
129
130
            if (file_exists($configFilePath)) {
131
                $jsonString = file_get_contents($configFilePath);
132
133
            } else {
134
                $jsonString = file_get_contents(__DIR__ . '/../../config.json');
135
136
                if (defined('PHP_UNIT_TEST')) {
137
                    $jsonString = file_get_contents(__DIR__ . '/../../tests/config.json');
138
                }
139
            }
140
141
            $this->configuration = json_decode($jsonString, true);
142
            $this->kernel->managedBy('managed');
143
144
        } elseif ($type === 'php') {
145
            $this->configuration = include $source;
146
            $this->kernel->managedBy('config');
147
        }
148
149
        $this->setup();
150
    }
151
152
    /**
153
     * Just, run!
154
     *
155
     * @return ResponseInterface
156
     */
157
    public function run(): ResponseInterface
158
    {
159
        // If settings are ready, let's start monitoring requests.
160
        if ($this->status) {
161
162
            $response = get_request();
163
164
            // PSR-15 request handler.
165
            $requestHandler = new RequestHandler();
166
167
            foreach ($this->middlewares as $middleware) {
168
                $requestHandler->add($middleware);
169
            }
170
171
            $response = $requestHandler->handle($response);
172
173
            // Something is detected by Middlewares, return.
174
            if ($response->getStatusCode() !== $this->kernel::HTTP_STATUS_OK) {
175
                return $response;
176
            }
177
178
            $result = $this->kernel->run();
179
180
            if ($result !== $this->kernel::RESPONSE_ALLOW) {
181
182
                if ($this->kernel->captchaResponse()) {
183
                    $this->kernel->unban();
184
185
                    $response = $response->withHeader('Location', $this->kernel->getCurrentUrl());
186
                    $response = $response->withStatus($this->kernel::HTTP_STATUS_SEE_OTHER);
187
188
                    return $response;
189
                }
190
            }
191
        }
192
193
        return $this->kernel->respond();
194
    }
195
196
    /**
197
     * Add middlewares and use them before going into Shieldon kernal.
198
     *
199
     * @param MiddlewareInterface $middleware A PSR-15 middlewares.
200
     *
201
     * @return void
202
     */
203
    public function add(MiddlewareInterface $middleware): void
204
    {
205
        $this->middlewares[] = $middleware;
206
    }
207
208
    /**
209
     * Set the channel ID.
210
     *
211
     * @return void
212
     */
213
    protected function setChannel(): void
214
    {
215
        $channelId = $this->getOption('channel_id');
216
217
        if ($channelId) {
218
            $this->kernel->setChannel($channelId);
219
            $this->channel = $channelId;
220
        }
221
    }
222
}
223