wiki.techinc.nl/tests/phpunit/includes/block/BlockManagerTest.php
Thalia 786a7a168a Pass in ServiceOptions to BlockManager
Change-Id: Ic63d7ff35a71e36c4e6157e9d472e2870f95f00d
2019-07-10 16:33:21 +01:00

394 lines
10 KiB
PHP

<?php
use MediaWiki\Block\BlockManager;
use MediaWiki\Block\DatabaseBlock;
use MediaWiki\Block\SystemBlock;
use MediaWiki\Config\ServiceOptions;
use MediaWiki\MediaWikiServices;
/**
* @group Blocking
* @group Database
* @coversDefaultClass \MediaWiki\Block\BlockManager
*/
class BlockManagerTest extends MediaWikiTestCase {
/** @var User */
protected $user;
/** @var int */
protected $sysopId;
protected function setUp() {
parent::setUp();
$this->user = $this->getTestUser()->getUser();
$this->sysopId = $this->getTestSysop()->getUser()->getId();
$this->blockManagerConfig = [
'wgApplyIpBlocksToXff' => true,
'wgCookieSetOnAutoblock' => true,
'wgCookieSetOnIpBlock' => true,
'wgDnsBlacklistUrls' => [],
'wgEnableDnsBlacklist' => true,
'wgProxyList' => [],
'wgProxyWhitelist' => [],
'wgSecretKey' => false,
'wgSoftBlockRanges' => [],
];
}
private function getBlockManager( $overrideConfig ) {
return new BlockManager(
...$this->getBlockManagerConstructorArgs( $overrideConfig )
);
}
private function getBlockManagerConstructorArgs( $overrideConfig ) {
$blockManagerConfig = array_merge( $this->blockManagerConfig, $overrideConfig );
$this->setMwGlobals( $blockManagerConfig );
$this->overrideMwServices();
return [
new ServiceOptions(
BlockManager::$constructorOptions,
MediaWikiServices::getInstance()->getMainConfig()
),
$this->user,
$this->user->getRequest()
];
}
/**
* @dataProvider provideGetBlockFromCookieValue
* @covers ::getBlockFromCookieValue
* @covers ::shouldApplyCookieBlock
*/
public function testGetBlockFromCookieValue( $options, $expected ) {
$blockManager = $this->getBlockManager( [
'wgCookieSetOnAutoblock' => true,
'wgCookieSetOnIpBlock' => true,
] );
$block = new DatabaseBlock( array_merge( [
'address' => $options[ 'target' ] ?: $this->user,
'by' => $this->sysopId,
], $options[ 'blockOptions' ] ) );
$block->insert();
$class = new ReflectionClass( BlockManager::class );
$method = $class->getMethod( 'getBlockFromCookieValue' );
$method->setAccessible( true );
$user = $options[ 'loggedIn' ] ? $this->user : new User();
$user->getRequest()->setCookie( 'BlockID', $block->getCookieValue() );
$this->assertSame( $expected, (bool)$method->invoke(
$blockManager,
$user,
$user->getRequest()
) );
$block->delete();
}
public static function provideGetBlockFromCookieValue() {
return [
'Autoblocking user block' => [
[
'target' => '',
'loggedIn' => true,
'blockOptions' => [
'enableAutoblock' => true
],
],
true,
],
'Non-autoblocking user block' => [
[
'target' => '',
'loggedIn' => true,
'blockOptions' => [],
],
false,
],
'IP block for anonymous user' => [
[
'target' => '127.0.0.1',
'loggedIn' => false,
'blockOptions' => [],
],
true,
],
'IP block for logged in user' => [
[
'target' => '127.0.0.1',
'loggedIn' => true,
'blockOptions' => [],
],
false,
],
'IP range block for anonymous user' => [
[
'target' => '127.0.0.0/8',
'loggedIn' => false,
'blockOptions' => [],
],
true,
],
];
}
/**
* @dataProvider provideIsLocallyBlockedProxy
* @covers ::isLocallyBlockedProxy
*/
public function testIsLocallyBlockedProxy( $proxyList, $expected ) {
$class = new ReflectionClass( BlockManager::class );
$method = $class->getMethod( 'isLocallyBlockedProxy' );
$method->setAccessible( true );
$blockManager = $this->getBlockManager( [
'wgProxyList' => $proxyList
] );
$ip = '1.2.3.4';
$this->assertSame( $expected, $method->invoke( $blockManager, $ip ) );
}
public static function provideIsLocallyBlockedProxy() {
return [
'Proxy list is empty' => [ [], false ],
'Proxy list contains IP' => [ [ '1.2.3.4' ], true ],
'Proxy list contains IP as value' => [ [ 'test' => '1.2.3.4' ], true ],
'Proxy list contains range that covers IP' => [ [ '1.2.3.0/16' ], true ],
];
}
/**
* @covers ::isLocallyBlockedProxy
*/
public function testIsLocallyBlockedProxyDeprecated() {
$proxy = '1.2.3.4';
$this->hideDeprecated(
'IP addresses in the keys of $wgProxyList (found the following IP ' .
'addresses in keys: ' . $proxy . ', please move them to values)'
);
$class = new ReflectionClass( BlockManager::class );
$method = $class->getMethod( 'isLocallyBlockedProxy' );
$method->setAccessible( true );
$blockManager = $this->getBlockManager( [
'wgProxyList' => [ $proxy => 'test' ]
] );
$ip = '1.2.3.4';
$this->assertSame( true, $method->invoke( $blockManager, $ip ) );
}
/**
* @dataProvider provideIsDnsBlacklisted
* @covers ::isDnsBlacklisted
* @covers ::inDnsBlacklist
*/
public function testIsDnsBlacklisted( $options, $expected ) {
$blockManagerConfig = [
'wgEnableDnsBlacklist' => true,
'wgDnsBlacklistUrls' => $options['blacklist'],
'wgProxyWhitelist' => $options['whitelist'],
];
$blockManager = $this->getMockBuilder( BlockManager::class )
->setConstructorArgs( $this->getBlockManagerConstructorArgs( $blockManagerConfig ) )
->setMethods( [ 'checkHost' ] )
->getMock();
$blockManager->expects( $this->any() )
->method( 'checkHost' )
->will( $this->returnValueMap( [ [
$options['dnsblQuery'],
$options['dnsblResponse'],
] ] ) );
$this->assertSame(
$expected,
$blockManager->isDnsBlacklisted( $options['ip'], $options['checkWhitelist'] )
);
}
public static function provideIsDnsBlacklisted() {
$dnsblFound = [ '127.0.0.2' ];
$dnsblNotFound = false;
return [
'IP is blacklisted' => [
[
'blacklist' => [ 'dnsbl.test' ],
'ip' => '127.0.0.1',
'dnsblQuery' => '1.0.0.127.dnsbl.test',
'dnsblResponse' => $dnsblFound,
'whitelist' => [],
'checkWhitelist' => false,
],
true,
],
'IP is blacklisted; blacklist has key' => [
[
'blacklist' => [ [ 'dnsbl.test', 'key' ] ],
'ip' => '127.0.0.1',
'dnsblQuery' => 'key.1.0.0.127.dnsbl.test',
'dnsblResponse' => $dnsblFound,
'whitelist' => [],
'checkWhitelist' => false,
],
true,
],
'IP is blacklisted; blacklist is array' => [
[
'blacklist' => [ [ 'dnsbl.test' ] ],
'ip' => '127.0.0.1',
'dnsblQuery' => '1.0.0.127.dnsbl.test',
'dnsblResponse' => $dnsblFound,
'whitelist' => [],
'checkWhitelist' => false,
],
true,
],
'IP is not blacklisted' => [
[
'blacklist' => [ 'dnsbl.test' ],
'ip' => '1.2.3.4',
'dnsblQuery' => '4.3.2.1.dnsbl.test',
'dnsblResponse' => $dnsblNotFound,
'whitelist' => [],
'checkWhitelist' => false,
],
false,
],
'Blacklist is empty' => [
[
'blacklist' => [],
'ip' => '127.0.0.1',
'dnsblQuery' => '1.0.0.127.dnsbl.test',
'dnsblResponse' => $dnsblFound,
'whitelist' => [],
'checkWhitelist' => false,
],
false,
],
'IP is blacklisted and whitelisted; whitelist is not checked' => [
[
'blacklist' => [ 'dnsbl.test' ],
'ip' => '127.0.0.1',
'dnsblQuery' => '1.0.0.127.dnsbl.test',
'dnsblResponse' => $dnsblFound,
'whitelist' => [ '127.0.0.1' ],
'checkWhitelist' => false,
],
true,
],
'IP is blacklisted and whitelisted; whitelist is checked' => [
[
'blacklist' => [ 'dnsbl.test' ],
'ip' => '127.0.0.1',
'dnsblQuery' => '1.0.0.127.dnsbl.test',
'dnsblResponse' => $dnsblFound,
'whitelist' => [ '127.0.0.1' ],
'checkWhitelist' => true,
],
false,
],
];
}
/**
* @covers ::getUniqueBlocks
*/
public function testGetUniqueBlocks() {
$blockId = 100;
$class = new ReflectionClass( BlockManager::class );
$method = $class->getMethod( 'getUniqueBlocks' );
$method->setAccessible( true );
$blockManager = $this->getBlockManager( [] );
$block = $this->getMockBuilder( DatabaseBlock::class )
->setMethods( [ 'getId' ] )
->getMock();
$block->expects( $this->any() )
->method( 'getId' )
->willReturn( $blockId );
$autoblock = $this->getMockBuilder( DatabaseBlock::class )
->setMethods( [ 'getParentBlockId', 'getType' ] )
->getMock();
$autoblock->expects( $this->any() )
->method( 'getParentBlockId' )
->willReturn( $blockId );
$autoblock->expects( $this->any() )
->method( 'getType' )
->willReturn( DatabaseBlock::TYPE_AUTO );
$blocks = [ $block, $block, $autoblock, new SystemBlock() ];
$this->assertSame( 2, count( $method->invoke( $blockManager, $blocks ) ) );
}
/**
* @covers ::trackBlockWithCookie
* @dataProvider provideTrackBlockWithCookie
* @param bool $expectCookieSet
* @param bool $hasCookie
* @param bool $isBlocked
*/
public function testTrackBlockWithCookie( $expectCookieSet, $hasCookie, $isBlocked ) {
$blockID = 123;
$this->setMwGlobals( 'wgCookiePrefix', '' );
$request = new FauxRequest();
if ( $hasCookie ) {
$request->setCookie( 'BlockID', 'the value does not matter' );
}
if ( $isBlocked ) {
$block = $this->getMockBuilder( DatabaseBlock::class )
->setMethods( [ 'getType', 'getId' ] )
->getMock();
$block->method( 'getType' )
->willReturn( DatabaseBlock::TYPE_IP );
$block->method( 'getId' )
->willReturn( $blockID );
} else {
$block = null;
}
$user = $this->getMockBuilder( User::class )
->setMethods( [ 'getBlock', 'getRequest' ] )
->getMock();
$user->method( 'getBlock' )
->willReturn( $block );
$user->method( 'getRequest' )
->willReturn( $request );
/** @var User $user */
// Although the block cookie is set via DeferredUpdates, in command line mode updates are
// processed immediately
$blockManager = $this->getBlockManager( [] );
$blockManager->trackBlockWithCookie( $user );
/** @var FauxResponse $response */
$response = $request->response();
$this->assertCount( $expectCookieSet ? 1 : 0, $response->getCookies() );
$this->assertEquals( $expectCookieSet ? $blockID : null, $response->getCookie( 'BlockID' ) );
}
public function provideTrackBlockWithCookie() {
return [
// $expectCookieSet, $hasCookie, $isBlocked
[ false, false, false ],
[ false, true, false ],
[ true, false, true ],
[ false, true, true ],
];
}
}