use MediaWiki\Auth\AuthManager;
use MediaWiki\Auth\TemporaryPasswordAuthenticationRequest;
-use MediaWiki\Block\DatabaseBlock;
use MediaWiki\Block\CompositeBlock;
+use MediaWiki\Block\DatabaseBlock;
use MediaWiki\Block\SystemBlock;
use MediaWiki\Config\ServiceOptions;
use MediaWiki\Permissions\PermissionManager;
->with( $user, 'editmyprivateinfo' )
->willReturn( $canEditPrivate );
- $loadBalancer = $this->getMockBuilder( ILoadBalancer::class )->getMock();
+ $loadBalancer = $this->createMock( ILoadBalancer::class );
$passwordReset = new PasswordReset(
$config,
];
}
- /**
- * @expectedException \LogicException
- */
public function testExecute_notAllowed() {
- $user = $this->getMock( User::class );
+ $user = $this->createMock( User::class );
/** @var User $user */
$passwordReset = $this->getMockBuilder( PasswordReset::class )
->willReturn( Status::newFatal( 'somestatuscode' ) );
/** @var PasswordReset $passwordReset */
+ $this->expectException( \LogicException::class );
$passwordReset->execute( $user );
}
'SpecialPasswordResetOnSubmit' => [],
] );
- $loadBalancer = $this->getMockBuilder( ILoadBalancer::class )
- ->getMock();
+ $loadBalancer = $this->createMock( ILoadBalancer::class );
$users = $this->makeUsers();
$permissionManager = $this->makePermissionManager( $performingUser, true );
return [
- 'Invalid email' => [
- 'expectedError' => 'passwordreset-invalidemail',
+ 'Throttled, pretend everything is ok' => [
+ 'expectedError' => false,
'config' => $defaultConfig,
'performingUser' => $throttledUser,
'permissionManager' => $permissionManager,
'authManager' => $this->makeAuthManager(),
+ 'username' => 'User1',
+ 'email' => '',
+ 'usersWithEmail' => [],
+ ],
+ 'Throttled, email required for resets, is invalid, pretend everything is ok' => [
+ 'expectedError' => false,
+ 'config' => $emailRequiredConfig,
+ 'performingUser' => $throttledUser,
+ 'permissionManager' => $permissionManager,
+ 'authManager' => $this->makeAuthManager(),
+ 'username' => 'User1',
+ 'email' => '[invalid email]',
+ 'usersWithEmail' => [],
+ ],
+ 'Invalid email, pretend everything is OK' => [
+ 'expectedError' => false,
+ 'config' => $defaultConfig,
+ 'performingUser' => $performingUser,
+ 'permissionManager' => $permissionManager,
+ 'authManager' => $this->makeAuthManager(),
'username' => '',
'email' => '[invalid email]',
'usersWithEmail' => [],
'No username, no email' => [
'expectedError' => 'passwordreset-nodata',
'config' => $defaultConfig,
- 'performingUser' => $throttledUser,
+ 'performingUser' => $performingUser,
'permissionManager' => $permissionManager,
'authManager' => $this->makeAuthManager(),
'username' => '',
'Email route not enabled' => [
'expectedError' => 'passwordreset-nodata',
'config' => $this->makeConfig( true, [ 'username' => true ], false ),
- 'performingUser' => $throttledUser,
+ 'performingUser' => $performingUser,
'permissionManager' => $permissionManager,
'authManager' => $this->makeAuthManager(),
'username' => '',
'Username route not enabled' => [
'expectedError' => 'passwordreset-nodata',
'config' => $this->makeConfig( true, [ 'email' => true ], false ),
- 'performingUser' => $throttledUser,
+ 'performingUser' => $performingUser,
'permissionManager' => $permissionManager,
'authManager' => $this->makeAuthManager(),
'username' => 'User1',
'No routes enabled' => [
'expectedError' => 'passwordreset-nodata',
'config' => $this->makeConfig( true, [], false ),
- 'performingUser' => $throttledUser,
+ 'performingUser' => $performingUser,
'permissionManager' => $permissionManager,
'authManager' => $this->makeAuthManager(),
'username' => 'User1',
'email' => self::VALID_EMAIL,
'usersWithEmail' => [],
],
- 'Email reqiured for resets, but is empty' => [
- 'expectedError' => 'passwordreset-username-email-required',
+ 'Email required for resets but is empty, pretend everything is OK' => [
+ 'expectedError' => false,
'config' => $emailRequiredConfig,
- 'performingUser' => $throttledUser,
+ 'performingUser' => $performingUser,
'permissionManager' => $permissionManager,
'authManager' => $this->makeAuthManager(),
'username' => 'User1',
'email' => '',
'usersWithEmail' => [],
],
- 'Email reqiured for resets, is invalid' => [
- 'expectedError' => 'passwordreset-invalidemail',
+ 'Email required for resets but is invalid, pretend everything is OK' => [
+ 'expectedError' => false,
'config' => $emailRequiredConfig,
- 'performingUser' => $throttledUser,
+ 'performingUser' => $performingUser,
'permissionManager' => $permissionManager,
'authManager' => $this->makeAuthManager(),
'username' => 'User1',
'email' => '[invalid email]',
'usersWithEmail' => [],
],
- 'Throttled' => [
- 'expectedError' => 'actionthrottledtext',
+ 'Password email already sent within 24 hours, pretend everything is ok' => [
+ 'expectedError' => false,
'config' => $defaultConfig,
- 'performingUser' => $throttledUser,
+ 'performingUser' => $performingUser,
'permissionManager' => $permissionManager,
- 'authManager' => $this->makeAuthManager(),
+ 'authManager' => $this->makeAuthManager( [ 'User1' ], 0, [], [ 'User1' ] ),
'username' => 'User1',
'email' => '',
- 'usersWithEmail' => [],
+ 'usersWithEmail' => [ 'User1' ],
],
- 'No user by this username' => [
- 'expectedError' => 'nosuchuser',
+ 'No user by this username, pretend everything is OK' => [
+ 'expectedError' => false,
'config' => $defaultConfig,
'performingUser' => $performingUser,
'permissionManager' => $permissionManager,
'email' => '',
'usersWithEmail' => [],
],
+ 'Username is not valid' => [
+ 'expectedError' => 'noname',
+ 'config' => $defaultConfig,
+ 'performingUser' => $performingUser,
+ 'permissionManager' => $permissionManager,
+ 'authManager' => $this->makeAuthManager(),
+ 'username' => 'Invalid|username',
+ 'email' => '',
+ 'usersWithEmail' => [],
+ ],
'If no users with this email found, pretend everything is OK' => [
'expectedError' => false,
'config' => $defaultConfig,
'email' => 'some@not.found.email',
'usersWithEmail' => [],
],
- 'No email for the user' => [
- 'expectedError' => 'noemail',
+ 'No email for the user, pretend everything is OK' => [
+ 'expectedError' => false,
'config' => $defaultConfig,
'performingUser' => $performingUser,
'permissionManager' => $permissionManager,
'email' => '',
'usersWithEmail' => [],
],
- 'Email reqiured for resets, no match' => [
+ 'Email required for resets, no match' => [
'expectedError' => false,
'config' => $emailRequiredConfig,
'performingUser' => $performingUser,
'email' => self::VALID_EMAIL,
'usersWithEmail' => [ 'User2' ],
],
+ 'Reset three users via email that did not opt in, multiple users with same email' => [
+ 'expectedError' => false,
+ 'config' => $emailRequiredConfig,
+ 'performingUser' => $performingUser,
+ 'permissionManager' => $permissionManager,
+ 'authManager' => $this->makeAuthManager( [ 'User2', 'User3', 'User4' ], 3, [ 'User1' ] ),
+ 'username' => '',
+ 'email' => self::VALID_EMAIL,
+ 'usersWithEmail' => [ 'User1', 'User2', 'User3', 'User4' ],
+ ],
];
}
}
/**
- * @param string[] $allowed
- * @param int $numUsersToAuth
- * @param string[] $ignored
+ * @param string[] $allowed Usernames that are allowed to send password reset email
+ * by AuthManager's allowsAuthenticationDataChange method.
+ * @param int $numUsersToAuth Number of users that will receive email
+ * @param string[] $ignored Usernames that are allowed but ignored by AuthManager's
+ * allowsAuthenticationDataChange method and will not receive password reset email.
+ * @param string[] $mailThrottledLimited Usernames that have already
+ * received the password reset email within a given time, and AuthManager
+ * changeAuthenticationData method will mark them as 'throttled-mailpassword.'
* @return AuthManager
*/
private function makeAuthManager(
array $allowed = [],
$numUsersToAuth = 0,
- array $ignored = []
+ array $ignored = [],
+ array $mailThrottledLimited = []
) : AuthManager {
$authManager = $this->getMockBuilder( AuthManager::class )
->disableOriginalConstructor()
->getMock();
$authManager->method( 'allowsAuthenticationDataChange' )
->willReturnCallback(
- function ( TemporaryPasswordAuthenticationRequest $req ) use ( $allowed, $ignored ) {
+ function ( TemporaryPasswordAuthenticationRequest $req )
+ use ( $allowed, $ignored, $mailThrottledLimited ) {
+ if ( in_array( $req->username, $mailThrottledLimited, true ) ) {
+ return Status::newGood( 'throttled-mailpassword' );
+ }
+
$value = in_array( $req->username, $ignored, true )
? 'ignored'
: 'okie dokie';
+
return in_array( $req->username, $allowed, true )
? Status::newGood( $value )
: Status::newFatal( 'rejected by test mock' );
private function makeUsers() {
$user1 = $this->getMockBuilder( User::class )->getMock();
$user2 = $this->getMockBuilder( User::class )->getMock();
+ $user3 = $this->getMockBuilder( User::class )->getMock();
+ $user4 = $this->getMockBuilder( User::class )->getMock();
$user1->method( 'getName' )->willReturn( 'User1' );
$user2->method( 'getName' )->willReturn( 'User2' );
+ $user3->method( 'getName' )->willReturn( 'User3' );
+ $user4->method( 'getName' )->willReturn( 'User4' );
$user1->method( 'getId' )->willReturn( 1 );
$user2->method( 'getId' )->willReturn( 2 );
+ $user3->method( 'getId' )->willReturn( 3 );
+ $user4->method( 'getId' )->willReturn( 4 );
$user1->method( 'getEmail' )->willReturn( self::VALID_EMAIL );
$user2->method( 'getEmail' )->willReturn( self::VALID_EMAIL );
+ $user3->method( 'getEmail' )->willReturn( self::VALID_EMAIL );
+ $user4->method( 'getEmail' )->willReturn( self::VALID_EMAIL );
$user1->method( 'getBoolOption' )
->with( 'requireemail' )
$badUser = $this->getMockBuilder( User::class )->getMock();
$badUser->method( 'getName' )->willReturn( 'BadUser' );
- $badUser->method( 'getId' )->willReturn( 3 );
+ $badUser->method( 'getId' )->willReturn( 5 );
$badUser->method( 'getEmail' )->willReturn( null );
return [
'User1' => $user1,
'User2' => $user2,
+ 'User3' => $user3,
+ 'User4' => $user4,
'BadUser' => $badUser,
];
}