5 use Wikimedia\TestingAccessWrapper;
12 global $wgDisableAuthManager;
14 $this->markTestSkipped(
'AuthManager is disabled' );
20 'wgCaptchaBadLoginAttempts' => 1,
21 'wgCaptchaBadLoginPerUserAttempts' => 1,
23 'wgMainCacheType' => __METHOD__,
27 $services = \MediaWiki\MediaWikiServices::getInstance();
28 if ( method_exists(
$services,
'getLocalClusterObjectCache' ) ) {
38 TestingAccessWrapper::newFromClass(
'ConfirmEditHooks' )->instanceCreated =
false;
45 $action,
$username, $triggers, $needsCaptcha, $preTestCallback =
null
48 if ( $preTestCallback ) {
49 $fn = array_shift( $preTestCallback );
50 call_user_func_array( [ $this, $fn ], $preTestCallback );
58 $provider->setManager( AuthManager::singleton() );
59 $reqs = $provider->getAuthenticationRequests( $action, [
'username' =>
$username ] );
60 if ( $needsCaptcha ) {
61 $this->assertCount( 1, $reqs );
64 $this->assertEmpty( $reqs );
70 [ AuthManager::ACTION_LOGIN,
null, [],
false ],
71 [ AuthManager::ACTION_LOGIN,
null, [
'badlogin' ],
false ],
72 [ AuthManager::ACTION_LOGIN,
null, [
'badlogin' ],
true, [
'blockLogin',
'Foo' ] ],
73 [ AuthManager::ACTION_LOGIN,
null, [
'badloginperuser' ],
false, [
'blockLogin',
'Foo' ] ],
74 [ AuthManager::ACTION_LOGIN,
'Foo', [
'badloginperuser' ],
false, [
'blockLogin',
'Bar' ] ],
75 [ AuthManager::ACTION_LOGIN,
'Foo', [
'badloginperuser' ],
true, [
'blockLogin',
'Foo' ] ],
76 [ AuthManager::ACTION_LOGIN,
null, [
'badloginperuser' ],
true, [
'flagSession' ] ],
77 [ AuthManager::ACTION_CREATE,
null, [],
false ],
78 [ AuthManager::ACTION_CREATE,
null, [
'createaccount' ],
true ],
79 [ AuthManager::ACTION_CREATE,
'UTSysop', [
'createaccount' ],
false ],
80 [ AuthManager::ACTION_LINK,
null, [],
false ],
81 [ AuthManager::ACTION_CHANGE,
null, [],
false ],
82 [ AuthManager::ACTION_REMOVE,
null, [],
false ],
90 $provider->setManager( AuthManager::singleton() );
92 $reqs = $provider->getAuthenticationRequests( AuthManager::ACTION_CREATE,
93 [
'username' =>
'Foo' ] );
95 $this->assertCount( 1, $reqs );
98 $id = $reqs[0]->captchaId;
99 $data = TestingAccessWrapper::newFromObject( $reqs[0] )->captchaData;
100 $this->assertEquals( $captcha->retrieveCaptcha( $id ), $data + [
'index' => $id ] );
107 $isBadLoginPerUserTriggered,
$result
115 [
'isBadLoginTriggered',
'isBadLoginPerUserTriggered' ] );
116 $captcha->expects( $this->
any() )->method(
'isBadLoginTriggered' )
117 ->willReturn( $isBadLoginTriggered );
118 $captcha->expects( $this->
any() )->method(
'isBadLoginPerUserTriggered' )
119 ->willReturn( $isBadLoginPerUserTriggered );
121 TestingAccessWrapper::newFromClass(
'ConfirmEditHooks' )->instanceCreated =
true;
123 $provider->setManager( AuthManager::singleton() );
136 'badloginperuser, no username' => [
null,
false,
true,
true ],
152 $this->
setTriggers( $disableTrigger ? [] : [
'createaccount' ] );
156 $provider->setManager( AuthManager::singleton() );
171 'user is exempt' => [
null, $sysop,
true ],
172 'disabled' => [
null,
$user,
true,
'disable' ],
177 $this->
setTriggers( [
'badlogin',
'badloginperuser' ] );
182 $provider->setManager( AuthManager::singleton() );
184 $this->assertFalse( $captcha->isBadLoginTriggered() );
185 $this->assertFalse( $captcha->isBadLoginPerUserTriggered(
$user ) );
187 $provider->postAuthentication(
$user, \
MediaWiki\Auth\AuthenticationResponse::newFail(
190 $this->assertTrue( $captcha->isBadLoginTriggered() );
191 $this->assertTrue( $captcha->isBadLoginPerUserTriggered(
$user ) );
192 $this->assertFalse( $captcha->isBadLoginPerUserTriggered( $anotherUser ) );
194 $provider->postAuthentication(
$user, \
MediaWiki\Auth\AuthenticationResponse::newPass(
'Foo' ) );
196 $this->assertFalse( $captcha->isBadLoginPerUserTriggered(
$user ) );
204 $provider->setManager( AuthManager::singleton() );
206 $this->assertFalse( $captcha->isBadLoginTriggered() );
207 $this->assertFalse( $captcha->isBadLoginPerUserTriggered(
$user ) );
209 $provider->postAuthentication(
$user, \
MediaWiki\Auth\AuthenticationResponse::newFail(
212 $this->assertFalse( $captcha->isBadLoginTriggered() );
213 $this->assertFalse( $captcha->isBadLoginPerUserTriggered(
$user ) );
229 $provider->setManager( AuthManager::singleton() );
230 $providerAccess = TestingAccessWrapper::newFromObject( $provider );
232 foreach ( $attempts
as $attempt ) {
233 if ( !empty( $attempts[3] ) ) {
239 $this->
setMwHook(
'PingLimiter',
function () {
245 $success = $providerAccess->verifyCaptcha( $captcha, [ $attempts[0] ], $attempts[1] );
246 $this->assertEquals( $attempts[2],
$success );
266 'pinglimiter disabled' => [
275 $req->captchaWord = $word;
282 $captcha->increaseBadLoginCounter(
$username );
287 ->set(
'ConfirmEdit:loginCaptchaPerUserTriggered',
true );
291 $types = [
'edit',
'create',
'sendemail',
'addurl',
'createaccount',
'badlogin',
293 $captchaTriggers = array_combine( $types, array_map(
function (
$type )
use ( $triggers ) {
294 return in_array(
$type, $triggers,
true );
296 $this->
setMwGlobals(
'wgCaptchaTriggers', $captchaTriggers );
305 protected function setMwHook( $hook, callable $callback ) {