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 );
225 $provider->beginPrimaryAuthentication( $reqs )
229 $req->username = $userName;
230 $req->password = $testUser->getPassword();
232 $ret = $provider->beginPrimaryAuthentication( $reqs );
239 $ret->message->getKey()
243 $this->manager->removeAuthenticationSessionData(
null );
247 $provider->beginPrimaryAuthentication( $reqs )
249 $this->assertNull( $this->manager->getAuthenticationSessionData(
'reset-pass' ) );
252 $this->manager->removeAuthenticationSessionData(
null );
254 $req->username = mb_strtolower( $userName[0] ) . substr( $userName, 1 );
257 $provider->beginPrimaryAuthentication( $reqs )
259 $this->assertNull( $this->manager->getAuthenticationSessionData(
'reset-pass' ) );
260 $req->username = $userName;
263 $this->manager->removeAuthenticationSessionData(
null );
264 $this->validity->error(
'arbitrary-warning' );
267 $provider->beginPrimaryAuthentication( $reqs )
269 $this->assertNotNull( $this->manager->getAuthenticationSessionData(
'reset-pass' ) );
273 $req->password =
'Wrong';
274 $ret = $provider->beginPrimaryAuthentication( $reqs );
281 $ret->message->getKey()
285 $password =
':B:salt:' . md5(
'salt-' . md5(
"\xe1\xe9\xed\xf3\xfa" ) );
286 $dbw->update(
'user', [
'user_password' => $password ], [
'user_name' => $userName ] );
287 $req->password =
'áéíóú';
288 $ret = $provider->beginPrimaryAuthentication( $reqs );
295 $ret->message->getKey()
298 $this->config->set(
'LegacyEncoding',
true );
301 $provider->beginPrimaryAuthentication( $reqs )
304 $req->password =
'áéíóú Wrong';
305 $ret = $provider->beginPrimaryAuthentication( $reqs );
312 $ret->message->getKey()
316 $this->config->set(
'PasswordSalt',
false );
317 $password = md5(
'FooBar' );
318 $dbw->update(
'user', [
'user_password' => $password ], [
'user_name' => $userName ] );
319 $req->password =
'FooBar';
322 $provider->beginPrimaryAuthentication( $reqs )
325 $this->config->set(
'PasswordSalt',
true );
326 $password = md5(
"$id-" . md5(
'FooBar' ) );
327 $dbw->update(
'user', [
'user_password' => $password ], [
'user_name' => $userName ] );
328 $req->password =
'FooBar';
331 $provider->beginPrimaryAuthentication( $reqs )
355 $req->password =
'NewPassword';
356 $req->retype =
'NewPassword';
360 $this->assertEquals( $expect1, $provider->providerAllowsAuthenticationDataChange(
$req,
false ) );
361 $this->assertEquals( $expect2, $provider->providerAllowsAuthenticationDataChange(
$req,
true ) );
363 $req->retype =
'BadRetype';
366 $provider->providerAllowsAuthenticationDataChange(
$req,
false )
370 $provider->providerAllowsAuthenticationDataChange(
$req,
true )
376 $provider->providerAllowsAuthenticationDataChange(
$req,
true ),
377 'loginOnly mode should claim to ignore all changes'
383 $err->error(
'arbitrary-warning' );
411 $usernameTransform,
$type, $loginOnly, $changed ) {
413 $user = $testUser->getUser()->getName();
414 if ( is_callable( $usernameTransform ) ) {
415 $user = call_user_func( $usernameTransform,
$user );
417 $cuser = ucfirst(
$user );
418 $oldpass = $testUser->getPassword();
419 $newpass =
'NewPassword';
422 $oldExpiry = $dbw->selectField(
'user',
'user_password_expires', [
'user_name' => $cuser ] );
425 'ResetPasswordExpiration' => [
function (
$user, &$expires ) {
426 $expires =
'30001231235959';
435 $loginReq->username =
$user;
436 $loginReq->password = $oldpass;
440 $provider->beginPrimaryAuthentication( $loginReqs ),
445 $changeReq =
new $type();
447 $changeReq = $this->createMock(
$type );
450 $changeReq->username =
$user;
451 $changeReq->password = $newpass;
452 $provider->providerChangeAuthenticationData( $changeReq );
454 if ( $loginOnly && $changed ) {
457 $expectExpiry =
null;
458 } elseif ( $changed ) {
461 $expectExpiry =
'30001231235959';
465 $expectExpiry = $oldExpiry;
468 $loginReq->password = $oldpass;
469 $ret = $provider->beginPrimaryAuthentication( $loginReqs );
470 if ( $old ===
'pass' ) {
474 'old password should pass'
480 'old password should fail'
484 $ret->message->getKey(),
485 'old password should fail'
489 $loginReq->password = $newpass;
490 $ret = $provider->beginPrimaryAuthentication( $loginReqs );
491 if ( $new ===
'pass' ) {
495 'new password should pass'
501 'new password should fail'
505 $ret->message->getKey(),
506 'new password should fail'
512 $dbw->selectField(
'user',
'user_password_expires', [
'user_name' => $cuser ] )
531 $req->username =
'Foo';
532 $req->password =
'Bar';
533 $req->retype =
'Bar';
539 $provider->testForAccountCreation(
$user,
$user, [] ),
540 'No password request'
545 $provider->testForAccountCreation(
$user,
$user, $reqs ),
546 'Password request, validated'
549 $req->retype =
'Baz';
552 $provider->testForAccountCreation(
$user,
$user, $reqs ),
553 'Password request, bad retype'
555 $req->retype =
'Bar';
557 $this->validity->error(
'arbitrary warning' );
559 $expect->error(
'arbitrary warning' );
562 $provider->testForAccountCreation(
$user,
$user, $reqs ),
563 'Password request, not validated'
567 $this->validity->error(
'arbitrary warning' );
570 $provider->testForAccountCreation(
$user,
$user, $reqs ),
571 'Password request, not validated, loginOnly'
584 $provider->beginPrimaryAccountCreation(
$user,
$user, [] );
585 $this->fail(
'Expected exception was not thrown' );
586 }
catch ( \BadMethodCallException $ex ) {
588 'Shouldn\'t call this when accountCreationType() is NONE', $ex->getMessage()
594 $this->fail(
'Expected exception was not thrown' );
595 }
catch ( \BadMethodCallException $ex ) {
597 'Shouldn\'t call this when accountCreationType() is NONE', $ex->getMessage()
605 $provider->beginPrimaryAccountCreation(
$user,
$user, [] )
608 $req->username =
'foo';
609 $req->password =
null;
612 $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs )
615 $req->username =
null;
616 $req->password =
'bar';
619 $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs )
622 $req->username =
'foo';
623 $req->password =
'bar';
626 $expect->createRequest = clone(
$req );
627 $expect->createRequest->username =
'Foo';
628 $this->assertEquals( $expect, $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs ) );
636 $req->password =
'NewPassword';
638 $expect->createRequest =
$req;
640 $res2 = $provider->beginPrimaryAccountCreation(
$user,
$user, $reqs );
641 $this->assertEquals( $expect, $res2,
'Sanity check' );
643 $ret = $provider->beginPrimaryAuthentication( $reqs );
646 $this->assertNull( $provider->finishAccountCreation(
$user,
$user, $res2 ) );
647 $ret = $provider->beginPrimaryAuthentication( $reqs );