Failed Conditions
Push — rbac ( be68b4...52c28b )
by Michael
03:11
created

PageBan::validateEmailBanTarget()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
cc 2
nc 2
nop 1
crap 6
1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca\Pages;
10
11
use Exception;
12
use Waca\DataObjects\Ban;
13
use Waca\DataObjects\Request;
14
use Waca\DataObjects\User;
15
use Waca\Exceptions\ApplicationLogicException;
16
use Waca\Helpers\Logger;
17
use Waca\Helpers\SearchHelpers\UserSearchHelper;
18
use Waca\SessionAlert;
19
use Waca\Tasks\InternalPageBase;
20
use Waca\WebRequest;
21
22
class PageBan extends InternalPageBase
23
{
24
    /**
25
     * Main function for this page, when no specific actions are called.
26
     */
27
    protected function main()
28
    {
29
        $this->assignCSRFToken();
30
31
        $this->setHtmlTitle('Bans');
32
33
        $bans = Ban::getActiveBans(null, $this->getDatabase());
34
35
        $userIds = array_map(
36
            function(Ban $entry) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
37
                return $entry->getUser();
38
            },
39
            $bans);
40
        $userList = UserSearchHelper::get($this->getDatabase())->inIds($userIds)->fetchMap('username');
41
42
        $user = User::getCurrent($this->getDatabase());
43
        $this->assign('canSet', $this->barrierTest('set', $user));
44
        $this->assign('canRemove', $this->barrierTest('remove', $user));
45
46
        $this->assign('usernames', $userList);
47
        $this->assign('activebans', $bans);
48
        $this->setTemplate('bans/banlist.tpl');
49
    }
0 ignored issues
show
Coding Style introduced by
Expected //end main()
Loading history...
50
51
    /**
52
     * Entry point for the ban set action
53
     */
54
    protected function set()
55
    {
56
        $this->setHtmlTitle('Bans');
57
58
        // dual-mode action
59
        if (WebRequest::wasPosted()) {
60
            try {
61
                $this->handlePostMethodForSetBan();
62
            }
63
            catch (ApplicationLogicException $ex) {
64
                SessionAlert::error($ex->getMessage());
65
                $this->redirect("bans", "set");
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal bans does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal set does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
66
            }
67
        }
68
        else {
69
            $this->handleGetMethodForSetBan();
70
        }
71
    }
0 ignored issues
show
Coding Style introduced by
Expected //end set()
Loading history...
72
73
    /**
74
     * Entry point for the ban remove action
75
     */
76
    protected function remove()
77
    {
78
        $this->setHtmlTitle('Bans');
79
80
        $ban = $this->getBanForUnban();
81
82
        // dual mode
83
        if (WebRequest::wasPosted()) {
84
            $this->validateCSRFToken();
85
            $unbanReason = WebRequest::postString('unbanreason');
86
87
            if ($unbanReason === null || trim($unbanReason) === "") {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
88
                SessionAlert::error('No unban reason specified');
89
                $this->redirect("bans", "remove", array('id' => $ban->getId()));
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal bans does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal remove does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
90
            }
91
92
            // set optimistic locking from delete form page load
93
            $updateVersion = WebRequest::postInt('updateversion');
94
            $ban->setUpdateVersion($updateVersion);
95
96
            $database = $this->getDatabase();
97
            $ban->setActive(false);
98
            $ban->save();
99
100
            Logger::unbanned($database, $ban, $unbanReason);
101
102
            SessionAlert::quick('Disabled ban.');
103
            $this->getNotificationHelper()->unbanned($ban, $unbanReason);
104
105
            $this->redirect('bans');
106
        }
107
        else {
108
            $this->assignCSRFToken();
109
            $this->assign('ban', $ban);
110
            $this->setTemplate('bans/unban.tpl');
111
        }
112
    }
0 ignored issues
show
Coding Style introduced by
Expected //end remove()
Loading history...
113
114
    /**
115
     * @throws ApplicationLogicException
116
     */
117
    private function getBanDuration()
118
    {
119
        $duration = WebRequest::postString('duration');
120
        if ($duration === "other") {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal other does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
121
            $duration = strtotime(WebRequest::postString('otherduration'));
122
123
            if (!$duration) {
124
                throw new ApplicationLogicException('Invalid ban time');
125
            }
126
            elseif (time() > $duration) {
127
                throw new ApplicationLogicException('Ban time has already expired!');
128
            }
129
130
            return $duration;
131
        }
132
        elseif ($duration === "-1") {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal -1 does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
133
            $duration = -1;
134
135
            return $duration;
136
        }
137
        else {
138
            $duration = WebRequest::postInt('duration') + time();
139
140
            return $duration;
141
        }
142
    }
0 ignored issues
show
Coding Style introduced by
Expected //end getBanDuration()
Loading history...
143
144
    /**
145
     * @param string $type
146
     * @param string $target
147
     *
148
     * @throws ApplicationLogicException
149
     */
150
    private function validateBanType($type, $target)
151
    {
152
        switch ($type) {
153
            case 'IP':
154
                $this->validateIpBan($target);
155
156
                return;
157
            case 'Name':
158
                // No validation needed here.
159
                return;
160
            case 'EMail':
161
                $this->validateEmailBanTarget($target);
162
163
                return;
164
            default:
165
                throw new ApplicationLogicException("Unknown ban type");
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal Unknown ban type does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
166
        }
167
    }
0 ignored issues
show
Coding Style introduced by
Expected //end validateBanType()
Loading history...
168
169
    /**
170
     * Handles the POST method on the set action
171
     *
172
     * @throws ApplicationLogicException
173
     * @throws Exception
174
     */
0 ignored issues
show
Coding Style introduced by
Expected 1 @throws tag(s) in function comment; 2 found
Loading history...
175
    private function handlePostMethodForSetBan()
