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