Keep Block as a deprecated class alias for DatabaseBlock. Update calls to the Block constructor and Block static methods from external classes. Also update documentation in several places that refer to blocks as Blocks. Bug: T222737 Change-Id: I6d96b63ca0a84bee19486471e0a16a53a79d768a
202 lines
7 KiB
PHP
202 lines
7 KiB
PHP
<?php
|
|
|
|
use MediaWiki\Auth\AuthManager;
|
|
use MediaWiki\Block\DatabaseBlock;
|
|
use MediaWiki\Block\SystemBlock;
|
|
|
|
/**
|
|
* @covers PasswordReset
|
|
* @group Database
|
|
*/
|
|
class PasswordResetTest extends MediaWikiTestCase {
|
|
/**
|
|
* @dataProvider provideIsAllowed
|
|
*/
|
|
public function testIsAllowed( $passwordResetRoutes, $enableEmail,
|
|
$allowsAuthenticationDataChange, $canEditPrivate, $block, $globalBlock, $isAllowed
|
|
) {
|
|
$config = new HashConfig( [
|
|
'PasswordResetRoutes' => $passwordResetRoutes,
|
|
'EnableEmail' => $enableEmail,
|
|
] );
|
|
|
|
$authManager = $this->getMockBuilder( AuthManager::class )->disableOriginalConstructor()
|
|
->getMock();
|
|
$authManager->expects( $this->any() )->method( 'allowsAuthenticationDataChange' )
|
|
->willReturn( $allowsAuthenticationDataChange ? Status::newGood() : Status::newFatal( 'foo' ) );
|
|
|
|
$user = $this->getMockBuilder( User::class )->getMock();
|
|
$user->expects( $this->any() )->method( 'getName' )->willReturn( 'Foo' );
|
|
$user->expects( $this->any() )->method( 'getBlock' )->willReturn( $block );
|
|
$user->expects( $this->any() )->method( 'getGlobalBlock' )->willReturn( $globalBlock );
|
|
$user->expects( $this->any() )->method( 'isAllowed' )
|
|
->will( $this->returnCallback( function ( $perm ) use ( $canEditPrivate ) {
|
|
if ( $perm === 'editmyprivateinfo' ) {
|
|
return $canEditPrivate;
|
|
} else {
|
|
$this->fail( 'Unexpected permission check' );
|
|
}
|
|
} ) );
|
|
|
|
$passwordReset = new PasswordReset( $config, $authManager );
|
|
|
|
$this->assertSame( $isAllowed, $passwordReset->isAllowed( $user )->isGood() );
|
|
}
|
|
|
|
public function provideIsAllowed() {
|
|
return [
|
|
'no routes' => [
|
|
'passwordResetRoutes' => [],
|
|
'enableEmail' => true,
|
|
'allowsAuthenticationDataChange' => true,
|
|
'canEditPrivate' => true,
|
|
'block' => null,
|
|
'globalBlock' => null,
|
|
'isAllowed' => false,
|
|
],
|
|
'email disabled' => [
|
|
'passwordResetRoutes' => [ 'username' => true ],
|
|
'enableEmail' => false,
|
|
'allowsAuthenticationDataChange' => true,
|
|
'canEditPrivate' => true,
|
|
'block' => null,
|
|
'globalBlock' => null,
|
|
'isAllowed' => false,
|
|
],
|
|
'auth data change disabled' => [
|
|
'passwordResetRoutes' => [ 'username' => true ],
|
|
'enableEmail' => true,
|
|
'allowsAuthenticationDataChange' => false,
|
|
'canEditPrivate' => true,
|
|
'block' => null,
|
|
'globalBlock' => null,
|
|
'isAllowed' => false,
|
|
],
|
|
'cannot edit private data' => [
|
|
'passwordResetRoutes' => [ 'username' => true ],
|
|
'enableEmail' => true,
|
|
'allowsAuthenticationDataChange' => true,
|
|
'canEditPrivate' => false,
|
|
'block' => null,
|
|
'globalBlock' => null,
|
|
'isAllowed' => false,
|
|
],
|
|
'blocked with account creation disabled' => [
|
|
'passwordResetRoutes' => [ 'username' => true ],
|
|
'enableEmail' => true,
|
|
'allowsAuthenticationDataChange' => true,
|
|
'canEditPrivate' => true,
|
|
'block' => new DatabaseBlock( [ 'createAccount' => true ] ),
|
|
'globalBlock' => null,
|
|
'isAllowed' => false,
|
|
],
|
|
'blocked w/o account creation disabled' => [
|
|
'passwordResetRoutes' => [ 'username' => true ],
|
|
'enableEmail' => true,
|
|
'allowsAuthenticationDataChange' => true,
|
|
'canEditPrivate' => true,
|
|
'block' => new DatabaseBlock( [] ),
|
|
'globalBlock' => null,
|
|
'isAllowed' => true,
|
|
],
|
|
'using blocked proxy' => [
|
|
'passwordResetRoutes' => [ 'username' => true ],
|
|
'enableEmail' => true,
|
|
'allowsAuthenticationDataChange' => true,
|
|
'canEditPrivate' => true,
|
|
'block' => new SystemBlock(
|
|
[ 'systemBlock' => 'proxy' ]
|
|
),
|
|
'globalBlock' => null,
|
|
'isAllowed' => false,
|
|
],
|
|
'globally blocked with account creation not disabled' => [
|
|
'passwordResetRoutes' => [ 'username' => true ],
|
|
'enableEmail' => true,
|
|
'allowsAuthenticationDataChange' => true,
|
|
'canEditPrivate' => true,
|
|
'block' => null,
|
|
'globalBlock' => new SystemBlock(
|
|
[ 'systemBlock' => 'global-block' ]
|
|
),
|
|
'isAllowed' => true,
|
|
],
|
|
'blocked via wgSoftBlockRanges' => [
|
|
'passwordResetRoutes' => [ 'username' => true ],
|
|
'enableEmail' => true,
|
|
'allowsAuthenticationDataChange' => true,
|
|
'canEditPrivate' => true,
|
|
'block' => new SystemBlock(
|
|
[ 'systemBlock' => 'wgSoftBlockRanges', 'anonOnly' => true ]
|
|
),
|
|
'globalBlock' => null,
|
|
'isAllowed' => true,
|
|
],
|
|
'blocked with an unknown system block type' => [
|
|
'passwordResetRoutes' => [ 'username' => true ],
|
|
'enableEmail' => true,
|
|
'allowsAuthenticationDataChange' => true,
|
|
'canEditPrivate' => true,
|
|
'block' => new SystemBlock( [ 'systemBlock' => 'unknown' ] ),
|
|
'globalBlock' => null,
|
|
'isAllowed' => false,
|
|
],
|
|
'all OK' => [
|
|
'passwordResetRoutes' => [ 'username' => true ],
|
|
'enableEmail' => true,
|
|
'allowsAuthenticationDataChange' => true,
|
|
'canEditPrivate' => true,
|
|
'block' => null,
|
|
'globalBlock' => null,
|
|
'isAllowed' => true,
|
|
],
|
|
];
|
|
}
|
|
|
|
public function testExecute_email() {
|
|
$config = new HashConfig( [
|
|
'PasswordResetRoutes' => [ 'username' => true, 'email' => true ],
|
|
'EnableEmail' => true,
|
|
] );
|
|
|
|
// Unregister the hooks for proper unit testing
|
|
$this->mergeMwGlobalArrayValue( 'wgHooks', [
|
|
'User::mailPasswordInternal' => [],
|
|
'SpecialPasswordResetOnSubmit' => [],
|
|
] );
|
|
|
|
$authManager = $this->getMockBuilder( AuthManager::class )->disableOriginalConstructor()
|
|
->getMock();
|
|
$authManager->expects( $this->any() )->method( 'allowsAuthenticationDataChange' )
|
|
->willReturn( Status::newGood() );
|
|
$authManager->expects( $this->exactly( 2 ) )->method( 'changeAuthenticationData' );
|
|
|
|
$request = new FauxRequest();
|
|
$request->setIP( '1.2.3.4' );
|
|
$performingUser = $this->getMockBuilder( User::class )->getMock();
|
|
$performingUser->expects( $this->any() )->method( 'getRequest' )->willReturn( $request );
|
|
$performingUser->expects( $this->any() )->method( 'isAllowed' )->willReturn( true );
|
|
$performingUser->expects( $this->any() )->method( 'getName' )->willReturn( 'Performer' );
|
|
|
|
$targetUser1 = $this->getMockBuilder( User::class )->getMock();
|
|
$targetUser2 = $this->getMockBuilder( User::class )->getMock();
|
|
$targetUser1->expects( $this->any() )->method( 'getName' )->willReturn( 'User1' );
|
|
$targetUser2->expects( $this->any() )->method( 'getName' )->willReturn( 'User2' );
|
|
$targetUser1->expects( $this->any() )->method( 'getId' )->willReturn( 1 );
|
|
$targetUser2->expects( $this->any() )->method( 'getId' )->willReturn( 2 );
|
|
$targetUser1->expects( $this->any() )->method( 'getEmail' )->willReturn( 'foo@bar.baz' );
|
|
$targetUser2->expects( $this->any() )->method( 'getEmail' )->willReturn( 'foo@bar.baz' );
|
|
|
|
$passwordReset = $this->getMockBuilder( PasswordReset::class )
|
|
->setMethods( [ 'getUsersByEmail' ] )->setConstructorArgs( [ $config, $authManager ] )
|
|
->getMock();
|
|
$passwordReset->expects( $this->any() )->method( 'getUsersByEmail' )->with( 'foo@bar.baz' )
|
|
->willReturn( [ $targetUser1, $targetUser2 ] );
|
|
|
|
$status = $passwordReset->isAllowed( $performingUser );
|
|
$this->assertTrue( $status->isGood() );
|
|
|
|
$status = $passwordReset->execute( $performingUser, null, 'foo@bar.baz' );
|
|
$this->assertTrue( $status->isGood() );
|
|
}
|
|
}
|