MediaWiki  1.30.0
AuthPluginPrimaryAuthenticationProviderTest.php
Go to the documentation of this file.
1 <?php
2 
3 namespace 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' );
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' );
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' );
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' ] ] );
77  }
78 
79  public function testOnUserLoggedIn() {
80  $user = \User::newFromName( 'UTSysop' );
81 
82  $plugin = $this->createMock( 'AuthPlugin' );
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' );
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' );
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' );
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' );
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' );
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 ],
169  [ AuthManager::ACTION_CHANGE, $arr, true ],
171  [ AuthManager::ACTION_REMOVE, $arr, true ],
173  ];
174  }
175 
176  public function testAuthentication() {
180 
181  $plugin = $this->getMockBuilder( 'AuthPlugin' )
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' )
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' )
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' )
236  ->setMethods( [ 'isLocked' ] )
237  ->disableOriginalConstructor()
238  ->getMock();
239  $pluginUser->expects( $this->once() )->method( 'isLocked' )
240  ->will( $this->returnValue( true ) );
241  $plugin = $this->getMockBuilder( 'AuthPlugin' )
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' )
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' )
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' )
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' )
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' );
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' );
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' );
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' )
354  ->disableOriginalConstructor()
355  ->getMock();
356  $pluginUser->expects( $this->once() )->method( 'isLocked' )
357  ->will( $this->returnValue( true ) );
358  $plugin = $this->createMock( 'AuthPlugin' );
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', $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' )
374  ->disableOriginalConstructor()
375  ->getMock();
376  $pluginUser->expects( $this->once() )->method( 'isLocked' )
377  ->will( $this->returnValue( false ) );
378  $plugin = $this->createMock( 'AuthPlugin' );
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', $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' )
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' )
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' );
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' );
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' ) ],
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' );
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' );
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' );
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' );
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' );
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' );
592  $plugin->expects( $this->any() )->method( 'domainList' )->willReturn( [] );
593  $provider = new AuthPluginPrimaryAuthenticationProvider( $plugin );
594  $this->assertEquals(
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 
608 
609  $plugin = $this->createMock( 'AuthPlugin' );
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' );
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' );
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' );
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' );
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 }
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\provideProviderAllowsAuthenticationDataChange
static provideProviderAllowsAuthenticationDataChange()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:478
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\provideGetAuthenticationRequests
static provideGetAuthenticationRequests()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:160
$user
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 account $user
Definition: hooks.txt:244
MediaWiki\Auth\PrimaryAuthenticationProvider\TYPE_CREATE
const TYPE_CREATE
Provider can create accounts.
Definition: PrimaryAuthenticationProvider.php:77
MediaWiki\$action
String $action
Cache what action this request is.
Definition: MediaWiki.php:47
MediaWiki\Auth\PrimaryAuthenticationProvider\TYPE_NONE
const TYPE_NONE
Provider cannot create or link to accounts.
Definition: PrimaryAuthenticationProvider.php:81
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testTestUserCanAuthenticate
testTestUserCanAuthenticate()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:343
MediaWiki\Auth\AuthManagerAuthPlugin
Backwards-compatibility wrapper for AuthManager via $wgAuth.
Definition: AuthManagerAuthPlugin.php:30
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest
AuthManager MediaWiki\Auth\AuthPluginPrimaryAuthenticationProvider.
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:9
use
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:10
$req
this hook is for auditing only $req
Definition: hooks.txt:988
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testTestUserExists
testTestUserExists()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:323
StatusValue\newFatal
static newFatal( $message)
Factory function for fatal errors.
Definition: StatusValue.php:68
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:550
User
User
Definition: All_system_messages.txt:425
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testProviderAllowsAuthenticationDataChange
testProviderAllowsAuthenticationDataChange( $type, $allow, $expect)
provideProviderAllowsAuthenticationDataChange
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:454
MediaWiki\Auth\PasswordDomainAuthenticationRequest
This is a value object for authentication requests with a username, password, and domain.
Definition: PasswordDomainAuthenticationRequest.php:29
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testOnUserSaveSettings
testOnUserSaveSettings()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:51
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProvider
Primary authentication provider wrapper for AuthPlugin.
Definition: AuthPluginPrimaryAuthenticationProvider.php:36
php
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
MediaWiki\Auth\AuthenticationResponse\newAbstain
static newAbstain()
Definition: AuthenticationResponse.php:170
MediaWiki\Auth\PasswordAuthenticationRequest
This is a value object for authentication requests with a username and password.
Definition: PasswordAuthenticationRequest.php:29
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testProviderRevokeAccessForUser
testProviderRevokeAccessForUser()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:394
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\provideAccountCreationType
static provideAccountCreationType()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:581
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testAccountCreation
testAccountCreation()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:600
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testOnUserLoggedIn
testOnUserLoggedIn()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:79
MediaWikiTestCase
Definition: MediaWikiTestCase.php:15
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testGetAuthenticationRequests
testGetAuthenticationRequests( $action, $response, $allowPasswordChange)
provideGetAuthenticationRequests
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:151
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testConstruction
testConstruction()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:10
MediaWiki\Auth\AuthenticationResponse\FAIL
const FAIL
Indicates that the authentication failed.
Definition: AuthenticationResponse.php:42
list
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
will
</td >< td > &</td >< td > t want your writing to be edited mercilessly and redistributed at will
Definition: All_system_messages.txt:914
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testProviderAllowsPropertyChange
testProviderAllowsPropertyChange()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:435
any
they could even be mouse clicks or menu items whatever suits your program You should also get your if any
Definition: COPYING.txt:326
MediaWiki\Auth\AuthManager\ACTION_CREATE
const ACTION_CREATE
Create a new user.
Definition: AuthManager.php:89
$e
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2141
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:81
MediaWiki\Auth\AuthManager\ACTION_CHANGE
const ACTION_CHANGE
Change a user's credentials.
Definition: AuthManager.php:99
$ret
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:1965
MediaWiki\Auth\AuthManager\ACTION_LINK
const ACTION_LINK
Link an existing user to a third-party account.
Definition: AuthManager.php:94
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testGetUniqueId
testGetUniqueId()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:135
$response
this hook is for auditing only $response
Definition: hooks.txt:781
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testAuthentication
testAuthentication()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:176
MediaWiki\Auth\AuthManager\ACTION_REMOVE
const ACTION_REMOVE
Remove a user's credentials.
Definition: AuthManager.php:101
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testTestForAccountCreation
testTestForAccountCreation()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:588
MediaWiki\Auth\AuthManager\ACTION_LOGIN
const ACTION_LOGIN
Log in with an existing (not necessarily local) user.
Definition: AuthManager.php:84
true
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:1965
class
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
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testAccountCreationType
testAccountCreationType( $can, $expect)
provideAccountCreationType
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:571
ErrorPageError
An error page which can definitely be safely rendered using the OutputPage.
Definition: ErrorPageError.php:27
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testProviderChangeAuthenticationData
testProviderChangeAuthenticationData()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:504
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:203
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testOnUserGroupsChanged
testOnUserGroupsChanged()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:63
MediaWiki\Auth
Definition: AbstractAuthenticationProvider.php:22
MediaWiki\Auth\AuthenticationResponse\newPass
static newPass( $username=null)
Definition: AuthenticationResponse.php:134
MediaWiki\Auth\AuthPluginPrimaryAuthenticationProviderTest\testOnLocalUserCreated
testOnLocalUserCreated()
Definition: AuthPluginPrimaryAuthenticationProviderTest.php:107
$type
$type
Definition: testCompression.php:48