Merge "Select "move subpages" by default when moving a page"
[lhc/web/wiklou.git] / tests / phpunit / includes / user / PasswordResetTest.php
1 <?php
2
3 use MediaWiki\Auth\AuthManager;
4 use MediaWiki\Block\DatabaseBlock;
5 use MediaWiki\Block\CompositeBlock;
6 use MediaWiki\Block\SystemBlock;
7
8 /**
9 * @covers PasswordReset
10 * @group Database
11 */
12 class PasswordResetTest extends MediaWikiTestCase {
13 /**
14 * @dataProvider provideIsAllowed
15 */
16 public function testIsAllowed( $passwordResetRoutes, $enableEmail,
17 $allowsAuthenticationDataChange, $canEditPrivate, $block, $globalBlock, $isAllowed
18 ) {
19 $config = new HashConfig( [
20 'PasswordResetRoutes' => $passwordResetRoutes,
21 'EnableEmail' => $enableEmail,
22 ] );
23
24 $authManager = $this->getMockBuilder( AuthManager::class )->disableOriginalConstructor()
25 ->getMock();
26 $authManager->expects( $this->any() )->method( 'allowsAuthenticationDataChange' )
27 ->willReturn( $allowsAuthenticationDataChange ? Status::newGood() : Status::newFatal( 'foo' ) );
28
29 $user = $this->getMockBuilder( User::class )->getMock();
30 $user->expects( $this->any() )->method( 'getName' )->willReturn( 'Foo' );
31 $user->expects( $this->any() )->method( 'getBlock' )->willReturn( $block );
32 $user->expects( $this->any() )->method( 'getGlobalBlock' )->willReturn( $globalBlock );
33 $user->expects( $this->any() )->method( 'isAllowed' )
34 ->will( $this->returnCallback( function ( $perm ) use ( $canEditPrivate ) {
35 if ( $perm === 'editmyprivateinfo' ) {
36 return $canEditPrivate;
37 } else {
38 $this->fail( 'Unexpected permission check' );
39 }
40 } ) );
41
42 $passwordReset = new PasswordReset( $config, $authManager );
43
44 $this->assertSame( $isAllowed, $passwordReset->isAllowed( $user )->isGood() );
45 }
46
47 public function provideIsAllowed() {
48 return [
49 'no routes' => [
50 'passwordResetRoutes' => [],
51 'enableEmail' => true,
52 'allowsAuthenticationDataChange' => true,
53 'canEditPrivate' => true,
54 'block' => null,
55 'globalBlock' => null,
56 'isAllowed' => false,
57 ],
58 'email disabled' => [
59 'passwordResetRoutes' => [ 'username' => true ],
60 'enableEmail' => false,
61 'allowsAuthenticationDataChange' => true,
62 'canEditPrivate' => true,
63 'block' => null,
64 'globalBlock' => null,
65 'isAllowed' => false,
66 ],
67 'auth data change disabled' => [
68 'passwordResetRoutes' => [ 'username' => true ],
69 'enableEmail' => true,
70 'allowsAuthenticationDataChange' => false,
71 'canEditPrivate' => true,
72 'block' => null,
73 'globalBlock' => null,
74 'isAllowed' => false,
75 ],
76 'cannot edit private data' => [
77 'passwordResetRoutes' => [ 'username' => true ],
78 'enableEmail' => true,
79 'allowsAuthenticationDataChange' => true,
80 'canEditPrivate' => false,
81 'block' => null,
82 'globalBlock' => null,
83 'isAllowed' => false,
84 ],
85 'blocked with account creation disabled' => [
86 'passwordResetRoutes' => [ 'username' => true ],
87 'enableEmail' => true,
88 'allowsAuthenticationDataChange' => true,
89 'canEditPrivate' => true,
90 'block' => new DatabaseBlock( [ 'createAccount' => true ] ),
91 'globalBlock' => null,
92 'isAllowed' => false,
93 ],
94 'blocked w/o account creation disabled' => [
95 'passwordResetRoutes' => [ 'username' => true ],
96 'enableEmail' => true,
97 'allowsAuthenticationDataChange' => true,
98 'canEditPrivate' => true,
99 'block' => new DatabaseBlock( [] ),
100 'globalBlock' => null,
101 'isAllowed' => true,
102 ],
103 'using blocked proxy' => [
104 'passwordResetRoutes' => [ 'username' => true ],
105 'enableEmail' => true,
106 'allowsAuthenticationDataChange' => true,
107 'canEditPrivate' => true,
108 'block' => new SystemBlock(
109 [ 'systemBlock' => 'proxy' ]
110 ),
111 'globalBlock' => null,
112 'isAllowed' => false,
113 ],
114 'globally blocked with account creation not disabled' => [
115 'passwordResetRoutes' => [ 'username' => true ],
116 'enableEmail' => true,
117 'allowsAuthenticationDataChange' => true,
118 'canEditPrivate' => true,
119 'block' => null,
120 'globalBlock' => new SystemBlock(
121 [ 'systemBlock' => 'global-block' ]
122 ),
123 'isAllowed' => true,
124 ],
125 'blocked via wgSoftBlockRanges' => [
126 'passwordResetRoutes' => [ 'username' => true ],
127 'enableEmail' => true,
128 'allowsAuthenticationDataChange' => true,
129 'canEditPrivate' => true,
130 'block' => new SystemBlock(
131 [ 'systemBlock' => 'wgSoftBlockRanges', 'anonOnly' => true ]
132 ),
133 'globalBlock' => null,
134 'isAllowed' => true,
135 ],
136 'blocked with an unknown system block type' => [
137 'passwordResetRoutes' => [ 'username' => true ],
138 'enableEmail' => true,
139 'allowsAuthenticationDataChange' => true,
140 'canEditPrivate' => true,
141 'block' => new SystemBlock( [ 'systemBlock' => 'unknown' ] ),
142 'globalBlock' => null,
143 'isAllowed' => false,
144 ],
145 'blocked with multiple blocks, all allowing password reset' => [
146 'passwordResetRoutes' => [ 'username' => true ],
147 'enableEmail' => true,
148 'allowsAuthenticationDataChange' => true,
149 'canEditPrivate' => true,
150 'block' => new CompositeBlock( [
151 'originalBlocks' => [
152 new SystemBlock( [ 'systemBlock' => 'wgSoftBlockRanges', 'anonOnly' => true ] ),
153 new Block( [] ),
154 ]
155 ] ),
156 'globalBlock' => null,
157 'isAllowed' => true,
158 ],
159 'blocked with multiple blocks, not all allowing password reset' => [
160 'passwordResetRoutes' => [ 'username' => true ],
161 'enableEmail' => true,
162 'allowsAuthenticationDataChange' => true,
163 'canEditPrivate' => true,
164 'block' => new CompositeBlock( [
165 'originalBlocks' => [
166 new SystemBlock( [ 'systemBlock' => 'wgSoftBlockRanges', 'anonOnly' => true ] ),
167 new SystemBlock( [ 'systemBlock' => 'proxy' ] ),
168 ]
169 ] ),
170 'globalBlock' => null,
171 'isAllowed' => false,
172 ],
173 'all OK' => [
174 'passwordResetRoutes' => [ 'username' => true ],
175 'enableEmail' => true,
176 'allowsAuthenticationDataChange' => true,
177 'canEditPrivate' => true,
178 'block' => null,
179 'globalBlock' => null,
180 'isAllowed' => true,
181 ],
182 ];
183 }
184
185 public function testExecute_email() {
186 $config = new HashConfig( [
187 'PasswordResetRoutes' => [ 'username' => true, 'email' => true ],
188 'EnableEmail' => true,
189 ] );
190
191 // Unregister the hooks for proper unit testing
192 $this->mergeMwGlobalArrayValue( 'wgHooks', [
193 'User::mailPasswordInternal' => [],
194 'SpecialPasswordResetOnSubmit' => [],
195 ] );
196
197 $authManager = $this->getMockBuilder( AuthManager::class )->disableOriginalConstructor()
198 ->getMock();
199 $authManager->expects( $this->any() )->method( 'allowsAuthenticationDataChange' )
200 ->willReturn( Status::newGood() );
201 $authManager->expects( $this->exactly( 2 ) )->method( 'changeAuthenticationData' );
202
203 $request = new FauxRequest();
204 $request->setIP( '1.2.3.4' );
205 $performingUser = $this->getMockBuilder( User::class )->getMock();
206 $performingUser->expects( $this->any() )->method( 'getRequest' )->willReturn( $request );
207 $performingUser->expects( $this->any() )->method( 'isAllowed' )->willReturn( true );
208 $performingUser->expects( $this->any() )->method( 'getName' )->willReturn( 'Performer' );
209
210 $targetUser1 = $this->getMockBuilder( User::class )->getMock();
211 $targetUser2 = $this->getMockBuilder( User::class )->getMock();
212 $targetUser1->expects( $this->any() )->method( 'getName' )->willReturn( 'User1' );
213 $targetUser2->expects( $this->any() )->method( 'getName' )->willReturn( 'User2' );
214 $targetUser1->expects( $this->any() )->method( 'getId' )->willReturn( 1 );
215 $targetUser2->expects( $this->any() )->method( 'getId' )->willReturn( 2 );
216 $targetUser1->expects( $this->any() )->method( 'getEmail' )->willReturn( 'foo@bar.baz' );
217 $targetUser2->expects( $this->any() )->method( 'getEmail' )->willReturn( 'foo@bar.baz' );
218
219 $passwordReset = $this->getMockBuilder( PasswordReset::class )
220 ->setMethods( [ 'getUsersByEmail' ] )->setConstructorArgs( [ $config, $authManager ] )
221 ->getMock();
222 $passwordReset->expects( $this->any() )->method( 'getUsersByEmail' )->with( 'foo@bar.baz' )
223 ->willReturn( [ $targetUser1, $targetUser2 ] );
224
225 $status = $passwordReset->isAllowed( $performingUser );
226 $this->assertTrue( $status->isGood() );
227
228 $status = $passwordReset->execute( $performingUser, null, 'foo@bar.baz' );
229 $this->assertTrue( $status->isGood() );
230 }
231 }