3 namespace MediaWiki\Auth
;
7 * @covers MediaWiki\Auth\ResetPasswordSecondaryAuthenticationProvider
9 class ResetPasswordSecondaryAuthenticationProviderTest
extends \MediaWikiTestCase
{
10 protected function setUp() {
11 global $wgDisableAuthManager;
14 if ( $wgDisableAuthManager ) {
15 $this->markTestSkipped( '$wgDisableAuthManager is set' );
20 * @dataProvider provideGetAuthenticationRequests
21 * @param string $action
22 * @param array $response
24 public function testGetAuthenticationRequests( $action, $response ) {
25 $provider = new ResetPasswordSecondaryAuthenticationProvider();
27 $this->assertEquals( $response, $provider->getAuthenticationRequests( $action, [] ) );
30 public static function provideGetAuthenticationRequests() {
32 [ AuthManager
::ACTION_LOGIN
, [] ],
33 [ AuthManager
::ACTION_CREATE
, [] ],
34 [ AuthManager
::ACTION_LINK
, [] ],
35 [ AuthManager
::ACTION_CHANGE
, [] ],
36 [ AuthManager
::ACTION_REMOVE
, [] ],
40 public function testBasics() {
41 $user = \User
::newFromName( 'UTSysop' );
44 $reqs = [ new \stdClass
];
46 $mb = $this->getMockBuilder( ResetPasswordSecondaryAuthenticationProvider
::class )
47 ->setMethods( [ 'tryReset' ] );
50 'beginSecondaryAuthentication' => [ $user, $reqs ],
51 'continueSecondaryAuthentication' => [ $user, $reqs ],
52 'beginSecondaryAccountCreation' => [ $user, $user2, $reqs ],
53 'continueSecondaryAccountCreation' => [ $user, $user2, $reqs ],
55 foreach ( $methods as $method => $args ) {
56 $mock = $mb->getMock();
57 $mock->expects( $this->once() )->method( 'tryReset' )
58 ->with( $this->identicalTo( $user ), $this->identicalTo( $reqs ) )
59 ->will( $this->returnValue( $obj ) );
60 $this->assertSame( $obj, call_user_func_array( [ $mock, $method ], $args ) );
64 public function testTryReset() {
65 $user = \User
::newFromName( 'UTSysop' );
67 $provider = $this->getMockBuilder(
68 ResetPasswordSecondaryAuthenticationProvider
::class
71 'providerAllowsAuthenticationDataChange', 'providerChangeAuthenticationData'
74 $provider->expects( $this->any() )->method( 'providerAllowsAuthenticationDataChange' )
75 ->will( $this->returnCallback( function ( $req ) {
76 $this->assertSame( 'UTSysop', $req->username
);
79 $provider->expects( $this->any() )->method( 'providerChangeAuthenticationData' )
80 ->will( $this->returnCallback( function ( $req ) {
81 $this->assertSame( 'UTSysop', $req->username
);
84 $config = new \
HashConfig( [
85 'AuthManagerConfig' => [
89 [ 'factory' => function () use ( $provider ) {
95 $manager = new AuthManager( new \FauxRequest
, $config );
96 $provider->setManager( $manager );
97 $provider = \TestingAccessWrapper
::newFromObject( $provider );
99 $msg = wfMessage( 'foo' );
100 $skipReq = new ButtonAuthenticationRequest(
102 wfMessage( 'authprovider-resetpass-skip-label' ),
103 wfMessage( 'authprovider-resetpass-skip-help' )
105 $passReq = new PasswordAuthenticationRequest();
106 $passReq->action
= AuthManager
::ACTION_CHANGE
;
107 $passReq->password
= 'Foo';
108 $passReq->retype
= 'Bar';
109 $passReq->allow
= \StatusValue
::newGood();
110 $passReq->done
= false;
112 $passReq2 = $this->getMockBuilder( PasswordAuthenticationRequest
::class )
113 ->enableProxyingToOriginalMethods()
115 $passReq2->action
= AuthManager
::ACTION_CHANGE
;
116 $passReq2->password
= 'Foo';
117 $passReq2->retype
= 'Foo';
118 $passReq2->allow
= \StatusValue
::newGood();
119 $passReq2->done
= false;
121 $passReq3 = new PasswordAuthenticationRequest();
122 $passReq3->action
= AuthManager
::ACTION_LOGIN
;
123 $passReq3->password
= 'Foo';
124 $passReq3->retype
= 'Foo';
125 $passReq3->allow
= \StatusValue
::newGood();
126 $passReq3->done
= false;
129 AuthenticationResponse
::newAbstain(),
130 $provider->tryReset( $user, [] )
133 $manager->setAuthenticationSessionData( 'reset-pass', 'foo' );
135 $provider->tryReset( $user, [] );
136 $this->fail( 'Expected exception not thrown' );
137 } catch ( \UnexpectedValueException
$ex ) {
138 $this->assertSame( 'reset-pass is not valid', $ex->getMessage() );
141 $manager->setAuthenticationSessionData( 'reset-pass', (object)[] );
143 $provider->tryReset( $user, [] );
144 $this->fail( 'Expected exception not thrown' );
145 } catch ( \UnexpectedValueException
$ex ) {
146 $this->assertSame( 'reset-pass msg is missing', $ex->getMessage() );
149 $manager->setAuthenticationSessionData( 'reset-pass', [
153 $provider->tryReset( $user, [] );
154 $this->fail( 'Expected exception not thrown' );
155 } catch ( \UnexpectedValueException
$ex ) {
156 $this->assertSame( 'reset-pass msg is not valid', $ex->getMessage() );
159 $manager->setAuthenticationSessionData( 'reset-pass', [
163 $provider->tryReset( $user, [] );
164 $this->fail( 'Expected exception not thrown' );
165 } catch ( \UnexpectedValueException
$ex ) {
166 $this->assertSame( 'reset-pass hard is missing', $ex->getMessage() );
169 $manager->setAuthenticationSessionData( 'reset-pass', [
175 $provider->tryReset( $user, [] );
176 $this->fail( 'Expected exception not thrown' );
177 } catch ( \UnexpectedValueException
$ex ) {
178 $this->assertSame( 'reset-pass req is not valid', $ex->getMessage() );
181 $manager->setAuthenticationSessionData( 'reset-pass', [
187 $provider->tryReset( $user, [ $passReq ] );
188 $this->fail( 'Expected exception not thrown' );
189 } catch ( \UnexpectedValueException
$ex ) {
190 $this->assertSame( 'reset-pass req is not valid', $ex->getMessage() );
193 $manager->setAuthenticationSessionData( 'reset-pass', [
197 $res = $provider->tryReset( $user, [] );
198 $this->assertInstanceOf( AuthenticationResponse
::class, $res );
199 $this->assertSame( AuthenticationResponse
::UI
, $res->status
);
200 $this->assertEquals( $msg, $res->message
);
201 $this->assertCount( 1, $res->neededRequests
);
202 $this->assertInstanceOf(
203 PasswordAuthenticationRequest
::class,
204 $res->neededRequests
[0]
206 $this->assertNotNull( $manager->getAuthenticationSessionData( 'reset-pass' ) );
207 $this->assertFalse( $passReq->done
);
209 $manager->setAuthenticationSessionData( 'reset-pass', [
214 $res = $provider->tryReset( $user, [] );
215 $this->assertInstanceOf( AuthenticationResponse
::class, $res );
216 $this->assertSame( AuthenticationResponse
::UI
, $res->status
);
217 $this->assertEquals( $msg, $res->message
);
218 $this->assertCount( 2, $res->neededRequests
);
219 $this->assertEquals( $passReq, $res->neededRequests
[0] );
220 $this->assertEquals( $skipReq, $res->neededRequests
[1] );
221 $this->assertNotNull( $manager->getAuthenticationSessionData( 'reset-pass' ) );
222 $this->assertFalse( $passReq->done
);
224 $passReq->retype
= 'Bad';
225 $manager->setAuthenticationSessionData( 'reset-pass', [
230 $res = $provider->tryReset( $user, [ $skipReq, $passReq ] );
231 $this->assertEquals( AuthenticationResponse
::newPass(), $res );
232 $this->assertNull( $manager->getAuthenticationSessionData( 'reset-pass' ) );
233 $this->assertFalse( $passReq->done
);
235 $passReq->retype
= 'Bad';
236 $manager->setAuthenticationSessionData( 'reset-pass', [
240 $res = $provider->tryReset( $user, [ $skipReq, $passReq ] );
241 $this->assertSame( AuthenticationResponse
::UI
, $res->status
);
242 $this->assertSame( 'badretype', $res->message
->getKey() );
243 $this->assertCount( 1, $res->neededRequests
);
244 $this->assertInstanceOf(
245 PasswordAuthenticationRequest
::class,
246 $res->neededRequests
[0]
248 $this->assertNotNull( $manager->getAuthenticationSessionData( 'reset-pass' ) );
249 $this->assertFalse( $passReq->done
);
251 $manager->setAuthenticationSessionData( 'reset-pass', [
255 $res = $provider->tryReset( $user, [ $skipReq, $passReq3 ] );
256 $this->assertSame( AuthenticationResponse
::UI
, $res->status
);
257 $this->assertEquals( $msg, $res->message
);
258 $this->assertCount( 1, $res->neededRequests
);
259 $this->assertInstanceOf(
260 PasswordAuthenticationRequest
::class,
261 $res->neededRequests
[0]
263 $this->assertNotNull( $manager->getAuthenticationSessionData( 'reset-pass' ) );
264 $this->assertFalse( $passReq->done
);
266 $passReq->retype
= $passReq->password
;
267 $passReq->allow
= \StatusValue
::newFatal( 'arbitrary-fail' );
268 $res = $provider->tryReset( $user, [ $skipReq, $passReq ] );
269 $this->assertSame( AuthenticationResponse
::UI
, $res->status
);
270 $this->assertSame( 'arbitrary-fail', $res->message
->getKey() );
271 $this->assertCount( 1, $res->neededRequests
);
272 $this->assertInstanceOf(
273 PasswordAuthenticationRequest
::class,
274 $res->neededRequests
[0]
276 $this->assertNotNull( $manager->getAuthenticationSessionData( 'reset-pass' ) );
277 $this->assertFalse( $passReq->done
);
279 $passReq->allow
= \StatusValue
::newGood();
280 $res = $provider->tryReset( $user, [ $skipReq, $passReq ] );
281 $this->assertEquals( AuthenticationResponse
::newPass(), $res );
282 $this->assertNull( $manager->getAuthenticationSessionData( 'reset-pass' ) );
283 $this->assertTrue( $passReq->done
);
285 $manager->setAuthenticationSessionData( 'reset-pass', [
290 $res = $provider->tryReset( $user, [ $passReq2 ] );
291 $this->assertEquals( AuthenticationResponse
::newPass(), $res );
292 $this->assertNull( $manager->getAuthenticationSessionData( 'reset-pass' ) );
293 $this->assertTrue( $passReq2->done
);
295 $passReq->done
= false;
296 $passReq2->done
= false;
297 $manager->setAuthenticationSessionData( 'reset-pass', [
302 $res = $provider->tryReset( $user, [ $passReq ] );
303 $this->assertInstanceOf( AuthenticationResponse
::class, $res );
304 $this->assertSame( AuthenticationResponse
::UI
, $res->status
);
305 $this->assertEquals( $msg, $res->message
);
306 $this->assertCount( 2, $res->neededRequests
);
307 $this->assertEquals( $passReq2, $res->neededRequests
[0] );
308 $this->assertEquals( $skipReq, $res->neededRequests
[1] );
309 $this->assertNotNull( $manager->getAuthenticationSessionData( 'reset-pass' ) );
310 $this->assertFalse( $passReq->done
);
311 $this->assertFalse( $passReq2->done
);