ApiLogin which will currently always try an AuthManager login which will
by default throttle via ThrottlePreAuthenticationProvider, but this only
happens after the BotPassword is checked so it's still possible to keep
trying to break the bot password.
There's a potential odd-behavior mode here: if the main account username
and password looks like a BotPasswords username and password, a
successful main account login will increment the BotPasswords throttle
for the user and not reset it after the successful main account login.
That seems such an odd edge case I say let's not worry about it.
Bug: T165846
Change-Id: Ie60f0e05c2a94722b91bc3a80c80346e28b443f4
$session = $status->getValue();
$authRes = 'Success';
$loginType = 'BotPassword';
$session = $status->getValue();
$authRes = 'Success';
$loginType = 'BotPassword';
- } elseif ( !$botLoginData[2] ) {
+ } elseif ( !$botLoginData[2] || $status->hasMessage( 'login-throttled' ) ) {
$authRes = 'Failed';
$message = $status->getMessage();
LoggerFactory::getInstance( 'authentication' )->info(
$authRes = 'Failed';
$message = $status->getMessage();
LoggerFactory::getInstance( 'authentication' )->info(
* @return Status On success, the good status's value is the new Session object
*/
public static function login( $username, $password, WebRequest $request ) {
* @return Status On success, the good status's value is the new Session object
*/
public static function login( $username, $password, WebRequest $request ) {
- global $wgEnableBotPasswords;
+ global $wgEnableBotPasswords, $wgPasswordAttemptThrottle;
if ( !$wgEnableBotPasswords ) {
return Status::newFatal( 'botpasswords-disabled' );
if ( !$wgEnableBotPasswords ) {
return Status::newFatal( 'botpasswords-disabled' );
return Status::newFatal( 'nosuchuser', $name );
}
return Status::newFatal( 'nosuchuser', $name );
}
+ // Throttle
+ $throttle = null;
+ if ( !empty( $wgPasswordAttemptThrottle ) ) {
+ $throttle = new MediaWiki\Auth\Throttler( $wgPasswordAttemptThrottle, [
+ 'type' => 'botpassword',
+ 'cache' => ObjectCache::getLocalClusterInstance(),
+ ] );
+ $result = $throttle->increase( $user->getName(), $request->getIP(), __METHOD__ );
+ if ( $result ) {
+ $msg = wfMessage( 'login-throttled' )->durationParams( $result['wait'] );
+ return Status::newFatal( $msg );
+ }
+ }
+
// Get the bot password
$bp = self::newFromUser( $user, $appId );
if ( !$bp ) {
// Get the bot password
$bp = self::newFromUser( $user, $appId );
if ( !$bp ) {
}
// Ok! Create the session.
}
// Ok! Create the session.
+ if ( $throttle ) {
+ $throttle->clear( $user->getName(), $request->getIP() );
+ }
return Status::newGood( $provider->newSessionForRequest( $user, $bp, $request ) );
}
}
return Status::newGood( $provider->newSessionForRequest( $user, $bp, $request ) );
}
}