FirewallMiddleware   A
last analyzed

Complexity

Total Complexity 39

Size/Duplication

Total Lines 322
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 104
dl 0
loc 322
ccs 0
cts 162
cp 0
rs 9.28
c 1
b 0
f 0
wmc 39

13 Methods

Rating   Name   Duplication   Size   Complexity  
A prepareResponseData() 0 18 2
A checkAcceptList() 0 10 3
A redirectIfBlocked() 0 12 3
B handle() 0 32 8
A __construct() 0 7 1
A saveLogForBlackAndAcceptList() 0 12 5
A logResponseData() 0 6 1
A setDefaultsToBlackListAndAccepted() 0 6 2
A redirectIfRejectListed() 0 13 3
A checkRejectList() 0 10 3
A logRequest() 0 19 2
A redirectIfNotWhiteListed() 0 13 3
A setValuesToWhiteListedAndRejected() 0 7 3
1
<?php
2
3
namespace Someshwer\Firewall\Middleware;
4
5
use Closure;
6
use Illuminate\Support\Facades\Log;
0 ignored issues
show
Bug introduced by
The type Illuminate\Support\Facades\Log was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Someshwer\Firewall\Lib\IPFilter;
8
use Someshwer\Firewall\src\Entities\FirewallLog;
9
10
/**
11
 * @author Someshwer<[email protected]>
12
 * Date: 11-08-2018
13
 * Time: 20:42 IST
14
 *
15
 * This class filters ip address of every incoming request before actual request is handled.
16
 * Filter in blacklist or whitelist are two configured options available.
17
 *
18
 * This also logs every incoming request to the application.
19
 * The log data is available in 'firewall_requests_log' table.
20
 *
21
 * FirewallMiddleware class
22
 */
