3 use MediaWiki\Auth\AuthManager
;
4 use MediaWiki\Block\DatabaseBlock
;
5 use MediaWiki\Block\SystemBlock
;
8 * @covers PasswordReset
11 class PasswordResetTest
extends MediaWikiTestCase
{
13 * @dataProvider provideIsAllowed
15 public function testIsAllowed( $passwordResetRoutes, $enableEmail,
16 $allowsAuthenticationDataChange, $canEditPrivate, $block, $globalBlock, $isAllowed
18 $config = new HashConfig( [
19 'PasswordResetRoutes' => $passwordResetRoutes,
20 'EnableEmail' => $enableEmail,
23 $authManager = $this->getMockBuilder( AuthManager
::class )->disableOriginalConstructor()
25 $authManager->expects( $this->any() )->method( 'allowsAuthenticationDataChange' )
26 ->willReturn( $allowsAuthenticationDataChange ? Status
::newGood() : Status
::newFatal( 'foo' ) );
28 $user = $this->getMockBuilder( User
::class )->getMock();
29 $user->expects( $this->any() )->method( 'getName' )->willReturn( 'Foo' );
30 $user->expects( $this->any() )->method( 'getBlock' )->willReturn( $block );
31 $user->expects( $this->any() )->method( 'getGlobalBlock' )->willReturn( $globalBlock );
32 $user->expects( $this->any() )->method( 'isAllowed' )
33 ->will( $this->returnCallback( function ( $perm ) use ( $canEditPrivate ) {
34 if ( $perm === 'editmyprivateinfo' ) {
35 return $canEditPrivate;
37 $this->fail( 'Unexpected permission check' );
41 $passwordReset = new PasswordReset( $config, $authManager );
43 $this->assertSame( $isAllowed, $passwordReset->isAllowed( $user )->isGood() );
46 public function provideIsAllowed() {
49 'passwordResetRoutes' => [],
50 'enableEmail' => true,
51 'allowsAuthenticationDataChange' => true,
52 'canEditPrivate' => true,
54 'globalBlock' => null,
58 'passwordResetRoutes' => [ 'username' => true ],
59 'enableEmail' => false,
60 'allowsAuthenticationDataChange' => true,
61 'canEditPrivate' => true,
63 'globalBlock' => null,
66 'auth data change disabled' => [
67 'passwordResetRoutes' => [ 'username' => true ],
68 'enableEmail' => true,
69 'allowsAuthenticationDataChange' => false,
70 'canEditPrivate' => true,
72 'globalBlock' => null,
75 'cannot edit private data' => [
76 'passwordResetRoutes' => [ 'username' => true ],
77 'enableEmail' => true,
78 'allowsAuthenticationDataChange' => true,
79 'canEditPrivate' => false,
81 'globalBlock' => null,
84 'blocked with account creation disabled' => [
85 'passwordResetRoutes' => [ 'username' => true ],
86 'enableEmail' => true,
87 'allowsAuthenticationDataChange' => true,
88 'canEditPrivate' => true,
89 'block' => new DatabaseBlock( [ 'createAccount' => true ] ),
90 'globalBlock' => null,
93 'blocked w/o account creation disabled' => [
94 'passwordResetRoutes' => [ 'username' => true ],
95 'enableEmail' => true,
96 'allowsAuthenticationDataChange' => true,
97 'canEditPrivate' => true,
98 'block' => new DatabaseBlock( [] ),
99 'globalBlock' => null,
102 'using blocked proxy' => [
103 'passwordResetRoutes' => [ 'username' => true ],
104 'enableEmail' => true,
105 'allowsAuthenticationDataChange' => true,
106 'canEditPrivate' => true,
107 'block' => new SystemBlock(
108 [ 'systemBlock' => 'proxy' ]
110 'globalBlock' => null,
111 'isAllowed' => false,
113 'globally blocked with account creation not disabled' => [
114 'passwordResetRoutes' => [ 'username' => true ],
115 'enableEmail' => true,
116 'allowsAuthenticationDataChange' => true,
117 'canEditPrivate' => true,
119 'globalBlock' => new SystemBlock(
120 [ 'systemBlock' => 'global-block' ]
124 'blocked via wgSoftBlockRanges' => [
125 'passwordResetRoutes' => [ 'username' => true ],
126 'enableEmail' => true,
127 'allowsAuthenticationDataChange' => true,
128 'canEditPrivate' => true,
129 'block' => new SystemBlock(
130 [ 'systemBlock' => 'wgSoftBlockRanges', 'anonOnly' => true ]
132 'globalBlock' => null,
135 'blocked with an unknown system block type' => [
136 'passwordResetRoutes' => [ 'username' => true ],
137 'enableEmail' => true,
138 'allowsAuthenticationDataChange' => true,
139 'canEditPrivate' => true,
140 'block' => new SystemBlock( [ 'systemBlock' => 'unknown' ] ),
141 'globalBlock' => null,
142 'isAllowed' => false,
145 'passwordResetRoutes' => [ 'username' => true ],
146 'enableEmail' => true,
147 'allowsAuthenticationDataChange' => true,
148 'canEditPrivate' => true,
150 'globalBlock' => null,
156 public function testExecute_email() {
157 $config = new HashConfig( [
158 'PasswordResetRoutes' => [ 'username' => true, 'email' => true ],
159 'EnableEmail' => true,
162 // Unregister the hooks for proper unit testing
163 $this->mergeMwGlobalArrayValue( 'wgHooks', [
164 'User::mailPasswordInternal' => [],
165 'SpecialPasswordResetOnSubmit' => [],
168 $authManager = $this->getMockBuilder( AuthManager
::class )->disableOriginalConstructor()
170 $authManager->expects( $this->any() )->method( 'allowsAuthenticationDataChange' )
171 ->willReturn( Status
::newGood() );
172 $authManager->expects( $this->exactly( 2 ) )->method( 'changeAuthenticationData' );
174 $request = new FauxRequest();
175 $request->setIP( '1.2.3.4' );
176 $performingUser = $this->getMockBuilder( User
::class )->getMock();
177 $performingUser->expects( $this->any() )->method( 'getRequest' )->willReturn( $request );
178 $performingUser->expects( $this->any() )->method( 'isAllowed' )->willReturn( true );
179 $performingUser->expects( $this->any() )->method( 'getName' )->willReturn( 'Performer' );
181 $targetUser1 = $this->getMockBuilder( User
::class )->getMock();
182 $targetUser2 = $this->getMockBuilder( User
::class )->getMock();
183 $targetUser1->expects( $this->any() )->method( 'getName' )->willReturn( 'User1' );
184 $targetUser2->expects( $this->any() )->method( 'getName' )->willReturn( 'User2' );
185 $targetUser1->expects( $this->any() )->method( 'getId' )->willReturn( 1 );
186 $targetUser2->expects( $this->any() )->method( 'getId' )->willReturn( 2 );
187 $targetUser1->expects( $this->any() )->method( 'getEmail' )->willReturn( 'foo@bar.baz' );
188 $targetUser2->expects( $this->any() )->method( 'getEmail' )->willReturn( 'foo@bar.baz' );
190 $passwordReset = $this->getMockBuilder( PasswordReset
::class )
191 ->setMethods( [ 'getUsersByEmail' ] )->setConstructorArgs( [ $config, $authManager ] )
193 $passwordReset->expects( $this->any() )->method( 'getUsersByEmail' )->with( 'foo@bar.baz' )
194 ->willReturn( [ $targetUser1, $targetUser2 ] );
196 $status = $passwordReset->isAllowed( $performingUser );
197 $this->assertTrue( $status->isGood() );
199 $status = $passwordReset->execute( $performingUser, null, 'foo@bar.baz' );
200 $this->assertTrue( $status->isGood() );