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 );
132 $passwordFactory = new \PasswordFactory();
135 $passwordFactory->setDefaultType(
'A' );
136 $pwhash = $passwordFactory->newFromPlaintext(
'password' )->toString();
139 $providerPriv = TestingAccessWrapper::newFromObject( $provider );
141 $this->assertFalse( $provider->testUserCanAuthenticate(
'<invalid>' ) );
142 $this->assertFalse( $provider->testUserCanAuthenticate(
'DoesNotExist' ) );
148 'user_newpass_time' =>
null,
150 [
'user_id' =>
$user->getId() ]
152 $this->assertFalse( $provider->testUserCanAuthenticate(
$user->getName() ) );
157 'user_newpassword' => $pwhash,
158 'user_newpass_time' =>
null,
160 [
'user_id' =>
$user->getId() ]
162 $this->assertTrue( $provider->testUserCanAuthenticate(
$user->getName() ) );
163 $this->assertTrue( $provider->testUserCanAuthenticate( lcfirst(
$user->getName() ) ) );
168 'user_newpassword' => $pwhash,
169 'user_newpass_time' => $dbw->timestamp( time() - 10 ),
171 [
'user_id' =>
$user->getId() ]
173 $providerPriv->newPasswordExpiry = 100;
174 $this->assertTrue( $provider->testUserCanAuthenticate(
$user->getName() ) );
175 $providerPriv->newPasswordExpiry = 1;
176 $this->assertFalse( $provider->testUserCanAuthenticate(
$user->getName() ) );
182 'user_newpass_time' =>
null,
184 [
'user_id' =>
$user->getId() ]
196 foreach ( $actual
as $req ) {
198 $req->password =
'random';
201 $this->assertEquals( $expected, $actual );
205 $anon = [
'username' => null ];
206 $loggedIn = [
'username' =>
'UTSysop' ];
239 $password =
'TemporaryPassword';
240 $hash =
':A:' . md5( $password );
244 [
'user_newpassword' => $hash,
'user_newpass_time' => $dbw->timestamp( time() - 10 ) ],
245 [
'user_id' =>
$user->getId() ]
253 $providerPriv = TestingAccessWrapper::newFromObject( $provider );
255 $providerPriv->newPasswordExpiry = 100;
260 $provider->beginPrimaryAuthentication( [] )
263 $req->username =
'foo';
264 $req->password =
null;
267 $provider->beginPrimaryAuthentication( $reqs )
270 $req->username =
null;
271 $req->password =
'bar';
274 $provider->beginPrimaryAuthentication( $reqs )
277 $req->username =
'<invalid>';
278 $req->password =
'WhoCares';
279 $ret = $provider->beginPrimaryAuthentication( $reqs );
282 $provider->beginPrimaryAuthentication( $reqs )
285 $req->username =
'DoesNotExist';
286 $req->password =
'DoesNotExist';
287 $ret = $provider->beginPrimaryAuthentication( $reqs );
290 $provider->beginPrimaryAuthentication( $reqs )
295 $req->password = $password;
297 $ret = $provider->beginPrimaryAuthentication( $reqs );
304 $ret->message->getKey()
308 $this->manager->removeAuthenticationSessionData(
null );
312 $provider->beginPrimaryAuthentication( $reqs )
314 $this->assertNotNull( $this->manager->getAuthenticationSessionData(
'reset-pass' ) );
316 $this->manager->removeAuthenticationSessionData(
null );
318 $req->username = lcfirst(
$user->getName() );
321 $provider->beginPrimaryAuthentication( $reqs )
323 $this->assertNotNull( $this->manager->getAuthenticationSessionData(
'reset-pass' ) );
327 $providerPriv->newPasswordExpiry = 1;
328 $ret = $provider->beginPrimaryAuthentication( $reqs );
335 $ret->message->getKey()
339 $providerPriv->newPasswordExpiry = 100;
341 $req->password =
'Wrong';
342 $ret = $provider->beginPrimaryAuthentication( $reqs );
349 $ret->message->getKey()
373 $req->password =
'NewPassword';
377 $this->assertEquals( $expect1, $provider->providerAllowsAuthenticationDataChange(
$req,
false ) );
378 $this->assertEquals( $expect2, $provider->providerAllowsAuthenticationDataChange(
$req,
true ) );
383 $err->error(
'arbitrary-warning' );
413 $cuser = ucfirst(
$user );
414 $oldpass =
'OldTempPassword';
415 $newpass =
'NewTempPassword';
418 $oldHash = $dbw->selectField(
'user',
'user_newpassword', [
'user_name' => $cuser ] );
419 $cb =
new ScopedCallback(
function ()
use ( $dbw, $cuser, $oldHash ) {
420 $dbw->update(
'user', [
'user_newpassword' => $oldHash ], [
'user_name' => $cuser ] );
423 $hash =
':A:' . md5( $oldpass );
426 [
'user_newpassword' => $hash,
'user_newpass_time' => $dbw->timestamp( time() + 10 ) ],
427 [
'user_name' => $cuser ]
435 $loginReq->username =
$user;
436 $loginReq->password = $oldpass;
440 $provider->beginPrimaryAuthentication( $loginReqs ),
447 $changeReq =
new $type();
449 $changeReq = $this->createMock(
$type );
452 $changeReq->username =
$user;
453 $changeReq->password = $newpass;
455 $provider->providerChangeAuthenticationData( $changeReq );
456 ScopedCallback::consume( $resetMailer );
458 $loginReq->password = $oldpass;
459 $ret = $provider->beginPrimaryAuthentication( $loginReqs );
463 'old password should fail'
467 $ret->message->getKey(),
468 'old password should fail'
471 $loginReq->password = $newpass;
472 $ret = $provider->beginPrimaryAuthentication( $loginReqs );
477 'new password should pass'
479 $this->assertNotNull(
480 $dbw->selectField(
'user',
'user_newpass_time', [
'user_name' => $cuser ] )
486 'new password should fail'
490 $ret->message->getKey(),
491 'new password should fail'
494 $dbw->selectField(
'user',
'user_newpass_time', [
'user_name' => $cuser ] )
513 [
'user_newpass_time' => $dbw->timestamp( time() - 5 * 3600 ) ],
514 [
'user_id' =>
$user->getId() ]
519 $req->mailpassword =
true;
521 $provider = $this->
getProvider( [
'emailEnabled' =>
false ] );
522 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
525 $provider = $this->
getProvider( [
'passwordReminderResendTime' => 10 ] );
526 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
529 $provider = $this->
getProvider( [
'passwordReminderResendTime' => 3 ] );
530 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
531 $this->assertFalse(
$status->hasMessage(
'throttled-mailpassword' ) );
535 [
'user_newpass_time' => $dbw->timestamp( time() + 5 * 3600 ) ],
536 [
'user_id' =>
$user->getId() ]
538 $provider = $this->
getProvider( [
'passwordReminderResendTime' => 0 ] );
539 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
540 $this->assertFalse(
$status->hasMessage(
'throttled-mailpassword' ) );
543 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
546 $req->caller =
'127.0.0.256';
547 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
551 $req->caller =
'<Invalid>';
552 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
556 $req->caller =
'127.0.0.1';
557 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
561 $status = $provider->providerAllowsAuthenticationDataChange(
$req,
true );
565 $resetMailer = $this->
hookMailer(
function ( $headers, $to, $from, $subject, $body )
569 $this->assertSame(
$user->getEmail(), $to[0]->address );
570 $this->assertContains(
$req->password, $body );
573 $provider->providerChangeAuthenticationData(
$req );
574 ScopedCallback::consume( $resetMailer );
575 $this->assertTrue( $mailed );
577 $priv = TestingAccessWrapper::newFromObject( $provider );
578 $req->username =
'<invalid>';
586 $req->username =
'Foo';
587 $req->password =
'Bar';
593 $provider->testForAccountCreation(
$user,
$user, [] ),
594 'No password request'
599 $provider->testForAccountCreation(
$user,
$user, $reqs ),
600 'Password request, validated'
603 $this->validity->error(
'arbitrary warning' );
605 $expect->error(
'arbitrary warning' );
608 $provider->testForAccountCreation(
$user,
$user, $reqs ),
609 'Password request, not validated'
629 $provider->beginPrimaryAccountCreation(
$user,
$user, [] )
632 $req->username =
'foo';
633 $req->password =
null;
636 $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs )
639 $req->username =
null;
640 $req->password =
'bar';
643 $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs )
646 $req->username =
'foo';
647 $req->password =
'bar';
650 $expect->createRequest = clone
$req;
651 $expect->createRequest->username =
'Foo';
652 $this->assertEquals( $expect, $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs ) );
653 $this->assertNull( $this->manager->getAuthenticationSessionData(
'no-email' ) );
656 $req->username = $authreq->username =
$user->getName();
657 $req->password = $authreq->password =
'NewPassword';
659 $expect->createRequest =
$req;
661 $res2 = $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs );
662 $this->assertEquals( $expect, $res2,
'Sanity check' );
664 $ret = $provider->beginPrimaryAuthentication( $authreqs );
667 $this->assertSame(
null, $provider->finishAccountCreation(
$user,
$user, $res2 ) );
669 $ret = $provider->beginPrimaryAuthentication( $authreqs );
677 $user->setEmail(
null );
681 $req->mailpassword =
true;
683 $provider = $this->
getProvider( [
'emailEnabled' =>
false ] );
687 $provider = $this->
getProvider( [
'emailEnabled' =>
true ] );
691 $user->setEmail(
'test@localhost.localdomain' );
696 $resetMailer = $this->
hookMailer(
function ( $headers, $to, $from, $subject, $body )
700 $this->assertSame(
'test@localhost.localdomain', $to[0]->address );
701 $this->assertContains(
$req->password, $body );
706 $expect->createRequest = clone
$req;
707 $expect->createRequest->username =
$user->getName();
708 $res = $provider->beginPrimaryAccountCreation(
$user, $creator, [
$req ] );
709 $this->assertEquals( $expect,
$res );
710 $this->assertTrue( $this->manager->getAuthenticationSessionData(
'no-email' ) );
711 $this->assertFalse( $mailed );
713 $this->assertSame(
'byemail', $provider->finishAccountCreation(
$user, $creator,
$res ) );
714 $this->assertTrue( $mailed );
716 ScopedCallback::consume( $resetMailer );
717 $this->assertTrue( $mailed );