From: Gergő Tisza Date: Mon, 28 May 2018 16:25:36 +0000 (+0000) Subject: Add maintenance script for resetting login/signup throttle X-Git-Tag: 1.34.0-rc.0~4691 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=43e4cd5b434b2202c9ba39680a27dc92ad47b78f Add maintenance script for resetting login/signup throttle Bug: T194506 Change-Id: I6dda5f516ba47a452e438946379fcb696c8c87f9 --- diff --git a/autoload.php b/autoload.php index 64c34b5a79..2ed9ff316a 100644 --- a/autoload.php +++ b/autoload.php @@ -1211,6 +1211,7 @@ $wgAutoloadLocalClasses = [ 'ReplicatedBagOStuff' => __DIR__ . '/includes/libs/objectcache/ReplicatedBagOStuff.php', 'RepoGroup' => __DIR__ . '/includes/filerepo/RepoGroup.php', 'RequestContext' => __DIR__ . '/includes/context/RequestContext.php', + 'ResetAuthenticationThrottle' => __DIR__ . '/maintenance/resetAuthenticationThrottle.php', 'ResetUserEmail' => __DIR__ . '/maintenance/resetUserEmail.php', 'ResetUserTokens' => __DIR__ . '/maintenance/resetUserTokens.php', 'ResourceFileCache' => __DIR__ . '/includes/cache/ResourceFileCache.php', diff --git a/maintenance/resetAuthenticationThrottle.php b/maintenance/resetAuthenticationThrottle.php new file mode 100644 index 0000000000..9760c42000 --- /dev/null +++ b/maintenance/resetAuthenticationThrottle.php @@ -0,0 +1,152 @@ +addDescription( 'Reset login/signup throttling for a specified user and/or IP. ' + . "\n\n" + . 'When resetting signup only, provide the IP. When resetting login (or both), provide ' + . 'both username (as entered in login screen) and IP. An easy way to obtain them is ' + . "the 'throttler' log channel." ); + $this->addOption( 'login', 'Reset login throttle' ); + $this->addOption( 'signup', 'Reset account creation throttle' ); + $this->addOption( 'user', 'Username to reset', false, true ); + $this->addOption( 'ip', 'IP to reset', false, true ); + } + + public function execute() { + $forLogin = (bool)$this->getOption( 'login' ); + $forSignup = (bool)$this->getOption( 'signup' ); + $username = $this->getOption( 'user' ); + $ip = $this->getOption( 'ip' ); + + if ( !$forLogin && !$forSignup ) { + $this->fatalError( 'At least one of --login and --signup is required!' ); + } elseif ( $forLogin && ( $ip === null || $username === null ) ) { + $this->fatalError( '--usename and --ip are both required when using --login!' ); + } elseif ( $forSignup && $ip === null ) { + $this->fatalError( '--ip is required when using --signup!' ); + } elseif ( $ip !== null && !IP::isValid( $ip ) ) { + $this->fatalError( "Not a valid IP: $ip" ); + } + + if ( $forLogin ) { + $this->clearLoginThrottle( $username, $ip ); + } + if ( $forSignup ) { + $this->clearSignupThrottle( $ip ); + } + + LoggerFactory::getInstance( 'throttler' )->notice( 'Manually cleared {type} throttle', [ + 'type' => implode( ' and ', array_filter( [ + $forLogin ? 'login' : null, + $forSignup ? 'signup' : null, + ] ) ), + 'username' => $username, + 'ipKey' => $ip, + ] ); + } + + /** + * @param string|null $rawUsername + * @param string|null $ip + */ + protected function clearLoginThrottle( $rawUsername, $ip ) { + $this->output( 'Clearing login throttle... ' ); + + $passwordAttemptThrottle = $this->getConfig()->get( 'PasswordAttemptThrottle' ); + if ( !$passwordAttemptThrottle ) { + $this->output( "none set\n" ); + return; + } + + $throttler = new Throttler( $passwordAttemptThrottle, [ + 'type' => 'password', + 'cache' => ObjectCache::getLocalClusterInstance(), + ] ); + if ( $rawUsername !== null ) { + $usernames = AuthManager::singleton()->normalizeUsername( $rawUsername ); + if ( !$usernames ) { + $this->fatalError( "Not a valid username: $rawUsername" ); + } + } else { + $usernames = [ null ]; + } + foreach ( $usernames as $username ) { + $throttler->clear( $username, $ip ); + } + + $botPasswordThrottler = new Throttler( $passwordAttemptThrottle, [ + 'type' => 'botpassword', + 'cache' => ObjectCache::getLocalClusterInstance(), + ] ); + $botPasswordThrottler->clear( $username, $ip ); + + $this->output( "done\n" ); + } + + /** + * @param string $ip + */ + protected function clearSignupThrottle( $ip ) { + $this->output( 'Clearing signup throttle... ' ); + + $accountCreationThrottle = $this->getConfig()->get( 'AccountCreationThrottle' ); + if ( !is_array( $accountCreationThrottle ) ) { + $accountCreationThrottle = [ [ + 'count' => $accountCreationThrottle, + 'seconds' => 86400, + ] ]; + } + if ( !$accountCreationThrottle ) { + $this->output( "none set\n" ); + return; + } + $throttler = new Throttler( $accountCreationThrottle, [ + 'type' => 'acctcreate', + 'cache' => ObjectCache::getLocalClusterInstance(), + ] ); + + $throttler->clear( null, $ip ); + + $this->output( "done\n" ); + } + +} + +$maintClass = ResetAuthenticationThrottle::class; +require_once RUN_MAINTENANCE_IF_MAIN;