14 'wgEnableBotPasswords' =>
true,
15 'wgBotPasswordsDatabase' =>
false,
16 'wgCentralIdLookupProvider' =>
'BotPasswordTest OkMock',
17 'wgGrantPermissions' => [
18 'test' => [
'read' =>
true ],
20 'wgUserrightsInterwikiDelimiter' =>
'@',
23 $mock1 = $this->getMockForAbstractClass(
'CentralIdLookup' );
24 $mock1->expects( $this->any() )->method(
'isAttached' )
25 ->will( $this->returnValue(
true ) );
26 $mock1->expects( $this->any() )->method(
'lookupUserNames' )
27 ->will( $this->returnValue( [
'UTSysop' => 42,
'UTDummy' => 43,
'UTInvalid' => 0 ] ) );
28 $mock1->expects( $this->never() )->method(
'lookupCentralIds' );
30 $mock2 = $this->getMockForAbstractClass(
'CentralIdLookup' );
31 $mock2->expects( $this->any() )->method(
'isAttached' )
32 ->will( $this->returnValue(
false ) );
33 $mock2->expects( $this->any() )->method(
'lookupUserNames' )
34 ->will( $this->returnArgument( 0 ) );
35 $mock2->expects( $this->never() )->method(
'lookupCentralIds' );
38 'BotPasswordTest OkMock' => [
'factory' =>
function ()
use ( $mock1 ) {
41 'BotPasswordTest FailMock' => [
'factory' =>
function ()
use ( $mock2 ) {
87 $user = User::newFromName(
'UTSysop' );
88 $bp = BotPassword::newFromUser(
$user,
'BotPassword' );
89 $this->assertInstanceOf(
'BotPassword', $bp );
90 $this->assertTrue( $bp->isSaved() );
91 $this->assertSame( 42, $bp->getUserCentralId() );
92 $this->assertSame(
'BotPassword', $bp->getAppId() );
93 $this->assertSame(
'token!', trim( $bp->getToken(),
" \0" ) );
94 $this->assertEquals(
'{"IPAddresses":["127.0.0.0/8"]}', $bp->getRestrictions()->toJson() );
95 $this->assertSame( [
'test' ], $bp->getGrants() );
97 $this->assertNull( BotPassword::newFromUser(
$user,
'DoesNotExist' ) );
100 'wgCentralIdLookupProvider' =>
'BotPasswordTest FailMock'
102 $this->assertNull( BotPassword::newFromUser(
$user,
'BotPassword' ) );
104 $this->assertSame(
'@', BotPassword::getSeparator() );
106 'wgUserrightsInterwikiDelimiter' =>
'#',
108 $this->assertSame(
'#', BotPassword::getSeparator() );
112 $user = User::newFromName(
'UTSysop' );
113 $bp = BotPassword::newUnsaved( [
115 'appId' =>
'DoesNotExist'
117 $this->assertInstanceOf(
'BotPassword', $bp );
118 $this->assertFalse( $bp->isSaved() );
119 $this->assertSame( 42, $bp->getUserCentralId() );
120 $this->assertSame(
'DoesNotExist', $bp->getAppId() );
122 $this->assertSame( [], $bp->getGrants() );
124 $bp = BotPassword::newUnsaved( [
125 'username' =>
'UTDummy',
126 'appId' =>
'DoesNotExist2',
128 'grants' => [
'test' ],
130 $this->assertInstanceOf(
'BotPassword', $bp );
131 $this->assertFalse( $bp->isSaved() );
132 $this->assertSame( 43, $bp->getUserCentralId() );
133 $this->assertSame(
'DoesNotExist2', $bp->getAppId() );
134 $this->assertEquals(
'{"IPAddresses":["127.0.0.0/8"]}', $bp->getRestrictions()->toJson() );
135 $this->assertSame( [
'test' ], $bp->getGrants() );
137 $user = User::newFromName(
'UTSysop' );
138 $bp = BotPassword::newUnsaved( [
140 'appId' =>
'DoesNotExist'
142 $this->assertInstanceOf(
'BotPassword', $bp );
143 $this->assertFalse( $bp->isSaved() );
144 $this->assertSame( 45, $bp->getUserCentralId() );
145 $this->assertSame(
'DoesNotExist', $bp->getAppId() );
147 $user = User::newFromName(
'UTSysop' );
148 $bp = BotPassword::newUnsaved( [
150 'appId' =>
'BotPassword'
152 $this->assertInstanceOf(
'BotPassword', $bp );
153 $this->assertFalse( $bp->isSaved() );
155 $this->assertNull( BotPassword::newUnsaved( [
159 $this->assertNull( BotPassword::newUnsaved( [
161 'appId' => str_repeat(
'X', BotPassword::APPID_MAXLENGTH + 1 ),
163 $this->assertNull( BotPassword::newUnsaved( [
167 $this->assertNull( BotPassword::newUnsaved( [
168 'username' =>
'UTInvalid',
171 $this->assertNull( BotPassword::newUnsaved( [
177 $bp = TestingAccessWrapper::newFromObject( BotPassword::newFromCentralId( 42,
'BotPassword' ) );
179 $password = $bp->getPassword();
180 $this->assertInstanceOf(
'Password', $password );
181 $this->assertTrue( $password->equals(
'foobaz' ) );
184 $password = $bp->getPassword();
185 $this->assertInstanceOf(
'InvalidPassword', $password );
187 $bp = TestingAccessWrapper::newFromObject( BotPassword::newFromCentralId( 42,
'BotPassword' ) );
191 [
'bp_password' =>
'garbage' ],
192 [
'bp_user' => 42,
'bp_app_id' =>
'BotPassword' ],
195 $password = $bp->getPassword();
196 $this->assertInstanceOf(
'InvalidPassword', $password );
200 $bp1 = TestingAccessWrapper::newFromObject( BotPassword::newFromCentralId( 42,
'BotPassword' ) );
201 $bp2 = TestingAccessWrapper::newFromObject( BotPassword::newFromCentralId( 43,
'BotPassword' ) );
203 $this->assertNotInstanceOf(
'InvalidPassword', $bp1->getPassword(),
'sanity check' );
204 $this->assertNotInstanceOf(
'InvalidPassword', $bp2->getPassword(),
'sanity check' );
205 BotPassword::invalidateAllPasswordsForUser(
'UTSysop' );
206 $this->assertInstanceOf(
'InvalidPassword', $bp1->getPassword() );
207 $this->assertNotInstanceOf(
'InvalidPassword', $bp2->getPassword() );
209 $bp = TestingAccessWrapper::newFromObject( BotPassword::newFromCentralId( 42,
'BotPassword' ) );
210 $this->assertInstanceOf(
'InvalidPassword', $bp->getPassword() );
214 $this->assertNotNull( BotPassword::newFromCentralId( 42,
'BotPassword' ),
'sanity check' );
215 $this->assertNotNull( BotPassword::newFromCentralId( 43,
'BotPassword' ),
'sanity check' );
217 BotPassword::removeAllPasswordsForUser(
'UTSysop' );
219 $this->assertNull( BotPassword::newFromCentralId( 42,
'BotPassword' ) );
220 $this->assertNotNull( BotPassword::newFromCentralId( 43,
'BotPassword' ) );
255 $this->assertEquals( Status::newFatal(
'botpasswords-disabled' ),
$status );
260 'logger' =>
new Psr\Log\NullLogger,
263 $reset = MediaWiki\Session\TestUtils::setSessionManagerSingleton( $manager );
265 $manager->getProvider(
MediaWiki\Session\BotPasswordSessionProvider::class ),
269 $this->assertEquals( Status::newFatal(
'botpasswords-no-provider' ),
$status );
275 'SessionProviders' => $mainConfig->get(
'SessionProviders' ) + [
276 MediaWiki\Session\BotPasswordSessionProvider::class => [
277 'class' =>
MediaWiki\Session\BotPasswordSessionProvider::class,
278 'args' => [ [
'priority' => 40 ] ],
284 'logger' =>
new Psr\Log\NullLogger,
287 $reset = MediaWiki\Session\TestUtils::setSessionManagerSingleton( $manager );
291 $this->assertEquals( Status::newFatal(
'botpasswords-invalid-name',
'@' ),
$status );
295 $this->assertEquals( Status::newFatal(
'nosuchuser',
'UTDummy' ),
$status );
300 Status::newFatal(
'botpasswords-not-exist',
'UTSysop',
'DoesNotExist' ),
305 $request = $this->getMock(
'FauxRequest', [
'getIP' ] );
306 $request->expects( $this->any() )->method(
'getIP' )
307 ->will( $this->returnValue(
'10.0.0.1' ) );
308 $status = BotPassword::login(
'UTSysop@BotPassword',
'foobaz',
$request );
309 $this->assertEquals( Status::newFatal(
'botpasswords-restriction-failed' ),
$status );
312 $status = BotPassword::login(
'UTSysop@BotPassword',
'UTSysopPassword',
new FauxRequest );
313 $this->assertEquals( Status::newFatal(
'wrongpassword' ),
$status );
317 $this->assertNotInstanceOf(
318 MediaWiki\Session\BotPasswordSessionProvider::class,
319 $request->getSession()->getProvider(),
322 $status = BotPassword::login(
'UTSysop@BotPassword',
'foobaz',
$request );
323 $this->assertInstanceOf(
'Status',
$status );
324 $this->assertTrue(
$status->isGood() );
325 $session =
$status->getValue();
326 $this->assertInstanceOf(
MediaWiki\Session\Session::class, $session );
327 $this->assertInstanceOf(
328 MediaWiki\Session\BotPasswordSessionProvider::class, $session->getProvider()
330 $this->assertSame( $session->getId(),
$request->getSession()->getId() );
340 $passwordFactory = new \PasswordFactory();
343 $passwordFactory->setDefaultType(
'A' );
345 $bp = BotPassword::newUnsaved( [
347 'appId' =>
'TestSave',
349 'grants' => [
'test' ],
351 $this->assertFalse( $bp->isSaved(),
'sanity check' );
353 BotPassword::newFromCentralId( 42,
'TestSave', BotPassword::READ_LATEST ),
'sanity check'
356 $pwhash = $password ? $passwordFactory->newFromPlaintext( $password ) :
null;
357 $this->assertFalse( $bp->save(
'update', $pwhash ) );
358 $this->assertTrue( $bp->save(
'insert', $pwhash ) );
359 $bp2 = BotPassword::newFromCentralId( 42,
'TestSave', BotPassword::READ_LATEST );
360 $this->assertInstanceOf(
'BotPassword', $bp2 );
361 $this->assertEquals( $bp->getUserCentralId(), $bp2->getUserCentralId() );
362 $this->assertEquals( $bp->getAppId(), $bp2->getAppId() );
363 $this->assertEquals( $bp->getToken(), $bp2->getToken() );
364 $this->assertEquals( $bp->getRestrictions(), $bp2->getRestrictions() );
365 $this->assertEquals( $bp->getGrants(), $bp2->getGrants() );
366 $pw = TestingAccessWrapper::newFromObject( $bp )->getPassword();
367 if ( $password ===
null ) {
368 $this->assertInstanceOf(
'InvalidPassword', $pw );
370 $this->assertTrue( $pw->equals( $password ) );
373 $token = $bp->getToken();
374 $this->assertFalse( $bp->save(
'insert' ) );
375 $this->assertTrue( $bp->save(
'update' ) );
376 $this->assertNotEquals( $token, $bp->getToken() );
377 $bp2 = BotPassword::newFromCentralId( 42,
'TestSave', BotPassword::READ_LATEST );
378 $this->assertInstanceOf(
'BotPassword', $bp2 );
379 $this->assertEquals( $bp->getToken(), $bp2->getToken() );
380 $pw = TestingAccessWrapper::newFromObject( $bp )->getPassword();
381 if ( $password ===
null ) {
382 $this->assertInstanceOf(
'InvalidPassword', $pw );
384 $this->assertTrue( $pw->equals( $password ) );
387 $pwhash = $passwordFactory->newFromPlaintext(
'XXX' );
388 $token = $bp->getToken();
389 $this->assertTrue( $bp->save(
'update', $pwhash ) );
390 $this->assertNotEquals( $token, $bp->getToken() );
391 $pw = TestingAccessWrapper::newFromObject( $bp )->getPassword();
392 $this->assertTrue( $pw->equals(
'XXX' ) );
394 $this->assertTrue( $bp->delete() );
395 $this->assertFalse( $bp->isSaved() );
396 $this->assertNull( BotPassword::newFromCentralId( 42,
'TestSave', BotPassword::READ_LATEST ) );
398 $this->assertFalse( $bp->save(
'foobar' ) );