6 use Wikimedia\ScopedCallback;
7 use Wikimedia\TestingAccessWrapper;
30 if ( !$this->config ) {
31 $this->config = new \HashConfig( [
32 'EmailEnabled' =>
true,
40 if ( !$this->manager ) {
45 $mockedMethods[] =
'checkPasswordValidity';
47 ->setMethods( $mockedMethods )
48 ->setConstructorArgs( [
$params ] )
50 $provider->expects( $this->
any() )->method(
'checkPasswordValidity' )
51 ->will( $this->returnCallback(
function () {
54 $provider->setConfig(
$config );
55 $provider->setLogger(
new \Psr\Log\NullLogger() );
56 $provider->setManager( $this->manager );
71 $this->fail(
'AlternateUserMailer hook called unexpectedly' );
76 return new ScopedCallback(
function () {
89 $provider->accountCreationType()
92 $this->assertTrue( $provider->testUserExists(
'UTSysop' ) );
93 $this->assertTrue( $provider->testUserExists(
'uTSysop' ) );
94 $this->assertFalse( $provider->testUserExists(
'DoesNotExist' ) );
95 $this->assertFalse( $provider->testUserExists(
'<invalid>' ) );
99 $req->username =
'<invalid>';
100 $provider->providerChangeAuthenticationData(
$req );
105 'EnableEmail' =>
false,
106 'NewPasswordExpiry' => 100,
107 'PasswordReminderResendTime' => 101,
112 $this->assertSame(
false, $p->emailEnabled );
113 $this->assertSame( 100, $p->newPasswordExpiry );
114 $this->assertSame( 101, $p->passwordReminderResendTime );
117 'emailEnabled' =>
true,
118 'newPasswordExpiry' => 42,
119 'passwordReminderResendTime' => 43,
122 $this->assertSame(
true, $p->emailEnabled );
123 $this->assertSame( 42, $p->newPasswordExpiry );
124 $this->assertSame( 43, $p->passwordReminderResendTime );
133 $passwordFactory = new \PasswordFactory(
$config->get(
'PasswordConfig' ),
'A' );
135 $pwhash = $passwordFactory->newFromPlaintext(
'password' )->toString();
138 $providerPriv = TestingAccessWrapper::newFromObject( $provider );
140 $this->assertFalse( $provider->testUserCanAuthenticate(
'<invalid>' ) );
141 $this->assertFalse( $provider->testUserCanAuthenticate(
'DoesNotExist' ) );
147 'user_newpass_time' =>
null,
149 [
'user_id' =>
$user->getId() ]
151 $this->assertFalse( $provider->testUserCanAuthenticate(
$user->getName() ) );
156 'user_newpassword' => $pwhash,
157 'user_newpass_time' =>
null,
159 [
'user_id' =>
$user->getId() ]
161 $this->assertTrue( $provider->testUserCanAuthenticate(
$user->getName() ) );
162 $this->assertTrue( $provider->testUserCanAuthenticate( lcfirst(
$user->getName() ) ) );
167 'user_newpassword' => $pwhash,
168 'user_newpass_time' => $dbw->timestamp( time() - 10 ),
170 [
'user_id' =>
$user->getId() ]
172 $providerPriv->newPasswordExpiry = 100;
173 $this->assertTrue( $provider->testUserCanAuthenticate(
$user->getName() ) );
174 $providerPriv->newPasswordExpiry = 1;
175 $this->assertFalse( $provider->testUserCanAuthenticate(
$user->getName() ) );
181 'user_newpass_time' =>
null,
183 [
'user_id' =>
$user->getId() ]
195 foreach ( $actual
as $req ) {
197 $req->password =
'random';
200 $this->assertEquals( $expected, $actual );
204 $anon = [
'username' =>
null ];
205 $loggedIn = [
'username' =>
'UTSysop' ];
238 $password =
'TemporaryPassword';
239 $hash =
':A:' . md5( $password );
243 [
'user_newpassword' => $hash,
'user_newpass_time' => $dbw->timestamp( time() - 10 ) ],
244 [
'user_id' =>
$user->getId() ]
252 $providerPriv = TestingAccessWrapper::newFromObject( $provider );
254 $providerPriv->newPasswordExpiry = 100;
259 $provider->beginPrimaryAuthentication( [] )
262 $req->username =
'foo';
263 $req->password =
null;
266 $provider->beginPrimaryAuthentication( $reqs )
269 $req->username =
null;
270 $req->password =
'bar';
273 $provider->beginPrimaryAuthentication( $reqs )
276 $req->username =
'<invalid>';
277 $req->password =
'WhoCares';
278 $ret = $provider->beginPrimaryAuthentication( $reqs );
281 $provider->beginPrimaryAuthentication( $reqs )
284 $req->username =
'DoesNotExist';
285 $req->password =
'DoesNotExist';
286 $ret = $provider->beginPrimaryAuthentication( $reqs );
289 $provider->beginPrimaryAuthentication( $reqs )
294 $req->password = $password;
296 $ret = $provider->beginPrimaryAuthentication( $reqs );
303 $ret->message->getKey()
307 $this->manager->removeAuthenticationSessionData(
null );
311 $provider->beginPrimaryAuthentication( $reqs )
313 $this->assertNotNull( $this->manager->getAuthenticationSessionData(
'reset-pass' ) );
315 $this->manager->removeAuthenticationSessionData(
null );
317 $req->username = lcfirst(
$user->getName() );
320 $provider->beginPrimaryAuthentication( $reqs )
322 $this->assertNotNull( $this->manager->getAuthenticationSessionData(
'reset-pass' ) );
326 $providerPriv->newPasswordExpiry = 1;
327 $ret = $provider->beginPrimaryAuthentication( $reqs );
334 $ret->message->getKey()
338 $providerPriv->newPasswordExpiry = 100;
340 $req->password =
'Wrong';
341 $ret = $provider->beginPrimaryAuthentication( $reqs );
348 $ret->message->getKey()
372 $req->password =
'NewPassword';
376 $this->assertEquals( $expect1, $provider->providerAllowsAuthenticationDataChange(
$req,
false ) );
377 $this->assertEquals( $expect2, $provider->providerAllowsAuthenticationDataChange(
$req,
true ) );
382 $err->error(
'arbitrary-warning' );
412 $cuser = ucfirst(
$user );
413 $oldpass =
'OldTempPassword';
414 $newpass =
'NewTempPassword';
417 $oldHash = $dbw->selectField(
'user',
'user_newpassword', [
'user_name' => $cuser ] );
418 $cb =
new ScopedCallback(
function ()
use ( $dbw, $cuser, $oldHash ) {
419 $dbw->update(
'user', [
'user_newpassword' => $oldHash ], [
'user_name' => $cuser ] );
422 $hash =
':A:' . md5( $oldpass );
425 [
'user_newpassword' => $hash,
'user_newpass_time' => $dbw->timestamp( time() + 10 ) ],
426 [
'user_name' => $cuser ]
434 $loginReq->username =
$user;
435 $loginReq->password = $oldpass;
439 $provider->beginPrimaryAuthentication( $loginReqs ),
446 $changeReq =
new $type();
448 $changeReq = $this->createMock(
$type );
451 $changeReq->username =
$user;
452 $changeReq->password = $newpass;
454 $provider->providerChangeAuthenticationData( $changeReq );
455 ScopedCallback::consume( $resetMailer );
457 $loginReq->password = $oldpass;
458 $ret = $provider->beginPrimaryAuthentication( $loginReqs );
462 'old password should fail'
466 $ret->message->getKey(),
467 'old password should fail'
470 $loginReq->password = $newpass;
471 $ret = $provider->beginPrimaryAuthentication( $loginReqs );
476 'new password should pass'
478 $this->assertNotNull(
479 $dbw->selectField(
'user',
'user_newpass_time', [
'user_name' => $cuser ] )
485 'new password should fail'
489 $ret->message->getKey(),
490 'new password should fail'
493 $dbw->selectField(
'user',
'user_newpass_time', [
'user_name' => $cuser ] )
512 [
'user_newpass_time' => $dbw->timestamp( time() - 5 * 3600 ) ],
513 [
'user_id' =>
$user->getId() ]
518 $req->mailpassword =
true;
520 $provider = $this->
getProvider( [
'emailEnabled' =>
false ] );
521 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
524 $provider = $this->
getProvider( [
'passwordReminderResendTime' => 10 ] );
525 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
528 $provider = $this->
getProvider( [
'passwordReminderResendTime' => 3 ] );
529 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
530 $this->assertFalse(
$status->hasMessage(
'throttled-mailpassword' ) );
534 [
'user_newpass_time' => $dbw->timestamp( time() + 5 * 3600 ) ],
535 [
'user_id' =>
$user->getId() ]
537 $provider = $this->
getProvider( [
'passwordReminderResendTime' => 0 ] );
538 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
539 $this->assertFalse(
$status->hasMessage(
'throttled-mailpassword' ) );
542 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
545 $req->caller =
'127.0.0.256';
546 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
550 $req->caller =
'<Invalid>';
551 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
555 $req->caller =
'127.0.0.1';
556 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
560 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
564 $resetMailer = $this->
hookMailer(
function ( $headers, $to, $from, $subject, $body )
568 $this->assertSame(
$user->getEmail(), $to[0]->address );
569 $this->assertContains(
$req->password, $body );
572 $provider->providerChangeAuthenticationData(
$req );
573 ScopedCallback::consume( $resetMailer );
574 $this->assertTrue( $mailed );
576 $priv = TestingAccessWrapper::newFromObject( $provider );
577 $req->username =
'<invalid>';
585 $req->username =
'Foo';
586 $req->password =
'Bar';
592 $provider->testForAccountCreation(
$user,
$user, [] ),
593 'No password request'
598 $provider->testForAccountCreation(
$user,
$user, $reqs ),
599 'Password request, validated'
602 $this->validity->error(
'arbitrary warning' );
604 $expect->error(
'arbitrary warning' );
607 $provider->testForAccountCreation(
$user,
$user, $reqs ),
608 'Password request, not validated'
628 $provider->beginPrimaryAccountCreation(
$user,
$user, [] )
631 $req->username =
'foo';
632 $req->password =
null;
635 $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs )
638 $req->username =
null;
639 $req->password =
'bar';
642 $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs )
645 $req->username =
'foo';
646 $req->password =
'bar';
649 $expect->createRequest = clone
$req;
650 $expect->createRequest->username =
'Foo';
651 $this->assertEquals( $expect, $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs ) );
652 $this->assertNull( $this->manager->getAuthenticationSessionData(
'no-email' ) );
655 $req->username = $authreq->username =
$user->getName();
656 $req->password = $authreq->password =
'NewPassword';
658 $expect->createRequest =
$req;
660 $res2 = $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs );
661 $this->assertEquals( $expect, $res2,
'Sanity check' );
663 $ret = $provider->beginPrimaryAuthentication( $authreqs );
666 $this->assertSame(
null, $provider->finishAccountCreation(
$user,
$user, $res2 ) );
668 $ret = $provider->beginPrimaryAuthentication( $authreqs );
676 $user->setEmail(
null );
680 $req->mailpassword =
true;
682 $provider = $this->
getProvider( [
'emailEnabled' =>
false ] );
686 $provider = $this->
getProvider( [
'emailEnabled' =>
true ] );
690 $user->setEmail(
'test@localhost.localdomain' );
695 $resetMailer = $this->
hookMailer(
function ( $headers, $to, $from, $subject, $body )
699 $this->assertSame(
'test@localhost.localdomain', $to[0]->address );
700 $this->assertContains(
$req->password, $body );
705 $expect->createRequest = clone
$req;
706 $expect->createRequest->username =
$user->getName();
707 $res = $provider->beginPrimaryAccountCreation(
$user, $creator, [
$req ] );
708 $this->assertEquals( $expect,
$res );
709 $this->assertTrue( $this->manager->getAuthenticationSessionData(
'no-email' ) );
710 $this->assertFalse( $mailed );
712 $this->assertSame(
'byemail', $provider->finishAccountCreation(
$user, $creator,
$res ) );
713 $this->assertTrue( $mailed );
715 ScopedCallback::consume( $resetMailer );
716 $this->assertTrue( $mailed );