Typo fix for AuthPluginPrimaryAuthenticationProvider::providerAllowsAuthenticationDat...
[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 $domains = $type instanceof PasswordDomainAuthenticationRequest ? [ 'foo', 'bar' ] : [];
465 $plugin = $this->getMock( 'AuthPlugin' );
466 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( $domains );
467 $plugin->expects( $allow === null ? $this->never() : $this->once() )
468 ->method( 'allowPasswordChange' )->will( $this->returnValue( $allow ) );
469 $plugin->expects( $this->any() )->method( 'validDomain' )
470 ->willReturnCallback( function ( $d ) use ( $domains ) {
471 return in_array( $d, $domains, true );
472 } );
473 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
474
475 if ( is_object( $type ) ) {
476 $req = $type;
477 } else {
478 $req = $this->getMock( $type );
479 }
480 $req->action = AuthManager::ACTION_CHANGE;
481 $req->username = 'UTSysop';
482 $req->password = 'Pa$$w0Rd!!!';
483 $req->retype = 'Pa$$w0Rd!!!';
484 $this->assertEquals( $expect, $provider->providerAllowsAuthenticationDataChange( $req ) );
485 }
486
487 public static function provideProviderAllowsAuthenticationDataChange() {
488 $domains = [ 'foo', 'bar' ];
489 $reqNoDomain = new PasswordDomainAuthenticationRequest( $domains );
490 $reqValidDomain = new PasswordDomainAuthenticationRequest( $domains );
491 $reqValidDomain->domain = 'foo';
492 $reqInvalidDomain = new PasswordDomainAuthenticationRequest( $domains );
493 $reqInvalidDomain->domain = 'invalid';
494
495 return [
496 [ AuthenticationRequest::class, null, \StatusValue::newGood( 'ignored' ) ],
497 [ new PasswordAuthenticationRequest, true, \StatusValue::newGood() ],
498 [
499 new PasswordAuthenticationRequest,
500 false,
501 \StatusValue::newFatal( 'authmanager-authplugin-setpass-denied' )
502 ],
503 [ $reqNoDomain, true, \StatusValue::newGood( 'ignored' ) ],
504 [ $reqValidDomain, true, \StatusValue::newGood() ],
505 [
506 $reqInvalidDomain,
507 true,
508 \StatusValue::newFatal( 'authmanager-authplugin-setpass-bad-domain' )
509 ],
510 ];
511 }
512
513 public function testProviderChangeAuthenticationData() {
514 $plugin = $this->getMock( 'AuthPlugin' );
515 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
516 $plugin->expects( $this->never() )->method( 'setPassword' );
517 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
518 $provider->providerChangeAuthenticationData(
519 $this->getMock( AuthenticationRequest::class )
520 );
521
522 $req = new PasswordAuthenticationRequest();
523 $req->action = AuthManager::ACTION_CHANGE;
524 $req->username = 'foo';
525 $req->password = 'bar';
526
527 $plugin = $this->getMock( 'AuthPlugin' );
528 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
529 $plugin->expects( $this->once() )->method( 'setPassword' )
530 ->with( $this->callback( function ( $u ) {
531 return $u instanceof \User && $u->getName() === 'Foo';
532 } ), $this->equalTo( 'bar' ) )
533 ->will( $this->returnValue( true ) );
534 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
535 $provider->providerChangeAuthenticationData( $req );
536
537 $plugin = $this->getMock( 'AuthPlugin' );
538 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
539 $plugin->expects( $this->once() )->method( 'setPassword' )
540 ->with( $this->callback( function ( $u ) {
541 return $u instanceof \User && $u->getName() === 'Foo';
542 } ), $this->equalTo( 'bar' ) )
543 ->will( $this->returnValue( false ) );
544 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
545 try {
546 $provider->providerChangeAuthenticationData( $req );
547 $this->fail( 'Expected exception not thrown' );
548 } catch ( \ErrorPageError $e ) {
549 $this->assertSame( 'authmanager-authplugin-setpass-failed-title', $e->title );
550 $this->assertSame( 'authmanager-authplugin-setpass-failed-message', $e->msg );
551 }
552
553 $plugin = $this->getMock( 'AuthPlugin' );
554 $plugin->expects( $this->any() )->method( 'domainList' )
555 ->will( $this->returnValue( [ 'Domain1', 'Domain2' ] ) );
556 $plugin->expects( $this->any() )->method( 'validDomain' )
557 ->will( $this->returnCallback( function ( $domain ) {
558 return in_array( $domain, [ 'Domain1', 'Domain2' ] );
559 } ) );
560 $plugin->expects( $this->once() )->method( 'setDomain' )
561 ->with( $this->equalTo( 'Domain2' ) );
562 $plugin->expects( $this->once() )->method( 'setPassword' )
563 ->with( $this->callback( function ( $u ) {
564 return $u instanceof \User && $u->getName() === 'Foo';
565 } ), $this->equalTo( 'bar' ) )
566 ->will( $this->returnValue( true ) );
567 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
568 list( $req ) = $provider->getAuthenticationRequests( AuthManager::ACTION_CREATE, [] );
569 $req->username = 'foo';
570 $req->password = 'bar';
571 $req->domain = 'Domain2';
572 $provider->providerChangeAuthenticationData( $req );
573 }
574
575 /**
576 * @dataProvider provideAccountCreationType
577 * @param bool $can
578 * @param string $expect
579 */
580 public function testAccountCreationType( $can, $expect ) {
581 $plugin = $this->getMock( 'AuthPlugin' );
582 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
583 $plugin->expects( $this->once() )
584 ->method( 'canCreateAccounts' )->will( $this->returnValue( $can ) );
585 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
586
587 $this->assertSame( $expect, $provider->accountCreationType() );
588 }
589
590 public static function provideAccountCreationType() {
591 return [
592 [ true, PrimaryAuthenticationProvider::TYPE_CREATE ],
593 [ false, PrimaryAuthenticationProvider::TYPE_NONE ],
594 ];
595 }
596
597 public function testTestForAccountCreation() {
598 $user = \User::newFromName( 'foo' );
599
600 $plugin = $this->getMock( 'AuthPlugin' );
601 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
602 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
603 $this->assertEquals(
604 \StatusValue::newGood(),
605 $provider->testForAccountCreation( $user, $user, [] )
606 );
607 }
608
609 public function testAccountCreation() {
610 $user = \User::newFromName( 'foo' );
611 $user->setEmail( 'email' );
612 $user->setRealName( 'realname' );
613
614 $req = new PasswordAuthenticationRequest();
615 $req->action = AuthManager::ACTION_CREATE;
616 $reqs = [ PasswordAuthenticationRequest::class => $req ];
617
618 $plugin = $this->getMock( 'AuthPlugin' );
619 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
620 $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
621 ->will( $this->returnValue( false ) );
622 $plugin->expects( $this->never() )->method( 'addUser' );
623 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
624 try {
625 $provider->beginPrimaryAccountCreation( $user, $user, [] );
626 $this->fail( 'Expected exception was not thrown' );
627 } catch ( \BadMethodCallException $ex ) {
628 $this->assertSame(
629 'Shouldn\'t call this when accountCreationType() is NONE', $ex->getMessage()
630 );
631 }
632
633 $plugin = $this->getMock( 'AuthPlugin' );
634 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
635 $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
636 ->will( $this->returnValue( true ) );
637 $plugin->expects( $this->never() )->method( 'addUser' );
638 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
639
640 $this->assertEquals(
641 AuthenticationResponse::newAbstain(),
642 $provider->beginPrimaryAccountCreation( $user, $user, [] )
643 );
644
645 $req->username = 'foo';
646 $req->password = null;
647 $this->assertEquals(
648 AuthenticationResponse::newAbstain(),
649 $provider->beginPrimaryAccountCreation( $user, $user, $reqs )
650 );
651
652 $req->username = null;
653 $req->password = 'bar';
654 $this->assertEquals(
655 AuthenticationResponse::newAbstain(),
656 $provider->beginPrimaryAccountCreation( $user, $user, $reqs )
657 );
658
659 $req->username = 'foo';
660 $req->password = 'bar';
661
662 $plugin = $this->getMock( 'AuthPlugin' );
663 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
664 $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
665 ->will( $this->returnValue( true ) );
666 $plugin->expects( $this->once() )->method( 'addUser' )
667 ->with(
668 $this->callback( function ( $u ) {
669 return $u instanceof \User && $u->getName() === 'Foo';
670 } ),
671 $this->equalTo( 'bar' ),
672 $this->equalTo( 'email' ),
673 $this->equalTo( 'realname' )
674 )
675 ->will( $this->returnValue( true ) );
676 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
677 $this->assertEquals(
678 AuthenticationResponse::newPass(),
679 $provider->beginPrimaryAccountCreation( $user, $user, $reqs )
680 );
681
682 $plugin = $this->getMock( 'AuthPlugin' );
683 $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
684 $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
685 ->will( $this->returnValue( true ) );
686 $plugin->expects( $this->once() )->method( 'addUser' )
687 ->with(
688 $this->callback( function ( $u ) {
689 return $u instanceof \User && $u->getName() === 'Foo';
690 } ),
691 $this->equalTo( 'bar' ),
692 $this->equalTo( 'email' ),
693 $this->equalTo( 'realname' )
694 )
695 ->will( $this->returnValue( false ) );
696 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
697 $ret = $provider->beginPrimaryAccountCreation( $user, $user, $reqs );
698 $this->assertSame( AuthenticationResponse::FAIL, $ret->status );
699 $this->assertSame( 'authmanager-authplugin-create-fail', $ret->message->getKey() );
700
701 $plugin = $this->getMock( 'AuthPlugin' );
702 $plugin->expects( $this->any() )->method( 'canCreateAccounts' )
703 ->will( $this->returnValue( true ) );
704 $plugin->expects( $this->any() )->method( 'domainList' )
705 ->will( $this->returnValue( [ 'Domain1', 'Domain2' ] ) );
706 $plugin->expects( $this->any() )->method( 'validDomain' )
707 ->will( $this->returnCallback( function ( $domain ) {
708 return in_array( $domain, [ 'Domain1', 'Domain2' ] );
709 } ) );
710 $plugin->expects( $this->once() )->method( 'setDomain' )
711 ->with( $this->equalTo( 'Domain2' ) );
712 $plugin->expects( $this->once() )->method( 'addUser' )
713 ->with( $this->callback( function ( $u ) {
714 return $u instanceof \User && $u->getName() === 'Foo';
715 } ), $this->equalTo( 'bar' ) )
716 ->will( $this->returnValue( true ) );
717 $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
718 list( $req ) = $provider->getAuthenticationRequests( AuthManager::ACTION_CREATE, [] );
719 $req->username = 'foo';
720 $req->password = 'bar';
721 $req->domain = 'Domain2';
722 $provider->beginPrimaryAccountCreation( $user, $user, [ $req ] );
723 }
724
725 }