From: cenarium Date: Tue, 20 Sep 2016 17:21:36 +0000 (+0200) Subject: Support multiple limits and arbitrary periods in account creation throttle X-Git-Tag: 1.31.0-rc.0~5372^2 X-Git-Url: http://git.cyclocoop.org/wiki/images/03.jpg?a=commitdiff_plain;h=380ab6271806ca93c6d2472f4753915258e0619f;p=lhc%2Fweb%2Fwiklou.git Support multiple limits and arbitrary periods in account creation throttle This adds support for multiple count-per-period limits and arbitrary period durations in the AuthManager account creation throttle in the wiki settings. The $wgAccountCreationThrottle config variable becomes an array like $wgPasswordAttemptThrottle. Bug: T146290 Change-Id: Iea182a92a1199b0ce7103ab9ae24f1c87b01985c --- diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index f0e9e83a0e..aa54629f68 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -5427,11 +5427,30 @@ $wgDeleteRevisionsLimit = 0; $wgHideUserContribLimit = 1000; /** - * Number of accounts each IP address may create, 0 to disable. + * Number of accounts each IP address may create per specified period(s). + * + * @par Example: + * @code + * $wgAccountCreationThrottle = [ + * // no more than 100 per month + * [ + * 'count' => 100, + * 'seconds' => 30*86400, + * ], + * // no more than 10 per day + * [ + * 'count' => 10, + * 'seconds' => 86400, + * ], + * ]; + * @endcode * * @warning Requires $wgMainCacheType to be enabled */ -$wgAccountCreationThrottle = 0; +$wgAccountCreationThrottle = [ [ + 'count' => 0, + 'seconds' => 86400, +] ]; /** * Edits matching these regular expressions in body text diff --git a/includes/auth/ThrottlePreAuthenticationProvider.php b/includes/auth/ThrottlePreAuthenticationProvider.php index e2123efa61..3f6a47d2d3 100644 --- a/includes/auth/ThrottlePreAuthenticationProvider.php +++ b/includes/auth/ThrottlePreAuthenticationProvider.php @@ -65,13 +65,19 @@ class ThrottlePreAuthenticationProvider extends AbstractPreAuthenticationProvide public function setConfig( Config $config ) { parent::setConfig( $config ); + $accountCreationThrottle = $this->config->get( 'AccountCreationThrottle' ); + // Handle old $wgAccountCreationThrottle format (number of attempts per 24 hours) + if ( !is_array( $accountCreationThrottle ) ) { + $accountCreationThrottle = [ [ + 'count' => $accountCreationThrottle, + 'seconds' => 86400, + ] ]; + } + // @codeCoverageIgnoreStart $this->throttleSettings += [ // @codeCoverageIgnoreEnd - 'accountCreationThrottle' => [ [ - 'count' => $this->config->get( 'AccountCreationThrottle' ), - 'seconds' => 86400, - ] ], + 'accountCreationThrottle' => $accountCreationThrottle, 'passwordAttemptThrottle' => $this->config->get( 'PasswordAttemptThrottle' ), ]; @@ -107,7 +113,9 @@ class ThrottlePreAuthenticationProvider extends AbstractPreAuthenticationProvide $result = $this->accountCreationThrottle->increase( null, $ip, __METHOD__ ); if ( $result ) { - return \StatusValue::newFatal( 'acct_creation_throttle_hit', $result['count'] ); + $message = wfMessage( 'acct_creation_throttle_hit' )->params( $result['count'] ) + ->durationParams( $result['wait'] ); + return \StatusValue::newFatal( $message ); } return \StatusValue::newGood(); diff --git a/languages/i18n/en.json b/languages/i18n/en.json index b3781c256d..614fa47c76 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -509,7 +509,7 @@ "signupend": "", "signupend-https": "", "mailerror": "Error sending mail: $1", - "acct_creation_throttle_hit": "Visitors to this wiki using your IP address have created {{PLURAL:$1|1 account|$1 accounts}} in the last day, which is the maximum allowed in this time period.\nAs a result, visitors using this IP address cannot create any more accounts at the moment.", + "acct_creation_throttle_hit": "Visitors to this wiki using your IP address have created {{PLURAL:$1|1 account|$1 accounts}} in the last $2, which is the maximum allowed in this time period.\nAs a result, visitors using this IP address cannot create any more accounts at the moment.", "emailauthenticated": "Your email address was confirmed on $2 at $3.", "emailnotauthenticated": "Your email address is not yet confirmed.\nNo email will be sent for any of the following features.", "noemailprefs": "Specify an email address in your preferences for these features to work.", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index 4ec5cec5fa..83d6d29a07 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -693,7 +693,7 @@ "signupend": "{{notranslate}}", "signupend-https": "{{notranslate}}", "mailerror": "Used as error message in sending confirmation mail to user. Parameters:\n* $1 - new mail address", - "acct_creation_throttle_hit": "Error message at [[Special:CreateAccount]].\n\n\"in the last day\" precisely means: during the lasts 86400 seconds (24 hours) ending right now.\n\nParameters:\n* $1 - number of accounts", + "acct_creation_throttle_hit": "Error message at [[Special:CreateAccount]].\n\nParameters:\n* $1 - number of accounts\n* $2 - period", "emailauthenticated": "In user preferences ([[Special:Preferences]] > {{int:prefs-personal}} > {{int:email}}) and on [[Special:ConfirmEmail]].\n\nParameters:\n* $1 - (Unused) obsolete, date and time\n* $2 - date\n* $3 - time", "emailnotauthenticated": "Message in [[Special:Preferences]] > {{int:prefs-personal}} > {{int:email}}.\n\nIt appears after saving your email address but before you confirm it.", "noemailprefs": "Message appearing in the \"Email options\" section of the \"User profile\" page in [[Special:Preferences|Preferences]], when no user email address has been entered.", diff --git a/tests/phpunit/includes/auth/ThrottlePreAuthenticationProviderTest.php b/tests/phpunit/includes/auth/ThrottlePreAuthenticationProviderTest.php index aa6f0e8dd2..20f4cbc44d 100644 --- a/tests/phpunit/includes/auth/ThrottlePreAuthenticationProviderTest.php +++ b/tests/phpunit/includes/auth/ThrottlePreAuthenticationProviderTest.php @@ -12,7 +12,10 @@ class ThrottlePreAuthenticationProviderTest extends \MediaWikiTestCase { $provider = new ThrottlePreAuthenticationProvider(); $providerPriv = \TestingAccessWrapper::newFromObject( $provider ); $config = new \HashConfig( [ - 'AccountCreationThrottle' => 123, + 'AccountCreationThrottle' => [ [ + 'count' => 123, + 'seconds' => 86400, + ] ], 'PasswordAttemptThrottle' => [ [ 'count' => 5, 'seconds' => 300, @@ -38,7 +41,10 @@ class ThrottlePreAuthenticationProviderTest extends \MediaWikiTestCase { ] ); $providerPriv = \TestingAccessWrapper::newFromObject( $provider ); $config = new \HashConfig( [ - 'AccountCreationThrottle' => 123, + 'AccountCreationThrottle' => [ [ + 'count' => 123, + 'seconds' => 86400, + ] ], 'PasswordAttemptThrottle' => [ [ 'count' => 5, 'seconds' => 300, @@ -122,18 +128,18 @@ class ThrottlePreAuthenticationProviderTest extends \MediaWikiTestCase { } $this->assertEquals( - \StatusValue::newGood(), - $provider->testForAccountCreation( $user, $creator, [] ), + true, + $provider->testForAccountCreation( $user, $creator, [] )->isOK(), 'attempt #1' ); $this->assertEquals( - \StatusValue::newGood(), - $provider->testForAccountCreation( $user, $creator, [] ), + true, + $provider->testForAccountCreation( $user, $creator, [] )->isOK(), 'attempt #2' ); $this->assertEquals( - $succeed ? \StatusValue::newGood() : \StatusValue::newFatal( 'acct_creation_throttle_hit', 2 ), - $provider->testForAccountCreation( $user, $creator, [] ), + $succeed ? true : false, + $provider->testForAccountCreation( $user, $creator, [] )->isOK(), 'attempt #3' ); }