Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
UserRateLimitConstraint
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
4 / 4
9
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 limit
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 checkConstraint
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
5
 getLegacyStatus
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21namespace MediaWiki\EditPage\Constraint;
22
23use MediaWiki\Permissions\RateLimiter;
24use MediaWiki\Permissions\RateLimitSubject;
25use StatusValue;
26
27/**
28 * Verify user doesn't exceed rate limits
29 *
30 * @since 1.36
31 * @internal
32 * @author DannyS712
33 */
34class UserRateLimitConstraint implements IEditConstraint {
35
36    private RateLimitSubject $subject;
37    private string $oldContentModel;
38    private string $newContentModel;
39    private RateLimiter $limiter;
40
41    private string $result;
42
43    public function __construct(
44        RateLimiter $limiter,
45        RateLimitSubject $subject,
46        string $oldContentModel,
47        string $newContentModel
48    ) {
49        $this->limiter = $limiter;
50        $this->subject = $subject;
51        $this->oldContentModel = $oldContentModel;
52        $this->newContentModel = $newContentModel;
53    }
54
55    private function limit( string $action, int $inc = 1 ) {
56        return $this->limiter->limit( $this->subject, $action, $inc );
57    }
58
59    public function checkConstraint(): string {
60        // Need to check for rate limits on `editcontentmodel` if it is changing
61        $contentModelChange = ( $this->newContentModel !== $this->oldContentModel );
62
63        // TODO inject and use a ThrottleStore once available, see T261744
64        // Checking if the user is rate limited increments the counts, so we cannot perform
65        // the check again when getting the status; thus, store the result
66        if ( $this->limit( 'edit' )
67            || $this->limit( 'linkpurge', 0 ) // only counted after the fact
68            || ( $contentModelChange && $this->limit( 'editcontentmodel' ) )
69        ) {
70            $this->result = self::CONSTRAINT_FAILED;
71        } else {
72            $this->result = self::CONSTRAINT_PASSED;
73        }
74
75        return $this->result;
76    }
77
78    public function getLegacyStatus(): StatusValue {
79        $statusValue = StatusValue::newGood();
80
81        if ( $this->result === self::CONSTRAINT_FAILED ) {
82            $statusValue->fatal( 'actionthrottledtext' );
83            $statusValue->value = self::AS_RATE_LIMITED;
84        }
85
86        return $statusValue;
87    }
88
89}