wgRateLimits: Add configuration option to ignore 'noratelimit' right
authorBryan Davis <bd808@wikimedia.org>
Tue, 4 Oct 2016 04:46:30 +0000 (22:46 -0600)
committerBryanDavis <bdavis@wikimedia.org>
Tue, 4 Oct 2016 05:38:10 +0000 (05:38 +0000)
It may be reasonable to ignore the 'noratelimit' right granted to a user
when perfuming some rate limit checks. As an example, a rate limit check
on failed authentication attempts should not be bypassed.

Add an optional '&can-bypass' configuration option for each
$wgRateLimits action that can be set to false to disable checking
User::isPingLimitable(). This bypasses both 'noratelimit' and
$wgRateLimitsExcludedIPs exclusions.

Depends-On: Iacdd1719d5f08eca91de0a35c0042ffee2136f34
Change-Id: Ia3add8bbbab0307f036e9b77e752c382da3a0d04

includes/DefaultSettings.php
includes/user/User.php

index b1436b0..2ae33b2 100644 (file)
@@ -5533,13 +5533,7 @@ $wgApplyIpBlocksToXff = false;
  * elapses.
  *
  * @par Example:
- * To set a generic maximum of 4 hits in 60 seconds:
- * @code
- *     $wgRateLimits = [ 4, 60 ];
- * @endcode
- *
- * @par Example:
- * You could also limit per action and then type of users.
+ * Limits per configured per action and then type of users.
  * @code
  *     $wgRateLimits = [
  *         'edit' => [
@@ -5548,8 +5542,20 @@ $wgApplyIpBlocksToXff = false;
  *             'newbie' => [ x, y ], // each new autoconfirmed accounts; overrides 'user'
  *             'ip' => [ x, y ], // each anon and recent account
  *             'subnet' => [ x, y ], // ... within a /24 subnet in IPv4 or /64 in IPv6
+ *             'groupName' => [ x, y ], // by group membership
  *         ]
- *     ]
+ *     ];
+ * @endcode
+ *
+ * @par Normally, the 'noratelimit' right allows a user to bypass any rate
+ * limit checks. This can be disabled on a per-action basis by setting the
+ * special '&can-bypass' key to false in that action's configuration.
+ * @code
+ *     $wgRateLimits = [
+ *         'some-action' => [
+ *             '&can-bypass' => false,
+ *             'user' => [ x, y ],
+ *     ];
  * @endcode
  *
  * @warning Requires that $wgMainCacheType is set to something persistent
index 6083db9..00fc9be 100644 (file)
@@ -1802,12 +1802,16 @@ class User implements IDBAccessObject {
                        return false;
                }
 
+               $limits = array_merge(
+                       [ '&can-bypass' => true ],
+                       $wgRateLimits[$action]
+               );
+
                // Some groups shouldn't trigger the ping limiter, ever
-               if ( !$this->isPingLimitable() ) {
+               if ( $limits['&can-bypass'] && !$this->isPingLimitable() ) {
                        return false;
                }
 
-               $limits = $wgRateLimits[$action];
                $keys = [];
                $id = $this->getId();
                $userLimit = false;