176
    {
177
        $this->validateCSRFToken();
178
        $reason = WebRequest::postString('banreason');
179
        $target = WebRequest::postString('target');
180
181
        // Checks whether there is a reason entered for ban.
182
        if ($reason === null || trim($reason) === "") {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
183
            throw new ApplicationLogicException('You must specify a ban reason');
184
        }
185
186
        // Checks whether there is a target entered to ban.
187
        if ($target === null || trim($target) === "") {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
188
            throw new ApplicationLogicException('You must specify a target to be banned');
189
        }
190
191
        // Validate ban duration
192
        $duration = $this->getBanDuration();
193
194
        // Validate ban type & target for that type
195
        $type = WebRequest::postString('type');
196
        $this->validateBanType($type, $target);
197
198
        $database = $this->getDatabase();
199
200
        if (count(Ban::getActiveBans($target, $database)) > 0) {
201
            throw new ApplicationLogicException('This target is already banned!');
202
        }
203
204
        $ban = new Ban();
205
        $ban->setDatabase($database);
206
        $ban->setActive(true);
207
        $ban->setType($type);
208
        $ban->setTarget($target);
209
        $ban->setUser(User::getCurrent($database)->getId());
210
        $ban->setReason($reason);
211
        $ban->setDuration($duration);
212
213
        $ban->save();
214
215
        Logger::banned($database, $ban, $reason);
216
217
        $this->getNotificationHelper()->banned($ban);
218
        SessionAlert::quick('Ban has been set.');
219
220
        $this->redirect('bans');
221
    }
0 ignored issues
show
Coding Style introduced by
Expected //end handlePostMethodForSetBan()
Loading history...
222
223
    /**
224
     * Handles the GET method on the set action
225
     */
226
    protected function handleGetMethodForSetBan()
227
    {
228
        $this->setTemplate('bans/banform.tpl');
229
        $this->assignCSRFToken();
230
231
        $banType = WebRequest::getString('type');
232
        $banTarget = WebRequest::getInt('request');
233
234
        $database = $this->getDatabase();
235
236
        // if the parameters are null, skip loading a request.
237
        if ($banType === null
238
            || !in_array($banType, array('IP', 'Name', 'EMail'))
239
            || $banTarget === null
240
            || $banTarget === 0
241
        ) {
242
            $this->assign('bantarget', '');
243
            $this->assign('bantype', '');
244
245
            return;
246
        }
247
248
        // Set the ban type, which the user has indicated.
249
        $this->assign('bantype', $banType);
250
251
        // Attempt to resolve the correct target
252
        /** @var Request $request */
253
        $request = Request::getById($banTarget, $database);
254
        if ($request === false) {
0 ignored issues
show
introduced by
The condition $request === false is always false.
Loading history...
255
            $this->assign('bantarget', '');
256
257
            return;
258
        }
259
260
        $realTarget = '';
261
        switch ($banType) {
262
            case 'EMail':
263
                $realTarget = $request->getEmail();
264
                break;
265
            case 'IP':
266
                $xffProvider = $this->getXffTrustProvider();
267
                $realTarget = $xffProvider->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
268
                break;
269
            case 'Name':
270
                $realTarget = $request->getName();
271
                break;
272
        }
273
274
        $this->assign('bantarget', $realTarget);
275
    }
0 ignored issues
show
Coding Style introduced by
Expected //end handleGetMethodForSetBan()
Loading history...
276
277
    /**
278
     * Validates an IP ban target
279
     *
280
     * @param string $target
281
     *
282
     * @throws ApplicationLogicException
283
     */
284
    private function validateIpBan($target)
285
    {
286
        $squidIpList = $this->getSiteConfiguration()->getSquidList();
287
288
        if (filter_var($target, FILTER_VALIDATE_IP) === false) {
289
            throw new ApplicationLogicException('Invalid target - IP address expected.');
290
        }
291
292
        if (in_array($target, $squidIpList)) {
293
            throw new ApplicationLogicException("This IP address is on the protected list of proxies, and cannot be banned.");
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal This IP address is on th..., and cannot be banned. does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
294
        }
295
    }
0 ignored issues
show
Coding Style introduced by
Expected //end validateIpBan()
Loading history...
296
297
    /**
298
     * Validates an email address as a ban target
299
     *
300
     * @param string $target
301
     *
302
     * @throws ApplicationLogicException
303
     */
304
    private function validateEmailBanTarget($target)
305
    {
306
        if (filter_var($target, FILTER_VALIDATE_EMAIL) !== $target) {
307
            throw new ApplicationLogicException('Invalid target - email address expected.');
308
        }
309
    }
0 ignored issues
show
Coding Style introduced by
Expected //end validateEmailBanTarget()
Loading history...
310
311
    /**
312
     * @return Ban
313
     * @throws ApplicationLogicException
314
     */
315
    private function getBanForUnban()
316
    {
317
        $banId = WebRequest::getInt('id');
318
        if ($banId === null || $banId === 0) {
319
            throw new ApplicationLogicException("The ban ID appears to be missing. This is probably a bug.");
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal The ban ID appears to be...This is probably a bug. does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
320
        }
321
322
        $ban = Ban::getActiveId($banId, $this->getDatabase());
323
324
        if ($ban === false) {
0 ignored issues
show
introduced by
The condition $ban === false is always false.
Loading history...
325
            throw new ApplicationLogicException("The specified ban is not currently active, or doesn't exist.");
326
        }
327
328
        return $ban;
329
    }
0 ignored issues
show
Coding Style introduced by
Expected //end getBanForUnban()
Loading history...
330
}
0 ignored issues
show
Coding Style introduced by
Expected //end class
Loading history...
331