Merge "Let BagOStuff::merge() callbacks override the TTL"
[lhc/web/wiklou.git] / tests / phpunit / includes / auth / AuthPluginPrimaryAuthenticationProviderTest.php
1 <?php
2
3 namespace MediaWiki\Auth;
4
5 /**
6 * @group AuthManager
7 * @covers MediaWiki\Auth\AuthPluginPrimaryAuthenticationProvider
8 */
9 class AuthPluginPrimaryAuthenticationProviderTest extends \MediaWikiTestCase {
10 protected function setUp() {
11 global $wgDisableAuthManager;
12
13 parent::setUp();
14 if ( $wgDisableAuthManager ) {
15 $this->markTestSkipped( '$wgDisableAuthManager is set' );
16 }
17 }
18
19 public function testConstruction() {
20 $plugin = new AuthManagerAuthPlugin();
21 try {
22 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
23 $this->fail( 'Expected exception not thrown' );
24 } catch ( \InvalidArgumentException $ex ) {
25 $this->assertSame(
26 'Trying to wrap AuthManagerAuthPlugin in AuthPluginPrimaryAuthenticationProvider ' .
27 'makes no sense.',
28 $ex->getMessage()
29 );
30 }
31
32 $plugin = $this->getMock( 'AuthPlugin' );
33 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
34
35 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
36 $this->assertEquals(
37 [ new PasswordAuthenticationRequest ],
38 $provider->getAuthenticationRequests( AuthManager::ACTION_LOGIN, [] )
39 );
40
41 $req = $this->getMock( PasswordAuthenticationRequest::class );
42 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin, get_class( $req ) );
43 $this->assertEquals(
44 [ $req ],
45 $provider->getAuthenticationRequests( AuthManager::ACTION_LOGIN, [] )
46 );
47
48 $reqType = get_class( $this->getMock( AuthenticationRequest::class ) );
49 try {
50 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin, $reqType );
51 $this->fail( 'Expected exception not thrown' );
52 } catch ( \InvalidArgumentException $ex ) {
53 $this->assertSame(
54 "$reqType is not a MediaWiki\\Auth\\PasswordAuthenticationRequest",
55 $ex->getMessage()
56 );
57 }
58 }
59
60 public function testOnUserSaveSettings() {
61 $user = \User::newFromName( 'UTSysop' );
62
63 $plugin = $this->getMock( 'AuthPlugin' );
64 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
65 $plugin->expects( $this->once() )->method( 'updateExternalDB' )
66 ->with( $this->identicalTo( $user ) );
67 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
68
69 \Hooks::run( 'UserSaveSettings', [ $user ] );
70 }
71
72 public function testOnUserGroupsChanged() {
73 $user = \User::newFromName( 'UTSysop' );
74
75 $plugin = $this->getMock( 'AuthPlugin' );
76 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
77 $plugin->expects( $this->once() )->method( 'updateExternalDBGroups' )
78 ->with(
79 $this->identicalTo( $user ),
80 $this->identicalTo( [ 'added' ] ),
81 $this->identicalTo( [ 'removed' ] )
82 );
83 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
84
85 \Hooks::run( 'UserGroupsChanged', [ $user, [ 'added' ], [ 'removed' ] ] );
86 }
87
88 public function testOnUserLoggedIn() {
89 $user = \User::newFromName( 'UTSysop' );
90
91 $plugin = $this->getMock( 'AuthPlugin' );
92 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
93 $plugin->expects( $this->exactly( 2 ) )->method( 'updateUser' )
94 ->with( $this->identicalTo( $user ) );
95 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
96 \Hooks::run( 'UserLoggedIn', [ $user ] );
97
98 $plugin = $this->getMock( 'AuthPlugin' );
99 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
100 $plugin->expects( $this->once() )->method( 'updateUser' )
101 ->will( $this->returnCallback( function ( &$user ) {
102 $user = \User::newFromName( 'UTSysop' );
103 } ) );
104 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
105 try {
106 \Hooks::run( 'UserLoggedIn', [ $user ] );
107 $this->fail( 'Expected exception not thrown' );
108 } catch ( \UnexpectedValueException $ex ) {
109 $this->assertSame(
110 get_class( $plugin ) . '::updateUser() tried to replace $user!',
111 $ex->getMessage()
112 );
113 }
114 }
115
116 public function testOnLocalUserCreated() {
117 $user = \User::newFromName( 'UTSysop' );
118
119 $plugin = $this->getMock( 'AuthPlugin' );
120 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
121 $plugin->expects( $this->exactly( 2 ) )->method( 'initUser' )
122 ->with( $this->identicalTo( $user ), $this->identicalTo( false ) );
123 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
124 \Hooks::run( 'LocalUserCreated', [ $user, false ] );
125
126 $plugin = $this->getMock( 'AuthPlugin' );
127 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
128 $plugin->expects( $this->once() )->method( 'initUser' )
129 ->will( $this->returnCallback( function ( &$user ) {
130 $user = \User::newFromName( 'UTSysop' );
131 } ) );
132 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
133 try {
134 \Hooks::run( 'LocalUserCreated', [ $user, false ] );
135 $this->fail( 'Expected exception not thrown' );
136 } catch ( \UnexpectedValueException $ex ) {
137 $this->assertSame(
138 get_class( $plugin ) . '::initUser() tried to replace $user!',
139 $ex->getMessage()
140 );
141 }
142 }
143
144 public function testGetUniqueId() {
145 $plugin = $this->getMock( 'AuthPlugin' );
146 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
147 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
148 $this->assertSame(
149 'MediaWiki\\Auth\\AuthPluginPrimaryAuthenticationProvider:' . get_class( $plugin ),
150 $provider->getUniqueId()
151 );
152 }
153
154 /**
155 * @dataProvider provideGetAuthenticationRequests
156 * @param string $action
157 * @param array $response
158 * @param bool $allowPasswordChange
159 */
160 public function testGetAuthenticationRequests( $action, $response, $allowPasswordChange ) {
161 $plugin = $this->getMock( 'AuthPlugin' );
162 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
163 $plugin->expects( $this->any() )->method( 'allowPasswordChange' )
164 ->will( $this->returnValue( $allowPasswordChange ) );
165 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
166 $this->assertEquals( $response, $provider->getAuthenticationRequests( $action, [] ) );
167 }
168
169 public static function provideGetAuthenticationRequests() {
170 $arr = [ new PasswordAuthenticationRequest() ];
171 return [
172 [ AuthManager::ACTION_LOGIN, $arr, true ],
173 [ AuthManager::ACTION_LOGIN, $arr, false ],
174 [ AuthManager::ACTION_CREATE, $arr, true ],
175 [ AuthManager::ACTION_CREATE, $arr, false ],
176 [ AuthManager::ACTION_LINK, [], true ],
177 [ AuthManager::ACTION_LINK, [], false ],
178 [ AuthManager::ACTION_CHANGE, $arr, true ],
179 [ AuthManager::ACTION_CHANGE, [], false ],
180 [ AuthManager::ACTION_REMOVE, $arr, true ],
181 [ AuthManager::ACTION_REMOVE, [], false ],
182 ];
183 }
184
185 public function testAuthentication() {
186 $req = new PasswordAuthenticationRequest();
187 $req->action = AuthManager::ACTION_LOGIN;
188 $reqs = [ PasswordAuthenticationRequest::class => $req ];
189
190 $plugin = $this->getMockBuilder( 'AuthPlugin' )
191 ->setMethods( [ 'authenticate' ] )
192 ->getMock();
193 $plugin->expects( $this->never() )->method( 'authenticate' );
194 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
195
196 $this->assertEquals(
197 AuthenticationResponse::newAbstain(),
198 $provider->beginPrimaryAuthentication( [] )
199 );
200
201 $req->username = 'foo';
202 $req->password = null;
203 $this->assertEquals(
204 AuthenticationResponse::newAbstain(),
205 $provider->beginPrimaryAuthentication( $reqs )
206 );
207
208 $req->username = null;
209 $req->password = 'bar';
210 $this->assertEquals(
211 AuthenticationResponse::newAbstain(),
212 $provider->beginPrimaryAuthentication( $reqs )
213 );
214
215 $req->username = 'foo';
216 $req->password = 'bar';
217
218 $plugin = $this->getMockBuilder( 'AuthPlugin' )
219 ->setMethods( [ 'userExists', 'authenticate' ] )
220 ->getMock();
221 $plugin->expects( $this->once() )->method( 'userExists' )
222 ->will( $this->returnValue( true ) );
223 $plugin->expects( $this->once() )->method( 'authenticate' )
224 ->with( $this->equalTo( 'Foo' ), $this->equalTo( 'bar' ) )
225 ->will( $this->returnValue( true ) );
226 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
227 $this->assertEquals(
228 AuthenticationResponse::newPass( 'Foo', $req ),
229 $provider->beginPrimaryAuthentication( $reqs )
230 );
231
232 $plugin = $this->getMockBuilder( 'AuthPlugin' )
233 ->setMethods( [ 'userExists', 'authenticate' ] )
234 ->getMock();
235 $plugin->expects( $this->once() )->method( 'userExists' )
236 ->will( $this->returnValue( false ) );
237 $plugin->expects( $this->never() )->method( 'authenticate' );
238 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
239 $this->assertEquals(
240 AuthenticationResponse::newAbstain(),
241 $provider->beginPrimaryAuthentication( $reqs )
242 );
243
244 $pluginUser = $this->getMockBuilder( 'AuthPluginUser' )
245 ->setMethods( [ 'isLocked' ] )
246 ->disableOriginalConstructor()
247 ->getMock();
248 $pluginUser->expects( $this->once() )->method( 'isLocked' )
249 ->will( $this->returnValue( true ) );
250 $plugin = $this->getMockBuilder( 'AuthPlugin' )
251 ->setMethods( [ 'userExists', 'getUserInstance', 'authenticate' ] )
252 ->getMock();
253 $plugin->expects( $this->once() )->method( 'userExists' )
254 ->will( $this->returnValue( true ) );
255 $plugin->expects( $this->once() )->method( 'getUserInstance' )
256 ->will( $this->returnValue( $pluginUser ) );
257 $plugin->expects( $this->never() )->method( 'authenticate' );
258 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
259 $this->assertEquals(
260 AuthenticationResponse::newAbstain(),
261 $provider->beginPrimaryAuthentication( $reqs )
262 );
263
264 $plugin = $this->getMockBuilder( 'AuthPlugin' )
265 ->setMethods( [ 'userExists', 'authenticate' ] )
266 ->getMock();
267 $plugin->expects( $this->once() )->method( 'userExists' )
268 ->will( $this->returnValue( true ) );
269 $plugin->expects( $this->once() )->method( 'authenticate' )
270 ->with( $this->equalTo( 'Foo' ), $this->equalTo( 'bar' ) )
271 ->will( $this->returnValue( false ) );
272 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
273 $this->assertEquals(
274 AuthenticationResponse::newAbstain(),
275 $provider->beginPrimaryAuthentication( $reqs )
276 );
277
278 $plugin = $this->getMockBuilder( 'AuthPlugin' )
279 ->setMethods( [ 'userExists', 'authenticate', 'strict' ] )
280 ->getMock();
281 $plugin->expects( $this->once() )->method( 'userExists' )
282 ->will( $this->returnValue( true ) );
283 $plugin->expects( $this->once() )->method( 'authenticate' )
284 ->with( $this->equalTo( 'Foo' ), $this->equalTo( 'bar' ) )
285 ->will( $this->returnValue( false ) );
286 $plugin->expects( $this->any() )->method( 'strict' )->will( $this->returnValue( true ) );
287 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
288 $ret = $provider->beginPrimaryAuthentication( $reqs );
289 $this->assertSame( AuthenticationResponse::FAIL, $ret->status );
290 $this->assertSame( 'wrongpassword', $ret->message->getKey() );
291
292 $plugin = $this->getMockBuilder( 'AuthPlugin' )
293 ->setMethods( [ 'userExists', 'authenticate', 'strictUserAuth' ] )
294 ->getMock();
295 $plugin->expects( $this->once() )->method( 'userExists' )
296 ->will( $this->returnValue( true ) );
297 $plugin->expects( $this->once() )->method( 'authenticate' )
298 ->with( $this->equalTo( 'Foo' ), $this->equalTo( 'bar' ) )
299 ->will( $this->returnValue( false ) );
300 $plugin->expects( $this->any() )->method( 'strictUserAuth' )
301 ->with( $this->equalTo( 'Foo' ) )
302 ->will( $this->returnValue( true ) );
303 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
304 $ret = $provider->beginPrimaryAuthentication( $reqs );
305 $this->assertSame( AuthenticationResponse::FAIL, $ret->status );
306 $this->assertSame( 'wrongpassword', $ret->message->getKey() );
307
308 $plugin = $this->getMockBuilder( 'AuthPlugin' )
309 ->setMethods( [ 'domainList', 'validDomain', 'setDomain', 'userExists', 'authenticate' ] )
310 ->getMock();
311 $plugin->expects( $this->any() )->method( 'domainList' )
312 ->will( $this->returnValue( [ 'Domain1', 'Domain2' ] ) );
313 $plugin->expects( $this->any() )->method( 'validDomain' )
314 ->will( $this->returnCallback( function ( $domain ) {
315 return in_array( $domain, [ 'Domain1', 'Domain2' ] );
316 } ) );
317 $plugin->expects( $this->once() )->method( 'setDomain' )
318 ->with( $this->equalTo( 'Domain2' ) );
319 $plugin->expects( $this->once() )->method( 'userExists' )
320 ->will( $this->returnValue( true ) );
321 $plugin->expects( $this->once() )->method( 'authenticate' )
322 ->with( $this->equalTo( 'Foo' ), $this->equalTo( 'bar' ) )
323 ->will( $this->returnValue( true ) );
324 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
325 list( $req ) = $provider->getAuthenticationRequests( AuthManager::ACTION_LOGIN, [] );
326 $req->username = 'foo';
327 $req->password = 'bar';
328 $req->domain = 'Domain2';
329 $provider->beginPrimaryAuthentication( [ $req ] );
330 }
331
332 public function testTestUserExists() {
333 $plugin = $this->getMock( 'AuthPlugin' );
334 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
335 $plugin->expects( $this->once() )->method( 'userExists' )
336 ->with( $this->equalTo( 'Foo' ) )
337 ->will( $this->returnValue( true ) );
338 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
339
340 $this->assertTrue( $provider->testUserExists( 'foo' ) );
341
342 $plugin = $this->getMock( 'AuthPlugin' );
343 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
344 $plugin->expects( $this->once() )->method( 'userExists' )
345 ->with( $this->equalTo( 'Foo' ) )
346 ->will( $this->returnValue( false ) );
347 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
348
349 $this->assertFalse( $provider->testUserExists( 'foo' ) );
350 }
351
352 public function testTestUserCanAuthenticate() {
353 $plugin = $this->getMock( 'AuthPlugin' );
354 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
355 $plugin->expects( $this->once() )->method( 'userExists' )
356 ->with( $this->equalTo( 'Foo' ) )
357 ->will( $this->returnValue( false ) );
358 $plugin->expects( $this->never() )->method( 'getUserInstance' );
359 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
360 $this->assertFalse( $provider->testUserCanAuthenticate( 'foo' ) );
361
362 $pluginUser = $this->getMockBuilder( 'AuthPluginUser' )
363 ->disableOriginalConstructor()
364 ->getMock();
365 $pluginUser->expects( $this->once() )->method( 'isLocked' )
366 ->will( $this->returnValue( true ) );
367 $plugin = $this->getMock( 'AuthPlugin' );
368 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
369 $plugin->expects( $this->once() )->method( 'userExists' )
370 ->with( $this->equalTo( 'Foo' ) )
371 ->will( $this->returnValue( true ) );
372 $plugin->expects( $this->once() )->method( 'getUserInstance' )
373 ->with( $this->callback( function ( $user ) {
374 $this->assertInstanceOf( 'User', $user );
375 $this->assertEquals( 'Foo', $user->getName() );
376 return true;
377 } ) )
378 ->will( $this->returnValue( $pluginUser ) );
379 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
380 $this->assertFalse( $provider->testUserCanAuthenticate( 'foo' ) );
381
382 $pluginUser = $this->getMockBuilder( 'AuthPluginUser' )
383 ->disableOriginalConstructor()
384 ->getMock();
385 $pluginUser->expects( $this->once() )->method( 'isLocked' )
386 ->will( $this->returnValue( false ) );
387 $plugin = $this->getMock( 'AuthPlugin' );
388 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
389 $plugin->expects( $this->once() )->method( 'userExists' )
390 ->with( $this->equalTo( 'Foo' ) )
391 ->will( $this->returnValue( true ) );
392 $plugin->expects( $this->once() )->method( 'getUserInstance' )
393 ->with( $this->callback( function ( $user ) {
394 $this->assertInstanceOf( 'User', $user );
395 $this->assertEquals( 'Foo', $user->getName() );
396 return true;
397 } ) )
398 ->will( $this->returnValue( $pluginUser ) );
399 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
400 $this->assertTrue( $provider->testUserCanAuthenticate( 'foo' ) );
401 }
402
403 public function testProviderRevokeAccessForUser() {
404 $plugin = $this->getMockBuilder( 'AuthPlugin' )
405 ->setMethods( [ 'userExists', 'setPassword' ] )
406 ->getMock();
407 $plugin->expects( $this->once() )->method( 'userExists' )->willReturn( true );
408 $plugin->expects( $this->once() )->method( 'setPassword' )
409 ->with( $this->callback( function ( $u ) {
410 return $u instanceof \User && $u->getName() === 'Foo';
411 } ), $this->identicalTo( null ) )
412 ->willReturn( true );
413 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
414 $provider->providerRevokeAccessForUser( 'foo' );
415
416 $plugin = $this->getMockBuilder( 'AuthPlugin' )
417 ->setMethods( [ 'domainList', 'userExists', 'setPassword' ] )
418 ->getMock();
419 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [ 'D1', 'D2', 'D3' ] );
420 $plugin->expects( $this->exactly( 3 ) )->method( 'userExists' )
421 ->willReturnCallback( function () use ( $plugin ) {
422 return $plugin->getDomain() !== 'D2';
423 } );
424 $plugin->expects( $this->exactly( 2 ) )->method( 'setPassword' )
425 ->with( $this->callback( function ( $u ) {
426 return $u instanceof \User && $u->getName() === 'Foo';
427 } ), $this->identicalTo( null ) )
428 ->willReturnCallback( function () use ( $plugin ) {
429 $this->assertNotEquals( 'D2', $plugin->getDomain() );
430 return $plugin->getDomain() !== 'D1';
431 } );
432 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
433 try {
434 $provider->providerRevokeAccessForUser( 'foo' );
435 $this->fail( 'Expected exception not thrown' );
436 } catch ( \UnexpectedValueException $ex ) {
437 $this->assertSame(
438 'AuthPlugin failed to reset password for Foo in the following domains: D1',
439 $ex->getMessage()
440 );
441 }
442 }
443
444 public function testProviderAllowsPropertyChange() {
445 $plugin = $this->getMock( 'AuthPlugin' );
446 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
447 $plugin->expects( $this->any() )->method( 'allowPropChange' )
448 ->will( $this->returnCallback( function ( $prop ) {
449 return $prop === 'allow';
450 } ) );
451 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
452
453 $this->assertTrue( $provider->providerAllowsPropertyChange( 'allow' ) );
454 $this->assertFalse( $provider->providerAllowsPropertyChange( 'deny' ) );
455 }
456
457 /**
458 * @dataProvider provideProviderAllowsAuthenticationDataChange
459 * @param string $type
460 * @param bool|null $allow
461 * @param StatusValue $expect
462 */
463 public function testProviderAllowsAuthenticationDataChange( $type, $allow, $expect ) {
464 $plugin = $this->getMock( 'AuthPlugin' );
465 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
466 $plugin->expects( $allow === null ? $this->never() : $this->once() )
467 ->method( 'allowPasswordChange' )->will( $this->returnValue( $allow ) );
468 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
469
470 if ( $type === PasswordAuthenticationRequest::class ) {
471 $req = new $type();
472 } else {
473 $req = $this->getMock( $type );
474 }
475 $req->action = AuthManager::ACTION_CHANGE;
476 $req->username = 'UTSysop';
477 $req->password = 'Pa$$w0Rd!!!';
478 $req->retype = 'Pa$$w0Rd!!!';
479 $this->assertEquals( $expect, $provider->providerAllowsAuthenticationDataChange( $req ) );
480 }
481
482 public static function provideProviderAllowsAuthenticationDataChange() {
483 return [
484 [ AuthenticationRequest::class, null, \StatusValue::newGood( 'ignored' ) ],
485 [ PasswordAuthenticationRequest::class, true, \StatusValue::newGood() ],
486 [
487 PasswordAuthenticationRequest::class,
488 false,
489 \StatusValue::newFatal( 'authmanager-authplugin-setpass-denied' )
490 ],
491 ];
492 }
493
494 public function testProviderChangeAuthenticationData() {
495 $plugin = $this->getMock( 'AuthPlugin' );
496 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
497 $plugin->expects( $this->never() )->method( 'setPassword' );
498 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
499 $provider->providerChangeAuthenticationData(
500 $this->getMock( AuthenticationRequest::class )
501 );
502
503 $req = new PasswordAuthenticationRequest();
504 $req->action = AuthManager::ACTION_CHANGE;
505 $req->username = 'foo';
506 $req->password = 'bar';
507
508 $plugin = $this->getMock( 'AuthPlugin' );
509 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
510 $plugin->expects( $this->once() )->method( 'setPassword' )
511 ->with( $this->callback( function ( $u ) {
512 return $u instanceof \User && $u->getName() === 'Foo';
513 } ), $this->equalTo( 'bar' ) )
514 ->will( $this->returnValue( true ) );
515 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
516 $provider->providerChangeAuthenticationData( $req );
517
518 $plugin = $this->getMock( 'AuthPlugin' );
519 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
520 $plugin->expects( $this->once() )->method( 'setPassword' )
521 ->with( $this->callback( function ( $u ) {
522 return $u instanceof \User && $u->getName() === 'Foo';
523 } ), $this->equalTo( 'bar' ) )
524 ->will( $this->returnValue( false ) );
525 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
526 try {
527 $provider->providerChangeAuthenticationData( $req );
528 $this->fail( 'Expected exception not thrown' );
529 } catch ( \ErrorPageError $e ) {
530 $this->assertSame( 'authmanager-authplugin-setpass-failed-title', $e->title );
531 $this->assertSame( 'authmanager-authplugin-setpass-failed-message', $e->msg );
532 }
533
534 $plugin = $this->getMock( 'AuthPlugin' );
535 $plugin->expects( $this->any() )->method( 'domainList' )
536 ->will( $this->returnValue( [ 'Domain1', 'Domain2' ] ) );
537 $plugin->expects( $this->any() )->method( 'validDomain' )
538 ->will( $this->returnCallback( function ( $domain ) {
539 return in_array( $domain, [ 'Domain1', 'Domain2' ] );
540 } ) );
541 $plugin->expects( $this->once() )->method( 'setDomain' )
542 ->with( $this->equalTo( 'Domain2' ) );
543 $plugin->expects( $this->once() )->method( 'setPassword' )
544 ->with( $this->callback( function ( $u ) {
545 return $u instanceof \User && $u->getName() === 'Foo';
546 } ), $this->equalTo( 'bar' ) )
547 ->will( $this->returnValue( true ) );
548 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
549 list( $req ) = $provider->getAuthenticationRequests( AuthManager::ACTION_CREATE, [] );
550 $req->username = 'foo';
551 $req->password = 'bar';
552 $req->domain = 'Domain2';
553 $provider->providerChangeAuthenticationData( $req );
554 }
555
556 /**
557 * @dataProvider provideAccountCreationType
558 * @param bool $can
559 * @param string $expect
560 */
561 public function testAccountCreationType( $can, $expect ) {
562 $plugin = $this->getMock( 'AuthPlugin' );
563 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
564 $plugin->expects( $this->once() )
565 ->method( 'canCreateAccounts' )->will( $this->returnValue( $can ) );
566 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
567
568 $this->assertSame( $expect, $provider->accountCreationType() );
569 }
570
571 public static function provideAccountCreationType() {
572 return [
573 [ true, PrimaryAuthenticationProvider::TYPE_CREATE ],
574 [ false, PrimaryAuthenticationProvider::TYPE_NONE ],
575 ];
576 }
577
578 public function testTestForAccountCreation() {
579 $user = \User::newFromName( 'foo' );
580
581 $plugin = $this->getMock( 'AuthPlugin' );
582 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
583 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
584 $this->assertEquals(
585 \StatusValue::newGood(),
586 $provider->testForAccountCreation( $user, $user, [] )
587 );
588 }
589
590 public function testAccountCreation() {
591 $user = \User::newFromName( 'foo' );
592 $user->setEmail( 'email' );
593 $user->setRealName( 'realname' );
594
595 $req = new PasswordAuthenticationRequest();
596 $req->action = AuthManager::ACTION_CREATE;
597 $reqs = [ PasswordAuthenticationRequest::class => $req ];
598
599 $plugin = $this->getMock( 'AuthPlugin' );
600 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
601 $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
602 ->will( $this->returnValue( false ) );
603 $plugin->expects( $this->never() )->method( 'addUser' );
604 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
605 try {
606 $provider->beginPrimaryAccountCreation( $user, $user, [] );
607 $this->fail( 'Expected exception was not thrown' );
608 } catch ( \BadMethodCallException $ex ) {
609 $this->assertSame(
610 'Shouldn\'t call this when accountCreationType() is NONE', $ex->getMessage()
611 );
612 }
613
614 $plugin = $this->getMock( 'AuthPlugin' );
615 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
616 $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
617 ->will( $this->returnValue( true ) );
618 $plugin->expects( $this->never() )->method( 'addUser' );
619 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
620
621 $this->assertEquals(
622 AuthenticationResponse::newAbstain(),
623 $provider->beginPrimaryAccountCreation( $user, $user, [] )
624 );
625
626 $req->username = 'foo';
627 $req->password = null;
628 $this->assertEquals(
629 AuthenticationResponse::newAbstain(),
630 $provider->beginPrimaryAccountCreation( $user, $user, $reqs )
631 );
632
633 $req->username = null;
634 $req->password = 'bar';
635 $this->assertEquals(
636 AuthenticationResponse::newAbstain(),
637 $provider->beginPrimaryAccountCreation( $user, $user, $reqs )
638 );
639
640 $req->username = 'foo';
641 $req->password = 'bar';
642
643 $plugin = $this->getMock( 'AuthPlugin' );
644 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
645 $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
646 ->will( $this->returnValue( true ) );
647 $plugin->expects( $this->once() )->method( 'addUser' )
648 ->with(
649 $this->callback( function ( $u ) {
650 return $u instanceof \User && $u->getName() === 'Foo';
651 } ),
652 $this->equalTo( 'bar' ),
653 $this->equalTo( 'email' ),
654 $this->equalTo( 'realname' )
655 )
656 ->will( $this->returnValue( true ) );
657 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
658 $this->assertEquals(
659 AuthenticationResponse::newPass(),
660 $provider->beginPrimaryAccountCreation( $user, $user, $reqs )
661 );
662
663 $plugin = $this->getMock( 'AuthPlugin' );
664 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
665 $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
666 ->will( $this->returnValue( true ) );
667 $plugin->expects( $this->once() )->method( 'addUser' )
668 ->with(
669 $this->callback( function ( $u ) {
670 return $u instanceof \User && $u->getName() === 'Foo';
671 } ),
672 $this->equalTo( 'bar' ),
673 $this->equalTo( 'email' ),
674 $this->equalTo( 'realname' )
675 )
676 ->will( $this->returnValue( false ) );
677 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
678 $ret = $provider->beginPrimaryAccountCreation( $user, $user, $reqs );
679 $this->assertSame( AuthenticationResponse::FAIL, $ret->status );
680 $this->assertSame( 'authmanager-authplugin-create-fail', $ret->message->getKey() );
681
682 $plugin = $this->getMock( 'AuthPlugin' );
683 $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
684 ->will( $this->returnValue( true ) );
685 $plugin->expects( $this->any() )->method( 'domainList' )
686 ->will( $this->returnValue( [ 'Domain1', 'Domain2' ] ) );
687 $plugin->expects( $this->any() )->method( 'validDomain' )
688 ->will( $this->returnCallback( function ( $domain ) {
689 return in_array( $domain, [ 'Domain1', 'Domain2' ] );
690 } ) );
691 $plugin->expects( $this->once() )->method( 'setDomain' )
692 ->with( $this->equalTo( 'Domain2' ) );
693 $plugin->expects( $this->once() )->method( 'addUser' )
694 ->with( $this->callback( function ( $u ) {
695 return $u instanceof \User && $u->getName() === 'Foo';
696 } ), $this->equalTo( 'bar' ) )
697 ->will( $this->returnValue( true ) );
698 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
699 list( $req ) = $provider->getAuthenticationRequests( AuthManager::ACTION_CREATE, [] );
700 $req->username = 'foo';
701 $req->password = 'bar';
702 $req->domain = 'Domain2';
703 $provider->beginPrimaryAccountCreation( $user, $user, [ $req ] );
704 }
705
706 }