MediaWiki  master
AuthPluginPrimaryAuthenticationProviderTest.php
Go to the documentation of this file.
1 <?php
2 
3 namespace MediaWiki\Auth;
4 
10  protected function setUp() {
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(
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 
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 ],
178  [ AuthManager::ACTION_CHANGE, $arr, true ],
180  [ AuthManager::ACTION_REMOVE, $arr, true ],
182  ];
183  }
184 
185  public function testAuthentication() {
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(
198  $provider->beginPrimaryAuthentication( [] )
199  );
200 
201  $req->username = 'foo';
202  $req->password = null;
203  $this->assertEquals(
205  $provider->beginPrimaryAuthentication( $reqs )
206  );
207 
208  $req->username = null;
209  $req->password = 'bar';
210  $this->assertEquals(
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(
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(
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(
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(
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 
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 
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 
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  }
481  $req->username = 'UTSysop';
482  $req->password = 'Pa$$w0Rd!!!';
483  $req->retype = 'Pa$$w0Rd!!!';
484  $this->assertEquals( $expect, $provider->providerAllowsAuthenticationDataChange( $req ) );
485  }
486 
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' ) ],
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 
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 
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 
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 [
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(
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 
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(
642  $provider->beginPrimaryAccountCreation( $user, $user, [] )
643  );
644 
645  $req->username = 'foo';
646  $req->password = null;
647  $this->assertEquals(
649  $provider->beginPrimaryAccountCreation( $user, $user, $reqs )
650  );
651 
652  $req->username = null;
653  $req->password = 'bar';
654  $this->assertEquals(
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(
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 }
static newFromName($name, $validate= 'valid')
Static factory method for creation from username.
Definition: User.php:522
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
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:189
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException'returning false will NOT prevent logging $e
Definition: hooks.txt:1980
static newFatal($message)
Factory function for fatal errors.
Definition: StatusValue.php:63
testProviderAllowsAuthenticationDataChange($type, $allow, $expect)
provideProviderAllowsAuthenticationDataChange
AuthManager MediaWiki\Auth\AuthPluginPrimaryAuthenticationProvider.
this hook is for auditing only $response
Definition: hooks.txt:776
when a variable name is used in a it is silently declared as a new local masking the global
Definition: design.txt:93
testGetAuthenticationRequests($action, $response, $allowPasswordChange)
provideGetAuthenticationRequests
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:1816
Backwards-compatibility wrapper for AuthManager via $wgAuth.
const FAIL
Indicates that the authentication failed.
Primary authentication provider wrapper for AuthPlugin.
An error page which can definitely be safely rendered using the OutputPage.
const ACTION_CHANGE
Change a user's credentials.
Definition: AuthManager.php:60
static newGood($value=null)
Factory function for good results.
Definition: StatusValue.php:76
static run($event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:131
const TYPE_NONE
Provider cannot create or link to accounts.
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:1816
const ACTION_LINK
Link an existing user to a third-party account.
Definition: AuthManager.php:55
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:242
This is a value object for authentication requests with a username and password.
String $action
Cache what action this request is.
Definition: MediaWiki.php:42
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:35
this hook is for auditing only $req
Definition: hooks.txt:981
msg($key, $fallback)
Get a message from i18n.
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:52
const ACTION_REMOVE
Remove a user's credentials.
Definition: AuthManager.php:62
$wgDisableAuthManager
Disable AuthManager.
const ACTION_CREATE
Create a new user.
Definition: AuthManager.php:50
</td >< td > &</td >< td > t want your writing to be edited mercilessly and redistributed at will
const ACTION_LOGIN
Log in with an existing (not necessarily local) user.
Definition: AuthManager.php:45
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached one of or reset my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled allows for interception of redirect as a string mapping parameter names to values & $type
Definition: hooks.txt:2376