23
class FirewallMiddleware
24
{
25
    /**
26
     * The ip addresses defined in this variable can be rejected even if they white listed.
27
     *
28
     * @var array
29
     */
30
    protected $reject;
31
32
    /**
33
     * The ip addresses defined in this variable can be acceptable even if they are blacklisted.
34
     *
35
     * @var array
36
     */
37
    protected $accept;
38
39
    /**
40
     * IPFilter class object.
41
     *
42
     * @var object
43
     */
44
    private $ip_filter;
45
46
    /**
47
     * Redirect url for black and white list.
48
     *
49
     * @var string
50
     */
51
    private $redirect_url;
52
53
    /**
54
     * Determines request to be logged or not.
55
     *
56
     * @var \Illuminate\Config\Repository|mixed
0 ignored issues
show
Bug introduced by
The type Illuminate\Config\Repository was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
57
     */
58
    private $log_request;
59
60
    /**
61
     * FirewallMiddleware constructor.
62
     *
63
     * @param IPFilter $ipFilter
64
     */
65
    public function __construct(IPFilter $ipFilter)
66
    {
67
        $this->ip_filter = $ipFilter;
68
        $this->redirect_url = config('firewall.redirect_url');
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

68
        $this->redirect_url = /** @scrutinizer ignore-call */ config('firewall.redirect_url');
Loading history...
69
        $this->accept = config('firewall.accept');
70
        $this->reject = config('firewall.reject');
71
        $this->log_request = config('firewall.firewall_log');
72
    }
73
74
    /**
75
     * This method assigns and stores the request
76
     * data into a firewall_log table.
77
     *
78
     * @param $request
79
     *
80
     * @return FirewallLog
81
     */
82
    private function logRequest($request)
83
    {
84
        $firewall_log = new FirewallLog();
85
        $firewall_log->fill([
86
            'path'             => $request->path(),
87
            'url'              => $request->url(),
88
            'full_url'         => $request->fullUrl(),
89
            'method'           => $_SERVER['REQUEST_METHOD'],
90
            'uri'              => $_SERVER['REQUEST_URI'],
91
            'query'            => $request->query() ? $request->query() : null,
92
            'file_name'        => $_SERVER['SCRIPT_FILENAME'],
93
            'http_host'        => $_SERVER['HTTP_HOST'],
94
            'http_user_agent'  => $_SERVER['HTTP_USER_AGENT'],
95
            'ip_address'       => $request->ip(),
96
            'all_request_data' => $_SERVER,
97
        ]);
98
        $firewall_log->save();
99
100
        return $firewall_log;
101
    }
102
103
    /**
104
     * Checking accept list whether it has current request ip or not.
105
     *
106
     * @param object $request
107
     *
108
     * @return bool
109
     */
110
    private function checkAcceptList($request)
111
    {
112
        $status = false;
113
        if (count($this->accept) > 0) {
114
            if (in_array($request->ip(), $this->accept)) {
115
                $status = true;
116
            }
117
        }
118
119
        return $status;
120
    }
121
122
    /**
123
     * Checking reject list whether it has current request ip or not.
124
     *
125
     * @param object $request
126
     *
127
     * @return bool
128
     */
129
    private function checkRejectList($request)
130
    {
131
        $status = false;
132
        if (count($this->reject) > 0) {
133
            if (in_array($request->ip(), $this->reject)) {
134
                $status = true;
135
            }
136
        }
137
138
        return $status;
139
    }
140
141
    /**
142
     * Set default values to black_listed and accepted attributes.
143
     *
144
     * @param $log_request
145
     */
146
    private function setDefaultsToBlackListAndAccepted($log_request)
147
    {
148
        if ($log_request) {
149
            $log_request->fill(['accepted' => false]);
150
            $log_request->fill(['black_listed' => false]);
151
            $log_request->save();
152
        }
153
    }
154
155
    /**
156
     * Set black_listed and accepted attributes and store in a table.
157
     *
158
     * @param $request
159
     * @param $log_request
160
     * @param $ip_filter
161
     */
162
    private function saveLogForBlackAndAcceptList($request, $log_request, $ip_filter)
163
    {
164
        if ($ip_filter->filterBlackList($request)) {
165
            if ($log_request) {
166
                $log_request->fill(['black_listed' => true]);
167
                $log_request->save();
168
            }
169
        }
170
        if ($this->checkAcceptList($request)) {
171
            if ($log_request) {
172
                $log_request->fill(['accepted' => true]);
173
                $log_request->save();
174
            }
175
        }
176
    }
177
178
    /**
179
     * This methods redirects to a specified url if the ip address is really blocked.
180
     *
181
     * @param $request
182
     *
183
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|null
0 ignored issues
show
Bug introduced by
The type Illuminate\Routing\Redirector was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Bug introduced by
The type Illuminate\Http\RedirectResponse was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
184
     */
185
    private function redirectIfBlocked($request)
186
    {
187
        // Checking accept list if blacklist is enabled
188
        if (!$this->checkAcceptList($request)) {
189
            // Checking request ip address is present in black list or not
190
            if ($this->ip_filter->filterBlackList($request)) {
191
                // If present redirect the request custom redirection url
192
                return redirect($this->redirect_url);
0 ignored issues
show
Bug introduced by
The function redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

192
                return /** @scrutinizer ignore-call */ redirect($this->redirect_url);
Loading history...
193
            }
194
        }
195
196
        return null;
197
    }
198
199
    /**
200
     * Set values to white_listed and rejected attributes.
201
     *
202
     * @param $request
203
     * @param $log_request
204
     */
205
    private function setValuesToWhiteListedAndRejected($request, $log_request)
206
    {
207
        if ($this->ip_filter->filterWhiteList($request)) {
208
            if ($log_request) {
209
                $log_request->fill(['white_listed' => true]);
210
                $log_request->fill(['rejected' => false]);
211
                $log_request->save();
212
            }
213
        }
214
    }
215
216
    /**
217
     * Redirecting to specified url if the ip in rejected list.
218
     *
219
     * @param $request
220
     * @param $log_request
221
     *
222
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|null
223
     */
224
    private function redirectIfRejectListed($request, $log_request)
225
    {
226
        // Checking reject list if whitelist is enabled
227
        if ($this->checkRejectList($request)) {
228
            if ($log_request) {
229
                $log_request->fill(['rejected' => true]);
230
                $log_request->save();
231
            }
232
            // If present redirect the request custom redirection url
233
            return redirect($this->redirect_url);
0 ignored issues
show
Bug introduced by
The function redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

233
            return /** @scrutinizer ignore-call */ redirect($this->redirect_url);
Loading history...
234
        }
235
236
        return null;
237
    }
238
239
    /**
240
     * Redirects to a specified url if given ip is not white listed.
241
     *
242
     * @param $request
243
     * @param $log_request
244
     *
245
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|null
246
     */
247
    private function redirectIfNotWhiteListed($request, $log_request)
248
    {
249
        // Checking request ip address is present in whitelist or not
250
        if (!$this->ip_filter->filterWhiteList($request)) {
251
            if ($log_request) {
252
                $log_request->fill(['white_listed' => false]);
253
                $log_request->save();
254
            }
255
            // If not present redirect the request custom redirection url
256
            return redirect($this->redirect_url);
0 ignored issues
show
Bug introduced by
The function redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

256
            return /** @scrutinizer ignore-call */ redirect($this->redirect_url);
Loading history...
257
        }
258
259
        return null;
260
    }
261
262
    /**
263
     * Handle an incoming request.
264
     *
265
     * @param \Illuminate\Http\Request $request
0 ignored issues
show
Bug introduced by
The type Illuminate\Http\Request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
266
     * @param \Closure                 $next
267
     *
268
     * @return mixed
269
     */
270
    public function handle($request, Closure $next)
271
    {
272
        $log_request = null;
273
        if ($this->log_request) {
274
            $log_request = $this->logRequest($request);
275
        }
276
        // Checking if blacklist enabled or not
277
        if ($this->ip_filter->getFilterType() == 'BLACKLIST') {
278
            $this->setDefaultsToBlackListAndAccepted($log_request);
279
            $this->saveLogForBlackAndAcceptList($request, $log_request, $this->ip_filter);
280
            $redirect_response = $this->redirectIfBlocked($request);
281
            if ($redirect_response) {
282
                return $redirect_response;
283
            }
284
        }
285
        // Checking if whitelist enabled or not
286
        if ($this->ip_filter->getFilterType() == 'WHITELIST') {
287
            $this->setValuesToWhiteListedAndRejected($request, $log_request);
288
            $redirect_rej_response = $this->redirectIfRejectListed($request, $log_request);
289
            $redirect_non_white_response = $this->redirectIfNotWhiteListed($request, $log_request);
290
            $redirect_response = ($redirect_rej_response) ? $redirect_rej_response :
291
                (($redirect_non_white_response) ? $redirect_non_white_response : null);
292
            if ($redirect_response) {
293
                return $redirect_response;
294
            }
295
        }
296
        $response = $next($request);
297
        // Logging response data
298
        $response_data = $this->prepareResponseData($response);
299
        $this->logResponseData($response_data, $log_request);
300
        // Proceeding further with the actual request
301
        return $response;
302
    }
303
304
    /**
305
     * Preparing response data to be stored.
306
     *
307
     * @param $response
308
     *
309
     * @return array
310
     */
311
    private function prepareResponseData($response)
312
    {
313
        try {
314
            $response_data = [
315
                'status_code' => $response->getStatusCode(),
316
                'headers'     => [
317
                    'cache_control' => $response->headers->get('cache-control'),
318
                    'content_type'  => $response->headers->get('content-type'),
319
                    'date'          => $response->headers->get('date'),
320
                ],
321
                // 'original_data'=>$response->getOriginalContent(),
322
            ];
323
        } catch (\Exception $e) {
324
            Log::error($e);
325
            $response_data = null;
326
        }
327
328
        return $response_data;
329
    }
330
331
    /**
332
     * This logs and stores the response data to firewall_requests_log table.
333
     *
334
     * @param $response
335
     * @param $firewall_log
336
     *
337
     * @return mixed
338
     */
339
    private function logResponseData($response, $firewall_log)
340
    {
341
        $firewall_log->response_data = $response;
342
        $firewall_log->save();
343
344
        return $firewall_log;
345
    }
346
}
347