3 use MediaWiki\Auth\AuthManager
;
4 use MediaWiki\Block\SystemBlock
;
7 * @covers PasswordReset
10 class PasswordResetTest
extends MediaWikiTestCase
{
12 * @dataProvider provideIsAllowed
14 public function testIsAllowed( $passwordResetRoutes, $enableEmail,
15 $allowsAuthenticationDataChange, $canEditPrivate, $block, $globalBlock, $isAllowed
17 $config = new HashConfig( [
18 'PasswordResetRoutes' => $passwordResetRoutes,
19 'EnableEmail' => $enableEmail,
22 $authManager = $this->getMockBuilder( AuthManager
::class )->disableOriginalConstructor()
24 $authManager->expects( $this->any() )->method( 'allowsAuthenticationDataChange' )
25 ->willReturn( $allowsAuthenticationDataChange ? Status
::newGood() : Status
::newFatal( 'foo' ) );
27 $user = $this->getMockBuilder( User
::class )->getMock();
28 $user->expects( $this->any() )->method( 'getName' )->willReturn( 'Foo' );
29 $user->expects( $this->any() )->method( 'getBlock' )->willReturn( $block );
30 $user->expects( $this->any() )->method( 'getGlobalBlock' )->willReturn( $globalBlock );
31 $user->expects( $this->any() )->method( 'isAllowed' )
32 ->will( $this->returnCallback( function ( $perm ) use ( $canEditPrivate ) {
33 if ( $perm === 'editmyprivateinfo' ) {
34 return $canEditPrivate;
36 $this->fail( 'Unexpected permission check' );
40 $passwordReset = new PasswordReset( $config, $authManager );
42 $this->assertSame( $isAllowed, $passwordReset->isAllowed( $user )->isGood() );
45 public function provideIsAllowed() {
48 'passwordResetRoutes' => [],
49 'enableEmail' => true,
50 'allowsAuthenticationDataChange' => true,
51 'canEditPrivate' => true,
53 'globalBlock' => null,
57 'passwordResetRoutes' => [ 'username' => true ],
58 'enableEmail' => false,
59 'allowsAuthenticationDataChange' => true,
60 'canEditPrivate' => true,
62 'globalBlock' => null,
65 'auth data change disabled' => [
66 'passwordResetRoutes' => [ 'username' => true ],
67 'enableEmail' => true,
68 'allowsAuthenticationDataChange' => false,
69 'canEditPrivate' => true,
71 'globalBlock' => null,
74 'cannot edit private data' => [
75 'passwordResetRoutes' => [ 'username' => true ],
76 'enableEmail' => true,
77 'allowsAuthenticationDataChange' => true,
78 'canEditPrivate' => false,
80 'globalBlock' => null,
83 'blocked with account creation disabled' => [
84 'passwordResetRoutes' => [ 'username' => true ],
85 'enableEmail' => true,
86 'allowsAuthenticationDataChange' => true,
87 'canEditPrivate' => true,
88 'block' => new Block( [ 'createAccount' => true ] ),
89 'globalBlock' => null,
92 'blocked w/o account creation disabled' => [
93 'passwordResetRoutes' => [ 'username' => true ],
94 'enableEmail' => true,
95 'allowsAuthenticationDataChange' => true,
96 'canEditPrivate' => true,
97 'block' => new Block( [] ),
98 'globalBlock' => null,
101 'using blocked proxy' => [
102 'passwordResetRoutes' => [ 'username' => true ],
103 'enableEmail' => true,
104 'allowsAuthenticationDataChange' => true,
105 'canEditPrivate' => true,
106 'block' => new SystemBlock(
107 [ 'systemBlock' => 'proxy' ]
109 'globalBlock' => null,
110 'isAllowed' => false,
112 'globally blocked with account creation not disabled' => [
113 'passwordResetRoutes' => [ 'username' => true ],
114 'enableEmail' => true,
115 'allowsAuthenticationDataChange' => true,
116 'canEditPrivate' => true,
118 'globalBlock' => new SystemBlock(
119 [ 'systemBlock' => 'global-block' ]
123 'blocked via wgSoftBlockRanges' => [
124 'passwordResetRoutes' => [ 'username' => true ],
125 'enableEmail' => true,
126 'allowsAuthenticationDataChange' => true,
127 'canEditPrivate' => true,
128 'block' => new SystemBlock(
129 [ 'systemBlock' => 'wgSoftBlockRanges', 'anonOnly' => true ]
131 'globalBlock' => null,
134 'blocked with an unknown system block type' => [
135 'passwordResetRoutes' => [ 'username' => true ],
136 'enableEmail' => true,
137 'allowsAuthenticationDataChange' => true,
138 'canEditPrivate' => true,
139 'block' => new SystemBlock( [ 'systemBlock' => 'unknown' ] ),
140 'globalBlock' => null,
141 'isAllowed' => false,
144 'passwordResetRoutes' => [ 'username' => true ],
145 'enableEmail' => true,
146 'allowsAuthenticationDataChange' => true,
147 'canEditPrivate' => true,
149 'globalBlock' => null,
155 public function testExecute_email() {
156 $config = new HashConfig( [
157 'PasswordResetRoutes' => [ 'username' => true, 'email' => true ],
158 'EnableEmail' => true,
161 // Unregister the hooks for proper unit testing
162 $this->mergeMwGlobalArrayValue( 'wgHooks', [
163 'User::mailPasswordInternal' => [],
164 'SpecialPasswordResetOnSubmit' => [],
167 $authManager = $this->getMockBuilder( AuthManager
::class )->disableOriginalConstructor()
169 $authManager->expects( $this->any() )->method( 'allowsAuthenticationDataChange' )
170 ->willReturn( Status
::newGood() );
171 $authManager->expects( $this->exactly( 2 ) )->method( 'changeAuthenticationData' );
173 $request = new FauxRequest();
174 $request->setIP( '1.2.3.4' );
175 $performingUser = $this->getMockBuilder( User
::class )->getMock();
176 $performingUser->expects( $this->any() )->method( 'getRequest' )->willReturn( $request );
177 $performingUser->expects( $this->any() )->method( 'isAllowed' )->willReturn( true );
178 $performingUser->expects( $this->any() )->method( 'getName' )->willReturn( 'Performer' );
180 $targetUser1 = $this->getMockBuilder( User
::class )->getMock();
181 $targetUser2 = $this->getMockBuilder( User
::class )->getMock();
182 $targetUser1->expects( $this->any() )->method( 'getName' )->willReturn( 'User1' );
183 $targetUser2->expects( $this->any() )->method( 'getName' )->willReturn( 'User2' );
184 $targetUser1->expects( $this->any() )->method( 'getId' )->willReturn( 1 );
185 $targetUser2->expects( $this->any() )->method( 'getId' )->willReturn( 2 );
186 $targetUser1->expects( $this->any() )->method( 'getEmail' )->willReturn( 'foo@bar.baz' );
187 $targetUser2->expects( $this->any() )->method( 'getEmail' )->willReturn( 'foo@bar.baz' );
189 $passwordReset = $this->getMockBuilder( PasswordReset
::class )
190 ->setMethods( [ 'getUsersByEmail' ] )->setConstructorArgs( [ $config, $authManager ] )
192 $passwordReset->expects( $this->any() )->method( 'getUsersByEmail' )->with( 'foo@bar.baz' )
193 ->willReturn( [ $targetUser1, $targetUser2 ] );
195 $status = $passwordReset->isAllowed( $performingUser );
196 $this->assertTrue( $status->isGood() );
198 $status = $passwordReset->execute( $performingUser, null, 'foo@bar.baz' );
199 $this->assertTrue( $status->isGood() );