Merge "Update docs/hooks.txt for ShowSearchHitTitle"
[mediawiki.git] / tests / phpunit / includes / auth / AbstractPasswordPrimaryAuthenticationProviderTest.php
bloba57682b66ea3e77889927e3c64ccda0b8f508b10
1 <?php
3 namespace MediaWiki\Auth;
5 use MediaWiki\MediaWikiServices;
7 /**
8 * @group AuthManager
9 * @covers MediaWiki\Auth\AbstractPasswordPrimaryAuthenticationProvider
11 class AbstractPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase {
12 public function testConstructor() {
13 $provider = $this->getMockForAbstractClass(
14 AbstractPasswordPrimaryAuthenticationProvider::class
16 $providerPriv = \TestingAccessWrapper::newFromObject( $provider );
17 $this->assertTrue( $providerPriv->authoritative );
19 $provider = $this->getMockForAbstractClass(
20 AbstractPasswordPrimaryAuthenticationProvider::class,
21 [ [ 'authoritative' => false ] ]
23 $providerPriv = \TestingAccessWrapper::newFromObject( $provider );
24 $this->assertFalse( $providerPriv->authoritative );
27 public function testGetPasswordFactory() {
28 $provider = $this->getMockForAbstractClass(
29 AbstractPasswordPrimaryAuthenticationProvider::class
31 $provider->setConfig( MediaWikiServices::getInstance()->getMainConfig() );
32 $providerPriv = \TestingAccessWrapper::newFromObject( $provider );
34 $obj = $providerPriv->getPasswordFactory();
35 $this->assertInstanceOf( 'PasswordFactory', $obj );
36 $this->assertSame( $obj, $providerPriv->getPasswordFactory() );
39 public function testGetPassword() {
40 $provider = $this->getMockForAbstractClass(
41 AbstractPasswordPrimaryAuthenticationProvider::class
43 $provider->setConfig( MediaWikiServices::getInstance()->getMainConfig() );
44 $provider->setLogger( new \Psr\Log\NullLogger() );
45 $providerPriv = \TestingAccessWrapper::newFromObject( $provider );
47 $obj = $providerPriv->getPassword( null );
48 $this->assertInstanceOf( 'Password', $obj );
50 $obj = $providerPriv->getPassword( 'invalid' );
51 $this->assertInstanceOf( 'Password', $obj );
54 public function testGetNewPasswordExpiry() {
55 $config = new \HashConfig;
56 $provider = $this->getMockForAbstractClass(
57 AbstractPasswordPrimaryAuthenticationProvider::class
59 $provider->setConfig( new \MultiConfig( [
60 $config,
61 MediaWikiServices::getInstance()->getMainConfig()
62 ] ) );
63 $provider->setLogger( new \Psr\Log\NullLogger() );
64 $providerPriv = \TestingAccessWrapper::newFromObject( $provider );
66 $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'ResetPasswordExpiration' => [] ] );
68 $config->set( 'PasswordExpirationDays', 0 );
69 $this->assertNull( $providerPriv->getNewPasswordExpiry( 'UTSysop' ) );
71 $config->set( 'PasswordExpirationDays', 5 );
72 $this->assertEquals(
73 time() + 5 * 86400,
74 wfTimestamp( TS_UNIX, $providerPriv->getNewPasswordExpiry( 'UTSysop' ) ),
75 '',
76 2 /* Fuzz */
79 $this->mergeMwGlobalArrayValue( 'wgHooks', [
80 'ResetPasswordExpiration' => [ function ( $user, &$expires ) {
81 $this->assertSame( 'UTSysop', $user->getName() );
82 $expires = '30001231235959';
83 } ]
84 ] );
85 $this->assertEquals( '30001231235959', $providerPriv->getNewPasswordExpiry( 'UTSysop' ) );
88 public function testCheckPasswordValidity() {
89 $uppCalled = 0;
90 $uppStatus = \Status::newGood();
91 $this->setMwGlobals( [
92 'wgPasswordPolicy' => [
93 'policies' => [
94 'default' => [
95 'Check' => true,
98 'checks' => [
99 'Check' => function () use ( &$uppCalled, &$uppStatus ) {
100 $uppCalled++;
101 return $uppStatus;
105 ] );
107 $provider = $this->getMockForAbstractClass(
108 AbstractPasswordPrimaryAuthenticationProvider::class
110 $provider->setConfig( MediaWikiServices::getInstance()->getMainConfig() );
111 $provider->setLogger( new \Psr\Log\NullLogger() );
112 $providerPriv = \TestingAccessWrapper::newFromObject( $provider );
114 $this->assertEquals( $uppStatus, $providerPriv->checkPasswordValidity( 'foo', 'bar' ) );
116 $uppStatus->fatal( 'arbitrary-warning' );
117 $this->assertEquals( $uppStatus, $providerPriv->checkPasswordValidity( 'foo', 'bar' ) );
120 public function testSetPasswordResetFlag() {
121 $config = new \HashConfig( [
122 'InvalidPasswordReset' => true,
123 ] );
125 $manager = new AuthManager(
126 new \FauxRequest(),
127 MediaWikiServices::getInstance()->getMainConfig()
130 $provider = $this->getMockForAbstractClass(
131 AbstractPasswordPrimaryAuthenticationProvider::class
133 $provider->setConfig( $config );
134 $provider->setLogger( new \Psr\Log\NullLogger() );
135 $provider->setManager( $manager );
136 $providerPriv = \TestingAccessWrapper::newFromObject( $provider );
138 $manager->removeAuthenticationSessionData( null );
139 $status = \Status::newGood();
140 $providerPriv->setPasswordResetFlag( 'Foo', $status );
141 $this->assertNull( $manager->getAuthenticationSessionData( 'reset-pass' ) );
143 $manager->removeAuthenticationSessionData( null );
144 $status = \Status::newGood();
145 $status->error( 'testing' );
146 $providerPriv->setPasswordResetFlag( 'Foo', $status );
147 $ret = $manager->getAuthenticationSessionData( 'reset-pass' );
148 $this->assertNotNull( $ret );
149 $this->assertSame( 'resetpass-validity-soft', $ret->msg->getKey() );
150 $this->assertFalse( $ret->hard );
152 $config->set( 'InvalidPasswordReset', false );
153 $manager->removeAuthenticationSessionData( null );
154 $providerPriv->setPasswordResetFlag( 'Foo', $status );
155 $ret = $manager->getAuthenticationSessionData( 'reset-pass' );
156 $this->assertNull( $ret );
159 public function testFailResponse() {
160 $provider = $this->getMockForAbstractClass(
161 AbstractPasswordPrimaryAuthenticationProvider::class,
162 [ [ 'authoritative' => false ] ]
164 $providerPriv = \TestingAccessWrapper::newFromObject( $provider );
166 $req = new PasswordAuthenticationRequest;
168 $ret = $providerPriv->failResponse( $req );
169 $this->assertSame( AuthenticationResponse::ABSTAIN, $ret->status );
171 $provider = $this->getMockForAbstractClass(
172 AbstractPasswordPrimaryAuthenticationProvider::class,
173 [ [ 'authoritative' => true ] ]
175 $providerPriv = \TestingAccessWrapper::newFromObject( $provider );
177 $req->password = '';
178 $ret = $providerPriv->failResponse( $req );
179 $this->assertSame( AuthenticationResponse::FAIL, $ret->status );
180 $this->assertSame( 'wrongpasswordempty', $ret->message->getKey() );
182 $req->password = 'X';
183 $ret = $providerPriv->failResponse( $req );
184 $this->assertSame( AuthenticationResponse::FAIL, $ret->status );
185 $this->assertSame( 'wrongpassword', $ret->message->getKey() );
189 * @dataProvider provideGetAuthenticationRequests
190 * @param string $action
191 * @param array $response
193 public function testGetAuthenticationRequests( $action, $response ) {
194 $provider = $this->getMockForAbstractClass(
195 AbstractPasswordPrimaryAuthenticationProvider::class
198 $this->assertEquals( $response, $provider->getAuthenticationRequests( $action, [] ) );
201 public static function provideGetAuthenticationRequests() {
202 return [
203 [ AuthManager::ACTION_LOGIN, [ new PasswordAuthenticationRequest() ] ],
204 [ AuthManager::ACTION_CREATE, [ new PasswordAuthenticationRequest() ] ],
205 [ AuthManager::ACTION_LINK, [] ],
206 [ AuthManager::ACTION_CHANGE, [ new PasswordAuthenticationRequest() ] ],
207 [ AuthManager::ACTION_REMOVE, [ new PasswordAuthenticationRequest() ] ],
211 public function testProviderRevokeAccessForUser() {
212 $req = new PasswordAuthenticationRequest;
213 $req->action = AuthManager::ACTION_REMOVE;
214 $req->username = 'foo';
215 $req->password = null;
217 $provider = $this->getMockForAbstractClass(
218 AbstractPasswordPrimaryAuthenticationProvider::class
220 $provider->expects( $this->once() )
221 ->method( 'providerChangeAuthenticationData' )
222 ->with( $this->equalTo( $req ) );
224 $provider->providerRevokeAccessForUser( 'foo' );