6 use Wikimedia\TestingAccessWrapper;
29 if ( !$this->config ) {
30 $this->config = new \HashConfig();
37 if ( !$this->manager ) {
43 ->setMethods( [
'checkPasswordValidity' ] )
44 ->setConstructorArgs( [ [
'loginOnly' => $loginOnly ] ] )
46 $provider->expects( $this->
any() )->method(
'checkPasswordValidity' )
47 ->will( $this->returnCallback(
function () {
50 $provider->setConfig(
$config );
51 $provider->setLogger(
new \Psr\Log\NullLogger() );
52 $provider->setManager( $this->manager );
59 $userName =
$user->getName();
60 $lowerInitialUserName = mb_strtolower( $userName[0] ) . substr( $userName, 1 );
66 $provider->accountCreationType()
69 $this->assertTrue( $provider->testUserExists( $userName ) );
70 $this->assertTrue( $provider->testUserExists( $lowerInitialUserName ) );
71 $this->assertFalse( $provider->testUserExists(
'DoesNotExist' ) );
72 $this->assertFalse( $provider->testUserExists(
'<invalid>' ) );
78 $provider->accountCreationType()
81 $this->assertTrue( $provider->testUserExists( $userName ) );
82 $this->assertFalse( $provider->testUserExists(
'DoesNotExist' ) );
86 $req->username =
'<invalid>';
87 $provider->providerChangeAuthenticationData(
$req );
92 $userName =
$user->getName();
97 $this->assertFalse( $provider->testUserCanAuthenticate(
'<invalid>' ) );
99 $this->assertFalse( $provider->testUserCanAuthenticate(
'DoesNotExist' ) );
101 $this->assertTrue( $provider->testUserCanAuthenticate( $userName ) );
102 $lowerInitialUserName = mb_strtolower( $userName[0] ) . substr( $userName, 1 );
103 $this->assertTrue( $provider->testUserCanAuthenticate( $lowerInitialUserName ) );
108 [
'user_name' => $userName ]
110 $this->assertFalse( $provider->testUserCanAuthenticate( $userName ) );
115 [
'user_password' =>
'0123456789abcdef0123456789abcdef' ],
116 [
'user_name' => $userName ]
118 $this->assertTrue( $provider->testUserCanAuthenticate( $userName ) );
126 $this->
setMwGlobals( [
'wgPasswordExpireGrace' => 100 ] );
128 $this->config->set(
'PasswordExpireGrace', 100 );
129 $this->config->set(
'InvalidPasswordReset',
true );
132 $provider->setConfig( $this->config );
133 $provider->setLogger(
new \Psr\Log\NullLogger() );
134 $provider->setManager( $this->manager );
135 $providerPriv = TestingAccessWrapper::newFromObject( $provider );
138 $userName =
$user->getName();
140 $row = $dbw->selectRow(
143 [
'user_name' => $userName ],
147 $this->manager->removeAuthenticationSessionData(
null );
148 $row->user_password_expires =
wfTimestamp( TS_MW, time() + 200 );
149 $providerPriv->setPasswordResetFlag( $userName, \
Status::newGood(), $row );
150 $this->assertNull( $this->manager->getAuthenticationSessionData(
'reset-pass' ) );
152 $this->manager->removeAuthenticationSessionData(
null );
153 $row->user_password_expires =
wfTimestamp( TS_MW, time() - 200 );
154 $providerPriv->setPasswordResetFlag( $userName, \
Status::newGood(), $row );
155 $ret = $this->manager->getAuthenticationSessionData(
'reset-pass' );
156 $this->assertNotNull(
$ret );
157 $this->assertSame(
'resetpass-expired',
$ret->msg->getKey() );
158 $this->assertTrue(
$ret->hard );
160 $this->manager->removeAuthenticationSessionData(
null );
161 $row->user_password_expires =
wfTimestamp( TS_MW, time() - 1 );
162 $providerPriv->setPasswordResetFlag( $userName, \
Status::newGood(), $row );
163 $ret = $this->manager->getAuthenticationSessionData(
'reset-pass' );
164 $this->assertNotNull(
$ret );
165 $this->assertSame(
'resetpass-expired-soft',
$ret->msg->getKey() );
166 $this->assertFalse(
$ret->hard );
168 $this->manager->removeAuthenticationSessionData(
null );
169 $row->user_password_expires =
null;
172 $providerPriv->setPasswordResetFlag( $userName,
$status, $row );
173 $ret = $this->manager->getAuthenticationSessionData(
'reset-pass' );
174 $this->assertNotNull(
$ret );
175 $this->assertSame(
'resetpass-validity-soft',
$ret->msg->getKey() );
176 $this->assertFalse(
$ret->hard );
181 $userName = $testUser->getUser()->getName();
195 $provider->beginPrimaryAuthentication( [] )
198 $req->username =
'foo';
199 $req->password =
null;
202 $provider->beginPrimaryAuthentication( $reqs )
205 $req->username =
null;
206 $req->password =
'bar';
209 $provider->beginPrimaryAuthentication( $reqs )
212 $req->username =
'<invalid>';
213 $req->password =
'WhoCares';
214 $ret = $provider->beginPrimaryAuthentication( $reqs );
217 $provider->beginPrimaryAuthentication( $reqs )
220 $req->username =
'DoesNotExist';
221 $req->password =
'DoesNotExist';
222 $ret = $provider->beginPrimaryAuthentication( $reqs );
229 $ret->message->getKey()
233 $req->username = $userName;
234 $req->password = $testUser->getPassword();
236 $ret = $provider->beginPrimaryAuthentication( $reqs );
243 $ret->message->getKey()
247 $this->manager->removeAuthenticationSessionData(
null );
251 $provider->beginPrimaryAuthentication( $reqs )
253 $this->assertNull( $this->manager->getAuthenticationSessionData(
'reset-pass' ) );
256 $this->manager->removeAuthenticationSessionData(
null );
258 $req->username = mb_strtolower( $userName[0] ) . substr( $userName, 1 );
261 $provider->beginPrimaryAuthentication( $reqs )
263 $this->assertNull( $this->manager->getAuthenticationSessionData(
'reset-pass' ) );
264 $req->username = $userName;
267 $this->manager->removeAuthenticationSessionData(
null );
268 $this->validity->error(
'arbitrary-warning' );
271 $provider->beginPrimaryAuthentication( $reqs )
273 $this->assertNotNull( $this->manager->getAuthenticationSessionData(
'reset-pass' ) );
277 $req->password =
'Wrong';
278 $ret = $provider->beginPrimaryAuthentication( $reqs );
285 $ret->message->getKey()
289 $password =
':B:salt:' . md5(
'salt-' . md5(
"\xe1\xe9\xed\xf3\xfa" ) );
290 $dbw->update(
'user', [
'user_password' => $password ], [
'user_name' => $userName ] );
291 $req->password =
'áéíóú';
292 $ret = $provider->beginPrimaryAuthentication( $reqs );
299 $ret->message->getKey()
302 $this->config->set(
'LegacyEncoding',
true );
305 $provider->beginPrimaryAuthentication( $reqs )
308 $req->password =
'áéíóú Wrong';
309 $ret = $provider->beginPrimaryAuthentication( $reqs );
316 $ret->message->getKey()
320 $this->config->set(
'PasswordSalt',
false );
321 $password = md5(
'FooBar' );
322 $dbw->update(
'user', [
'user_password' => $password ], [
'user_name' => $userName ] );
323 $req->password =
'FooBar';
326 $provider->beginPrimaryAuthentication( $reqs )
329 $this->config->set(
'PasswordSalt',
true );
330 $password = md5(
"$id-" . md5(
'FooBar' ) );
331 $dbw->update(
'user', [
'user_password' => $password ], [
'user_name' => $userName ] );
332 $req->password =
'FooBar';
335 $provider->beginPrimaryAuthentication( $reqs )
359 $req->password =
'NewPassword';
360 $req->retype =
'NewPassword';
364 $this->assertEquals( $expect1, $provider->providerAllowsAuthenticationDataChange(
$req,
false ) );
365 $this->assertEquals( $expect2, $provider->providerAllowsAuthenticationDataChange(
$req,
true ) );
367 $req->retype =
'BadRetype';
370 $provider->providerAllowsAuthenticationDataChange(
$req,
false )
374 $provider->providerAllowsAuthenticationDataChange(
$req,
true )
380 $provider->providerAllowsAuthenticationDataChange(
$req,
true ),
381 'loginOnly mode should claim to ignore all changes'
387 $err->error(
'arbitrary-warning' );
415 $usernameTransform,
$type, $loginOnly, $changed ) {
417 $user = $testUser->getUser()->getName();
418 if ( is_callable( $usernameTransform ) ) {
419 $user = call_user_func( $usernameTransform,
$user );
421 $cuser = ucfirst(
$user );
422 $oldpass = $testUser->getPassword();
423 $newpass =
'NewPassword';
426 $oldExpiry = $dbw->selectField(
'user',
'user_password_expires', [
'user_name' => $cuser ] );
429 'ResetPasswordExpiration' => [
function (
$user, &$expires ) {
430 $expires =
'30001231235959';
439 $loginReq->username =
$user;
440 $loginReq->password = $oldpass;
444 $provider->beginPrimaryAuthentication( $loginReqs ),
449 $changeReq =
new $type();
451 $changeReq = $this->createMock(
$type );
454 $changeReq->username =
$user;
455 $changeReq->password = $newpass;
456 $provider->providerChangeAuthenticationData( $changeReq );
458 if ( $loginOnly && $changed ) {
461 $expectExpiry =
null;
462 } elseif ( $changed ) {
465 $expectExpiry =
'30001231235959';
469 $expectExpiry = $oldExpiry;
472 $loginReq->password = $oldpass;
473 $ret = $provider->beginPrimaryAuthentication( $loginReqs );
474 if ( $old ===
'pass' ) {
478 'old password should pass'
484 'old password should fail'
488 $ret->message->getKey(),
489 'old password should fail'
493 $loginReq->password = $newpass;
494 $ret = $provider->beginPrimaryAuthentication( $loginReqs );
495 if ( $new ===
'pass' ) {
499 'new password should pass'
505 'new password should fail'
509 $ret->message->getKey(),
510 'new password should fail'
518 $dbw->selectField(
'user',
'user_password_expires', [
'user_name' => $cuser ] )
538 $req->username =
'Foo';
539 $req->password =
'Bar';
540 $req->retype =
'Bar';
546 $provider->testForAccountCreation(
$user,
$user, [] ),
547 'No password request'
552 $provider->testForAccountCreation(
$user,
$user, $reqs ),
553 'Password request, validated'
556 $req->retype =
'Baz';
559 $provider->testForAccountCreation(
$user,
$user, $reqs ),
560 'Password request, bad retype'
562 $req->retype =
'Bar';
564 $this->validity->error(
'arbitrary warning' );
566 $expect->error(
'arbitrary warning' );
569 $provider->testForAccountCreation(
$user,
$user, $reqs ),
570 'Password request, not validated'
574 $this->validity->error(
'arbitrary warning' );
577 $provider->testForAccountCreation(
$user,
$user, $reqs ),
578 'Password request, not validated, loginOnly'
591 $provider->beginPrimaryAccountCreation(
$user,
$user, [] );
592 $this->fail(
'Expected exception was not thrown' );
593 }
catch ( \BadMethodCallException $ex ) {
595 'Shouldn\'t call this when accountCreationType() is NONE', $ex->getMessage()
601 $this->fail(
'Expected exception was not thrown' );
602 }
catch ( \BadMethodCallException $ex ) {
604 'Shouldn\'t call this when accountCreationType() is NONE', $ex->getMessage()
612 $provider->beginPrimaryAccountCreation(
$user,
$user, [] )
615 $req->username =
'foo';
616 $req->password =
null;
619 $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs )
622 $req->username =
null;
623 $req->password =
'bar';
626 $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs )
629 $req->username =
'foo';
630 $req->password =
'bar';
633 $expect->createRequest = clone
$req;
634 $expect->createRequest->username =
'Foo';
635 $this->assertEquals( $expect, $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs ) );
643 $req->password =
'NewPassword';
645 $expect->createRequest =
$req;
647 $res2 = $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs );
648 $this->assertEquals( $expect, $res2,
'Sanity check' );
650 $ret = $provider->beginPrimaryAuthentication( $reqs );
653 $this->assertNull( $provider->finishAccountCreation(
$user,
$user, $res2 ) );
654 $ret = $provider->beginPrimaryAuthentication( $reqs );