Failed Conditions
Push — ipv6 ( 5a0e63...57156c )
by Richard
19:48 queued 11:25
created

PageBan::splitCidrRange()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
dl 0
loc 13
rs 10
c 1
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 * ACC Development Team. Please see team.json for a list of contributors.     *
5
 *                                                                            *
6
 * This is free and unencumbered software released into the public domain.    *
7
 * Please see LICENSE.md for the full licencing statement.                    *
8
 ******************************************************************************/
9
10
namespace Waca\Pages;
11
12
use Exception;
13
use SmartyException;
14
use Waca\DataObjects\Ban;
15
use Waca\DataObjects\Domain;
16
use Waca\DataObjects\Request;
17
use Waca\DataObjects\RequestQueue;
18
use Waca\DataObjects\User;
19
use Waca\Exceptions\AccessDeniedException;
20
use Waca\Exceptions\ApplicationLogicException;
21
use Waca\Helpers\BanHelper;
0 ignored issues
show
Bug introduced by
The type Waca\Helpers\BanHelper 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...
22
use Waca\Helpers\Logger;
23
use Waca\Helpers\SearchHelpers\UserSearchHelper;
24
use Waca\SessionAlert;
25
use Waca\Tasks\InternalPageBase;
26
use Waca\WebRequest;
27
28
class PageBan extends InternalPageBase
29
{
30
    /**
31
     * Main function for this page, when no specific actions are called.
32
     */
33
    protected function main(): void
34
    {
35
        $this->assignCSRFToken();
36
        $this->setHtmlTitle('Bans');
37
38
        $database = $this->getDatabase();
39
        $currentDomain = Domain::getCurrent($database);
40
        $bans = Ban::getActiveBans($database, $currentDomain->getId());
41
42
        $this->setupBanList($bans);
43
44
        $this->assign('isFiltered', false);
45
        $this->setTemplate('bans/main.tpl');
46
    }
47
48
    protected function show(): void
49
    {
50
        $this->assignCSRFToken();
51
        $this->setHtmlTitle('Bans');
52
53
        $rawIdList = WebRequest::getString('id');
54
        if ($rawIdList === null) {
55
            $this->redirect('bans');
56
57
            return;
58
        }
59
60
        $idList = explode(',', $rawIdList);
61
62
        $database = $this->getDatabase();
63
        $currentDomain = Domain::getCurrent($database);
64
        $bans = Ban::getByIdList($idList, $database, $currentDomain->getId());
65
66
        $this->setupBanList($bans);
67
        $this->assign('isFiltered', true);
68
        $this->setTemplate('bans/main.tpl');
69
    }
70
71
    /**
72
     * Entry point for the ban set action
73
     * @throws SmartyException
74
     * @throws Exception
75
     */
76
    protected function set(): void
77
    {
78
        $this->setHtmlTitle('Bans');
79
80
        // dual-mode action
81
        if (WebRequest::wasPosted()) {
82
            try {
83
                $this->handlePostMethodForSetBan();
84
            }
85
            catch (ApplicationLogicException $ex) {
86
                SessionAlert::error($ex->getMessage());
87
                $this->redirect("bans", "set");
88
            }
89
        }
90
        else {
91
            $this->handleGetMethodForSetBan();
92
93
            $user = User::getCurrent($this->getDatabase());
94
            $banType = WebRequest::getString('type');
95
            $banRequest = WebRequest::getInt('request');
96
97
            // if the parameters are null, skip loading a request.
98
            if ($banType !== null && $banRequest !== null && $banRequest !== 0) {
99
                $this->preloadFormForRequest($banRequest, $banType, $user);
100
            }
101
        }
102
    }
103
104
    protected function replace(): void
105
    {
106
        $this->setHtmlTitle('Bans');
107
108
        $database = $this->getDatabase();
109
        $domain = Domain::getCurrent($database);
110
111
        // dual-mode action
112
        if (WebRequest::wasPosted()) {
113
            try {
114
                $originalBanId = WebRequest::postInt('replaceBanId');
115
                $originalBanUpdateVersion = WebRequest::postInt('replaceBanUpdateVersion');
116
117
                $originalBan = Ban::getActiveId($originalBanId, $database, $domain->getId());
118
119
                if ($originalBan === false) {
120
                    throw new ApplicationLogicException("The specified ban is not currently active, or doesn't exist.");
121
                }
122
123
                // Discard original ban; we're replacing it.
124
                $originalBan->setUpdateVersion($originalBanUpdateVersion);
125
                $originalBan->setActive(false);
126
                $originalBan->save();
127
128
                Logger::banReplaced($database, $originalBan);
129
130
                // Proceed as normal to save the new ban.
131
                $this->handlePostMethodForSetBan();
132
            }
133
            catch (ApplicationLogicException $ex) {
134
                $database->rollback();
135
                SessionAlert::error($ex->getMessage());
136
                $this->redirect("bans", "set");
137
            }
138
        }
139
        else {
140
            $this->handleGetMethodForSetBan();
141
142
            $user = User::getCurrent($database);
143
            $originalBanId = WebRequest::getString('id');
144
145
            $originalBan = Ban::getActiveId($originalBanId, $database, $domain->getId());
146
147
            if ($originalBan === false) {
148
                throw new ApplicationLogicException("The specified ban is not currently active, or doesn't exist.");
149
            }
150
151
            if ($originalBan->getName() !== null) {
152
                if (!$this->barrierTest('name', $user, 'BanType')) {
153
                    SessionAlert::error("You are not allowed to set this type of ban.");
154
                    $this->redirect("bans", "set");
155
                    return;
156
                }
157
158
                $this->assign('banName', $originalBan->getName());
159
            }
160
161
            if ($originalBan->getEmail() !== null) {
162
                if (!$this->barrierTest('email', $user, 'BanType')) {
163
                    SessionAlert::error("You are not allowed to set this type of ban.");
164
                    $this->redirect("bans", "set");
165
                    return;
166
                }
167
168
                $this->assign('banEmail', $originalBan->getEmail());
169
            }
170
171
            if ($originalBan->getUseragent() !== null) {
172
                if (!$this->barrierTest('useragent', $user, 'BanType')) {
173
                    SessionAlert::error("You are not allowed to set this type of ban.");
174
                    $this->redirect("bans", "set");
175
                    return;
176
                }
177
178
                $this->assign('banUseragent', $originalBan->getUseragent());
179
            }
180
181
            if ($originalBan->getIp() !== null) {
182
                if (!$this->barrierTest('ip', $user, 'BanType')) {
183
                    SessionAlert::error("You are not allowed to set this type of ban.");
184
                    $this->redirect("bans", "set");
185
                    return;
186
                }
187
188
                $this->assign('banIP', $originalBan->getIp() . '/' . $originalBan->getIpMask());
189
            }
190
191
            $banIsGlobal = $originalBan->getDomain() === null;
192
            if ($banIsGlobal) {
193
                if (!$this->barrierTest('global', $user, 'BanType')) {
194
                    SessionAlert::error("You are not allowed to set this type of ban.");
195
                    $this->redirect("bans", "set");
196
                    return;
197
                }
198
            }
199
200
            if (!$this->barrierTest($originalBan->getVisibility(), $user, 'BanVisibility')) {
201
                SessionAlert::error("You are not allowed to set this type of ban.");
202
                $this->redirect("bans", "set");
203
                return;
204
            }
205
206
            $this->assign('banGlobal', $banIsGlobal);
207
            $this->assign('banVisibility', $originalBan->getVisibility());
208
209
            if ($originalBan->getDuration() !== null) {
210
                $this->assign('banDuration', date('c', $originalBan->getDuration()));
211
            }
212
213
            $this->assign('banReason', $originalBan->getReason());
214
            $this->assign('banAction', $originalBan->getAction());
215
            $this->assign('banQueue', $originalBan->getTargetQueue());
216
217
            $this->assign('replaceBanId', $originalBan->getId());
218
            $this->assign('replaceBanUpdateVersion', $originalBan->getUpdateVersion());
219
        }
220
    }
221
222
    /**
223
     * Entry point for the ban remove action
224
     *
225
     * @throws AccessDeniedException
226
     * @throws ApplicationLogicException
227
     * @throws SmartyException
228
     */
229
    protected function remove(): void
230
    {
231
        $this->setHtmlTitle('Bans');
232
233
        $ban = $this->getBanForUnban();
234
235
        $banHelper = new BanHelper($this->getDatabase(), $this->getXffTrustProvider(), $this->getSecurityManager());
236
        if (!$banHelper->canUnban($ban)) {
237
            // triggered when a user tries to unban a ban they can't see the entirety of.
238
            // there's no UI way to get to this, so a raw exception is fine.
239
            throw new AccessDeniedException($this->getSecurityManager(), $this->getDomainAccessManager());
240
        }
241
242
        // dual mode
243
        if (WebRequest::wasPosted()) {
244
            $this->validateCSRFToken();
245
            $unbanReason = WebRequest::postString('unbanreason');
246
247
            if ($unbanReason === null || trim($unbanReason) === "") {
248
                SessionAlert::error('No unban reason specified');
249
                $this->redirect("bans", "remove", array('id' => $ban->getId()));
250
            }
251
252
            // set optimistic locking from delete form page load
253
            $updateVersion = WebRequest::postInt('updateversion');
254
            $ban->setUpdateVersion($updateVersion);
255
256
            $database = $this->getDatabase();
257
            $ban->setActive(false);
258
            $ban->save();
259
260
            Logger::unbanned($database, $ban, $unbanReason);
261
262
            SessionAlert::quick('Disabled ban.');
263
            $this->getNotificationHelper()->unbanned($ban, $unbanReason);
264
265
            $this->redirect('bans');
266
        }
267
        else {
268
            $this->assignCSRFToken();
269
            $this->assign('ban', $ban);
270
            $this->setTemplate('bans/unban.tpl');
271
        }
272
    }
273
274
    /**
275
     * Retrieves the requested ban duration from the WebRequest
276
     *
277
     * @throws ApplicationLogicException
278
     */
279
    private function getBanDuration(): ?int
280
    {
281
        $duration = WebRequest::postString('duration');
282
        if ($duration === "other") {
283
            $duration = strtotime(WebRequest::postString('otherduration'));
0 ignored issues
show
Bug introduced by
It seems like Waca\WebRequest::postString('otherduration') can also be of type null; however, parameter $datetime of strtotime() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

283
            $duration = strtotime(/** @scrutinizer ignore-type */ WebRequest::postString('otherduration'));
Loading history...
284
285
            if (!$duration) {
286
                throw new ApplicationLogicException('Invalid ban time');
287
            }
288
            elseif (time() > $duration) {
289
                throw new ApplicationLogicException('Ban time has already expired!');
290
            }
291
292
            return $duration;
293
        }
294
        elseif ($duration === "-1") {
295
            return null;
296
        }
297
        else {
298
            return WebRequest::postInt('duration') + time();
299
        }
300
    }
301
302
    /**
303
     * Handles the POST method on the set action
304
     *
305
     * @throws ApplicationLogicException
306
     * @throws Exception
307
     */
308
    private function handlePostMethodForSetBan()
309
    {
310
        $this->validateCSRFToken();
311
        $database = $this->getDatabase();
312
        $user = User::getCurrent($database);
313
        $currentDomain = Domain::getCurrent($database);
314
315
        // Checks whether there is a reason entered for ban.
316
        $reason = WebRequest::postString('banreason');
317
        if ($reason === null || trim($reason) === "") {
318
            throw new ApplicationLogicException('You must specify a ban reason');
319
        }
320
321
        // ban targets
322
        list($targetName, $targetIp, $targetEmail, $targetUseragent) = $this->getRawBanTargets($user);
323
324
        $visibility = $this->getBanVisibility();
325
326
        // Validate ban duration
327
        $duration = $this->getBanDuration();
328
329
        $action = WebRequest::postString('banAction') ?? Ban::ACTION_NONE;
330
331
        $global = WebRequest::postBoolean('banGlobal');
332
        if (!$this->barrierTest('global', $user, 'BanType')) {
333
            $global = false;
334
        }
335
336
        if ($action === Ban::ACTION_DEFER && $global) {
337
            throw new ApplicationLogicException("Cannot set a global ban in defer-to-queue mode.");
338
        }
339
340
        // handle CIDR ranges
341
        $targetMask = null;
342
        if ($targetIp !== null) {
343
            list($targetIp, $targetMask) = $this->splitCidrRange($targetIp);
344
            $this->validateIpBan($targetIp, $targetMask, $user, $action);
345
        }
346
347
        $banHelper = new BanHelper($this->getDatabase(), $this->getXffTrustProvider(), $this->getSecurityManager());
348
349
        $bansByTarget = $banHelper->getBansByTarget(
350
            $targetName,
351
            $targetEmail,
352
            $targetIp,
353
            $targetMask,
354
            $targetUseragent,
355
            $currentDomain->getId());
356
357
        if (count($bansByTarget) > 0) {
358
            throw new ApplicationLogicException('This target is already banned!');
359
        }
360
361
        $ban = new Ban();
362
        $ban->setDatabase($database);
363
        $ban->setActive(true);
364
365
        $ban->setName($targetName);
366
        $ban->setIp($targetIp, $targetMask);
367
        $ban->setEmail($targetEmail);
368
        $ban->setUseragent($targetUseragent);
369
370
        $ban->setUser($user->getId());
371
        $ban->setReason($reason);
372
        $ban->setDuration($duration);
373
        $ban->setVisibility($visibility);
374
375
        $ban->setDomain($global ? null : $currentDomain->getId());
376
377
        $ban->setAction($action);
378
        if ($ban->getAction() === Ban::ACTION_DEFER) {
379
            //FIXME: domains
380
            $queue = RequestQueue::getByApiName($database, WebRequest::postString('banActionTarget'), 1);
0 ignored issues
show
Bug introduced by
It seems like Waca\WebRequest::postString('banActionTarget') can also be of type null; however, parameter $apiName of Waca\DataObjects\RequestQueue::getByApiName() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

380
            $queue = RequestQueue::getByApiName($database, /** @scrutinizer ignore-type */ WebRequest::postString('banActionTarget'), 1);
Loading history...
381
            if ($queue === false) {
382
                throw new ApplicationLogicException("Unknown target queue");
383
            }
384
385
            if (!$queue->isEnabled()) {
386
                throw new ApplicationLogicException("Target queue is not enabled");
387
            }
388
389
            $ban->setTargetQueue($queue->getId());
390
        }
391
392
        $ban->save();
393
394
        Logger::banned($database, $ban, $reason);
395
396
        $this->getNotificationHelper()->banned($ban);
397
        SessionAlert::quick('Ban has been set.');
398
399
        $this->redirect('bans');
400
    }
401
402
    /**
403
     * Handles the GET method on the set action
404
     * @throws Exception
405
     */
406
    private function handleGetMethodForSetBan()
407
    {
408
        $this->setTemplate('bans/banform.tpl');
409
        $this->assignCSRFToken();
410
411
        $this->assign('maxIpRange', $this->getSiteConfiguration()->getBanMaxIpRange());
412
        $this->assign('maxIpBlockRange', $this->getSiteConfiguration()->getBanMaxIpBlockRange());
413
414
        $this->assign('banVisibility', 'user');
415
        $this->assign('banGlobal', false);
416
        $this->assign('banQueue', false);
417
        $this->assign('banAction', Ban::ACTION_BLOCK);
418
        $this->assign('banDuration', '');
419
        $this->assign('banReason', '');
420
421
        $this->assign('banEmail', '');
422
        $this->assign('banIP', '');
423
        $this->assign('banName', '');
424
        $this->assign('banUseragent', '');
425
426
        $this->assign('replaceBanId', null);
427
428
429
430
        $database = $this->getDatabase();
431
432
        $user = User::getCurrent($database);
433
        $this->setupSecurity($user);
434
435
        $queues = RequestQueue::getEnabledQueues($database);
436
437
        $this->assign('requestQueues', $queues);
438
    }
439
440
    /**
441
     * Finds the Ban object referenced in the WebRequest if it is valid
442
     *
443
     * @return Ban
444
     * @throws ApplicationLogicException
445
     */
446
    private function getBanForUnban(): Ban
447
    {
448
        $banId = WebRequest::getInt('id');
449
        if ($banId === null || $banId === 0) {
450
            throw new ApplicationLogicException("The ban ID appears to be missing. This is probably a bug.");
451
        }
452
453
        $database = $this->getDatabase();
454
        $this->setupSecurity(User::getCurrent($database));
455
        $currentDomain = Domain::getCurrent($database);
456
        $ban = Ban::getActiveId($banId, $database, $currentDomain->getId());
457
458
        if ($ban === false) {
459
            throw new ApplicationLogicException("The specified ban is not currently active, or doesn't exist.");
460
        }
461
462
        return $ban;
463
    }
464
465
    /**
466
     * Sets up Smarty variables for access control
467
     */
468
    private function setupSecurity(User $user): void
469
    {
470
        $this->assign('canSeeIpBan', $this->barrierTest('ip', $user, 'BanType'));
471
        $this->assign('canSeeNameBan', $this->barrierTest('name', $user, 'BanType'));
472
        $this->assign('canSeeEmailBan', $this->barrierTest('email', $user, 'BanType'));
473
        $this->assign('canSeeUseragentBan', $this->barrierTest('useragent', $user, 'BanType'));
474
475
        $this->assign('canGlobalBan', $this->barrierTest('global', $user, 'BanType'));
476
477
        $this->assign('canSeeUserVisibility', $this->barrierTest('user', $user, 'BanVisibility'));
478
        $this->assign('canSeeAdminVisibility', $this->barrierTest('admin', $user, 'BanVisibility'));
479
        $this->assign('canSeeCheckuserVisibility', $this->barrierTest('checkuser', $user, 'BanVisibility'));
480
    }
481
482
    /**
483
     * Validates that the provided IP is acceptable for a ban of this type
484
     *
485
     * @param string $targetIp   IP address
486
     * @param int    $targetMask CIDR prefix length
487
     * @param User   $user       User performing the ban
488
     * @param string $action     Ban action to take
489
     *
490
     * @throws ApplicationLogicException
491
     */
492
    private function validateIpBan(string $targetIp, int $targetMask, User $user, string $action): void
493
    {
494
        // validate this is an IP
495
        if (!filter_var($targetIp, FILTER_VALIDATE_IP)) {
496
            throw new ApplicationLogicException("Not a valid IP address");
497
        }
498
499
        $canLargeIpBan = $this->barrierTest('ip-largerange', $user, 'BanType');
500
        $maxIpBlockRange = $this->getSiteConfiguration()->getBanMaxIpBlockRange();
501
        $maxIpRange = $this->getSiteConfiguration()->getBanMaxIpRange();
502
503
        // validate CIDR ranges
504
        if (filter_var($targetIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
505
            if ($targetMask < 0 || $targetMask > 128) {
506
                throw new ApplicationLogicException("CIDR mask out of range for IPv6");
507
            }
508
509
            // prevent setting the ban if:
510
            //  * the user isn't allowed to set large bans, AND
511
            //  * the ban is a drop or a block (preventing human review of the request), AND
512
            //  * the mask is too wide-reaching
513
            if (!$canLargeIpBan && ($action == Ban::ACTION_BLOCK || $action == Ban::ACTION_DROP) && $targetMask < $maxIpBlockRange[6]) {
514
                throw new ApplicationLogicException("The requested IP range for this ban is too wide for the block/drop action.");
515
            }
516
517
            if (!$canLargeIpBan && $targetMask < $maxIpRange[6]) {
518
                throw new ApplicationLogicException("The requested IP range for this ban is too wide.");
519
            }
520
        }
521
522
        if (filter_var($targetIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
523
            if ($targetMask < 0 || $targetMask > 32) {
524
                throw new ApplicationLogicException("CIDR mask out of range for IPv4");
525
            }
526
527
            if (!$canLargeIpBan && ($action == Ban::ACTION_BLOCK || $action == Ban::ACTION_DROP) && $targetMask < $maxIpBlockRange[4]) {
528
                throw new ApplicationLogicException("The IP range for this ban is too wide for the block/drop action.");
529
            }
530
531
            if (!$canLargeIpBan && $targetMask < $maxIpRange[4]) {
532
                throw new ApplicationLogicException("The requested IP range for this ban is too wide.");
533
            }
534
        }
535
536
        $squidIpList = $this->getSiteConfiguration()->getSquidList();
537
        if (in_array($targetIp, $squidIpList)) {
538
            throw new ApplicationLogicException("This IP address is on the protected list of proxies, and cannot be banned.");
539
        }
540
    }
541
542
    /**
543
     * Configures a ban list template for display
544
     *
545
     * @param Ban[] $bans
546
     */
547
    private function setupBanList(array $bans): void
548
    {
549
        $userIds = array_map(fn(Ban $entry) => $entry->getUser(), $bans);
550
        $userList = UserSearchHelper::get($this->getDatabase())->inIds($userIds)->fetchMap('username');
551
552
        $domainIds = array_filter(array_unique(array_map(fn(Ban $entry) => $entry->getDomain(), $bans)));
553
        $domains = [];
554
        foreach ($domainIds as $d) {
555
            if ($d === null) {
556
                continue;
557
            }
558
            $domains[$d] = Domain::getById($d, $this->getDatabase());
559
        }
560
561
        $this->assign('domains', $domains);
562
563
        $user = User::getCurrent($this->getDatabase());
564
        $this->assign('canSet', $this->barrierTest('set', $user));
565
        $this->assign('canRemove', $this->barrierTest('remove', $user));
566
567
        $this->setupSecurity($user);
568
569
        $this->assign('usernames', $userList);
570
        $this->assign('activebans', $bans);
571
572
        $banHelper = new BanHelper($this->getDatabase(), $this->getXffTrustProvider(), $this->getSecurityManager());
573
        $this->assign('banHelper', $banHelper);
574
    }
575
576
    /**
577
     * Converts a plain IP or CIDR mask into an IP and a CIDR suffix
578
     *
579
     * @param string $targetIp IP or CIDR range
580
     *
581
     * @return array
582
     */
583
    private function splitCidrRange(string $targetIp): array
584
    {
585
        if (strpos($targetIp, '/') !== false) {
586
            $ipParts = explode('/', $targetIp, 2);
587
            $targetIp = $ipParts[0];
588
            $targetMask = (int)$ipParts[1];
589
        }
590
        else {
591
            // Default the CIDR range based on the IP type
592
            $targetMask = filter_var($targetIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? 128 : 32;
593
        }
594
595
        return array($targetIp, $targetMask);
596
}
597
598
    /**
599
     * Returns the validated ban visibility from WebRequest
600
     *
601
     * @throws ApplicationLogicException
602
     */
603
    private function getBanVisibility(): string
604
    {
605
        $visibility = WebRequest::postString('banVisibility');
606
        if ($visibility !== 'user' && $visibility !== 'admin' && $visibility !== 'checkuser') {
607
            throw new ApplicationLogicException('Invalid ban visibility');
608
        }
609
610
        return $visibility;
611
    }
612
613
    /**
614
     * Returns array of [username, ip, email, ua] as ban targets from WebRequest,
615
     * filtered for whether the user is allowed to set bans including those types.
616
     *
617
     * @return string[]
618
     * @throws ApplicationLogicException
619
     */
620
    private function getRawBanTargets(User $user): array
621
    {
622
        $targetName = WebRequest::postString('banName');
623
        $targetIp = WebRequest::postString('banIP');
624
        $targetEmail = WebRequest::postString('banEmail');
625
        $targetUseragent = WebRequest::postString('banUseragent');
626
627
        // check the user is allowed to use provided targets
628
        if (!$this->barrierTest('name', $user, 'BanType')) {
629
            $targetName = null;
630
        }
631
        if (!$this->barrierTest('ip', $user, 'BanType')) {
632
            $targetIp = null;
633
        }
634
        if (!$this->barrierTest('email', $user, 'BanType')) {
635
            $targetEmail = null;
636
        }
637
        if (!$this->barrierTest('useragent', $user, 'BanType')) {
638
            $targetUseragent = null;
639
        }
640
641
        // Checks whether there is a target entered to ban.
642
        if ($targetName === null && $targetIp === null && $targetEmail === null && $targetUseragent === null) {
643
            throw new ApplicationLogicException('You must specify a target to be banned');
644
        }
645
646
        return array($targetName, $targetIp, $targetEmail, $targetUseragent);
647
    }
648
649
    private function preloadFormForRequest(int $banRequest, string $banType, User $user): void
650
    {
651
        $database = $this->getDatabase();
652
653
        // Attempt to resolve the correct target
654
        /** @var Request|false $request */
655
        $request = Request::getById($banRequest, $database);
656
        if ($request === false) {
0 ignored issues
show
introduced by
The condition $request === false is always false.
Loading history...
657
            $this->assign('bantarget', '');
658
659
            return;
660
        }
661
662
        switch ($banType) {
663
            case 'EMail':
664
                if ($this->barrierTest('email', $user, 'BanType')) {
665
                    $this->assign('banEmail', $request->getEmail());
666
                }
667
                break;
668
            case 'IP':
669
                if ($this->barrierTest('ip', $user, 'BanType')) {
670
                    $trustedIp = $this->getXffTrustProvider()->getTrustedClientIp(
671
                        $request->getIp(),
672
                        $request->getForwardedIp());
673
674
                    $this->assign('banIP', $trustedIp);
675
                }
676
                break;
677
            case 'Name':
678
                if ($this->barrierTest('name', $user, 'BanType')) {
679
                    $this->assign('banName', $request->getName());
680
                }
681
                break;
682
            case 'UA':
683
                if ($this->barrierTest('useragent', $user, 'BanType')) {
684
                    $this->assign('banUseragent', $request->getEmail());
685
                }
686
                break;
687
        }
688
    }
689
}
690