MediaWiki REL1_31
AuthPluginPrimaryAuthenticationProviderTest.php
Go to the documentation of this file.
1<?php
2
3namespace MediaWiki\Auth;
4
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(
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
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 [
173 ];
174 }
175
176 public function testAuthentication() {
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(
189 $provider->beginPrimaryAuthentication( [] )
190 );
191
192 $req->username = 'foo';
193 $req->password = null;
194 $this->assertEquals(
196 $provider->beginPrimaryAuthentication( $reqs )
197 );
198
199 $req->username = null;
200 $req->password = 'bar';
201 $this->assertEquals(
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(
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(
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(
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(
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
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
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
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 }
472 $req->username = 'UTSysop';
473 $req->password = 'Pa$$w0Rd!!!';
474 $req->retype = 'Pa$$w0Rd!!!';
475 $this->assertEquals( $expect, $provider->providerAllowsAuthenticationDataChange( $req ) );
476 }
477
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 [
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
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
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
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 [
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
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(
633 $provider->beginPrimaryAccountCreation( $user, $user, [] )
634 );
635
636 $req->username = 'foo';
637 $req->password = null;
638 $this->assertEquals(
640 $provider->beginPrimaryAccountCreation( $user, $user, $reqs )
641 );
642
643 $req->username = null;
644 $req->password = 'bar';
645 $this->assertEquals(
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(
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}
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
</td >< td > &</td >< td > t want your writing to be edited mercilessly and redistributed at will
An error page which can definitely be safely rendered using the OutputPage.
Backwards-compatibility wrapper for AuthManager via $wgAuth.
const ACTION_CHANGE
Change a user's credentials.
const ACTION_REMOVE
Remove a user's credentials.
const ACTION_LINK
Link an existing user to a third-party account.
const ACTION_LOGIN
Log in with an existing (not necessarily local) user.
const ACTION_CREATE
Create a new user.
AuthManager MediaWiki\Auth\AuthPluginPrimaryAuthenticationProvider.
testProviderAllowsAuthenticationDataChange( $type, $allow, $expect)
provideProviderAllowsAuthenticationDataChange
testGetAuthenticationRequests( $action, $response, $allowPasswordChange)
provideGetAuthenticationRequests
const FAIL
Indicates that the authentication failed.
This is a value object for authentication requests with a username and password.
This is a value object for authentication requests with a username, password, and domain.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition deferred.txt:11
this hook is for auditing only $req
Definition hooks.txt:990
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
Definition hooks.txt:2006
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses & $ret
Definition hooks.txt:2005
this hook is for auditing only $response
Definition hooks.txt:783
processing should stop and the error should be shown to the user * false
Definition hooks.txt:187
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a local account $user
Definition hooks.txt:247
returning false will NOT prevent logging $e
Definition hooks.txt:2176
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition injection.txt:37
const TYPE_NONE
Provider cannot create or link to accounts.