2018-08-27 22:19:37 +00:00
|
|
|
<?php
|
|
|
|
|
|
2019-04-11 19:54:10 +00:00
|
|
|
use MediaWiki\Block\BlockRestrictionStore;
|
2019-05-13 14:18:07 +00:00
|
|
|
use MediaWiki\Block\DatabaseBlock;
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
use MediaWiki\Block\Restriction\ActionRestriction;
|
2018-12-14 21:08:40 +00:00
|
|
|
use MediaWiki\Block\Restriction\NamespaceRestriction;
|
2020-01-10 00:00:51 +00:00
|
|
|
use MediaWiki\Block\Restriction\PageRestriction;
|
2022-08-14 13:47:11 +00:00
|
|
|
use MediaWiki\MainConfigNames;
|
2022-10-28 10:04:25 +00:00
|
|
|
use MediaWiki\Request\FauxRequest;
|
2023-03-17 14:37:51 +00:00
|
|
|
use MediaWiki\Specials\SpecialBlock;
|
2023-05-05 13:13:06 +00:00
|
|
|
use Wikimedia\Rdbms\IConnectionProvider;
|
2020-01-10 00:00:51 +00:00
|
|
|
use Wikimedia\TestingAccessWrapper;
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @group Blocking
|
|
|
|
|
* @group Database
|
2023-05-27 09:43:12 +00:00
|
|
|
* @coversDefaultClass MediaWiki\Specials\SpecialBlock
|
2018-08-27 22:19:37 +00:00
|
|
|
*/
|
|
|
|
|
class SpecialBlockTest extends SpecialPageTestBase {
|
|
|
|
|
/**
|
2019-02-26 12:57:24 +00:00
|
|
|
* @inheritDoc
|
2018-08-27 22:19:37 +00:00
|
|
|
*/
|
|
|
|
|
protected function newSpecialPage() {
|
2022-01-12 20:13:39 +00:00
|
|
|
$services = $this->getServiceContainer();
|
2020-05-08 22:31:17 +00:00
|
|
|
return new SpecialBlock(
|
2020-10-05 16:08:10 +00:00
|
|
|
$services->getBlockUtils(),
|
|
|
|
|
$services->getBlockPermissionCheckerFactory(),
|
|
|
|
|
$services->getBlockUserFactory(),
|
|
|
|
|
$services->getUserNameUtils(),
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
$services->getUserNamePrefixSearch(),
|
2021-05-30 16:18:26 +00:00
|
|
|
$services->getBlockActionInfo(),
|
2021-08-16 16:50:55 +00:00
|
|
|
$services->getTitleFormatter(),
|
|
|
|
|
$services->getNamespaceInfo()
|
2020-05-08 22:31:17 +00:00
|
|
|
);
|
2018-08-27 22:19:37 +00:00
|
|
|
}
|
|
|
|
|
|
2021-07-22 03:11:47 +00:00
|
|
|
protected function tearDown(): void {
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->resetTables();
|
2020-12-20 01:52:16 +00:00
|
|
|
parent::tearDown();
|
2018-08-27 22:19:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers ::getFormFields()
|
|
|
|
|
*/
|
|
|
|
|
public function testGetFormFields() {
|
2022-08-14 13:47:11 +00:00
|
|
|
$this->overrideConfigValues( [
|
|
|
|
|
MainConfigNames::BlockAllowsUTEdit => true,
|
|
|
|
|
MainConfigNames::EnablePartialActionBlocks => true,
|
2018-08-27 22:19:37 +00:00
|
|
|
] );
|
|
|
|
|
$page = $this->newSpecialPage();
|
|
|
|
|
$wrappedPage = TestingAccessWrapper::newFromObject( $page );
|
|
|
|
|
$fields = $wrappedPage->getFormFields();
|
2019-12-13 14:29:10 +00:00
|
|
|
$this->assertIsArray( $fields );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertArrayHasKey( 'Target', $fields );
|
|
|
|
|
$this->assertArrayHasKey( 'Expiry', $fields );
|
|
|
|
|
$this->assertArrayHasKey( 'Reason', $fields );
|
|
|
|
|
$this->assertArrayHasKey( 'CreateAccount', $fields );
|
|
|
|
|
$this->assertArrayHasKey( 'DisableUTEdit', $fields );
|
|
|
|
|
$this->assertArrayHasKey( 'AutoBlock', $fields );
|
|
|
|
|
$this->assertArrayHasKey( 'HardBlock', $fields );
|
|
|
|
|
$this->assertArrayHasKey( 'PreviousTarget', $fields );
|
|
|
|
|
$this->assertArrayHasKey( 'Confirm', $fields );
|
|
|
|
|
$this->assertArrayHasKey( 'EditingRestriction', $fields );
|
|
|
|
|
$this->assertArrayHasKey( 'PageRestrictions', $fields );
|
2018-12-14 21:08:40 +00:00
|
|
|
$this->assertArrayHasKey( 'NamespaceRestrictions', $fields );
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
$this->assertArrayHasKey( 'ActionRestrictions', $fields );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers ::getFormFields()
|
|
|
|
|
*/
|
|
|
|
|
public function testGetFormFieldsActionRestrictionDisabled() {
|
2022-08-14 13:47:11 +00:00
|
|
|
$this->overrideConfigValue( MainConfigNames::EnablePartialActionBlocks, false );
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
$page = $this->newSpecialPage();
|
|
|
|
|
$wrappedPage = TestingAccessWrapper::newFromObject( $page );
|
|
|
|
|
$fields = $wrappedPage->getFormFields();
|
|
|
|
|
$this->assertArrayNotHasKey( 'ActionRestrictions', $fields );
|
2018-08-27 22:19:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers ::maybeAlterFormDefaults()
|
|
|
|
|
*/
|
|
|
|
|
public function testMaybeAlterFormDefaults() {
|
2022-08-14 13:47:11 +00:00
|
|
|
$this->overrideConfigValue( MainConfigNames::BlockAllowsUTEdit, true );
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
$block = $this->insertBlock();
|
|
|
|
|
|
|
|
|
|
// Refresh the block from the database.
|
2021-06-03 10:25:17 +00:00
|
|
|
$block = DatabaseBlock::newFromTarget( $block->getTargetUserIdentity() );
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
$page = $this->newSpecialPage();
|
|
|
|
|
|
|
|
|
|
$wrappedPage = TestingAccessWrapper::newFromObject( $page );
|
2021-06-03 10:25:17 +00:00
|
|
|
$wrappedPage->target = $block->getTargetUserIdentity();
|
2018-08-27 22:19:37 +00:00
|
|
|
$fields = $wrappedPage->getFormFields();
|
|
|
|
|
|
2021-06-03 10:25:17 +00:00
|
|
|
$this->assertSame( $block->getTargetName(), $fields['Target']['default'] );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertSame( $block->isHardblock(), $fields['HardBlock']['default'] );
|
Separate out different functionalities of Block::prevents
Block::prevents plays several different roles:
* acts as get/setter for Boolean properties that correspond to
ipb_create_account, ipb_block_email and ipb_allow_usertalk
* calculates whether a block blocks a given right, based on Block
properties, global configs, white/blacklists and anonymous user
rights
* decides whether a block prevents editing of the target's own
user talk page (listed separately because 'editownusertalk' is
not a right)
This patch:
* renames mDisableUsertalk to allowEditUsertalk (and reverses the
value), to match the field ipb_allow_usertalk and make this logic
easier to follow
* renames mCreateAccount to blockCreateAccount, to make it clear
that the flag blocks account creation when true, and make this
logic easier to follow
* decouples the block that is stored in the database (which now
reflects the form that the admin submitted) and the behaviour of
the block on enforcement (since the properties set by the admin
can be overridden by global configs) - so if the global configs
change, the block behaviour could too
* creates get/setters for blockCreateAccount, mBlockEmail and
allowEditUsertalk properties
* creates appliesToRight, exclusively for checking whether the
block blocks a given right, taking into account the block
properties, global configs and anonymous user rights
* creates appliesToUsertalk, for checking whether the block
blocks a user from editing their own talk page. The block is
unaware of the user trying to make the edit, and this user is not
always the same as the block target, e.g. if the block target is
an IP range. Therefore the user's talk page is passed in to this
method. appliesToUsertalk can be called from anywhere where the
user is known
* uses the get/setters wherever Block::prevents was being used as
such
* uses appliesToRight whenever Block::prevents was being used to
determine if the block blocks a given right
* uses appliesToUsertalk in User::isBlockedFrom
Bug: T211578
Bug: T214508
Change-Id: I0e131696419211319082cb454f4f05297e55d22e
2019-02-09 12:17:54 +00:00
|
|
|
$this->assertSame( $block->isCreateAccountBlocked(), $fields['CreateAccount']['default'] );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertSame( $block->isAutoblocking(), $fields['AutoBlock']['default'] );
|
Separate out different functionalities of Block::prevents
Block::prevents plays several different roles:
* acts as get/setter for Boolean properties that correspond to
ipb_create_account, ipb_block_email and ipb_allow_usertalk
* calculates whether a block blocks a given right, based on Block
properties, global configs, white/blacklists and anonymous user
rights
* decides whether a block prevents editing of the target's own
user talk page (listed separately because 'editownusertalk' is
not a right)
This patch:
* renames mDisableUsertalk to allowEditUsertalk (and reverses the
value), to match the field ipb_allow_usertalk and make this logic
easier to follow
* renames mCreateAccount to blockCreateAccount, to make it clear
that the flag blocks account creation when true, and make this
logic easier to follow
* decouples the block that is stored in the database (which now
reflects the form that the admin submitted) and the behaviour of
the block on enforcement (since the properties set by the admin
can be overridden by global configs) - so if the global configs
change, the block behaviour could too
* creates get/setters for blockCreateAccount, mBlockEmail and
allowEditUsertalk properties
* creates appliesToRight, exclusively for checking whether the
block blocks a given right, taking into account the block
properties, global configs and anonymous user rights
* creates appliesToUsertalk, for checking whether the block
blocks a user from editing their own talk page. The block is
unaware of the user trying to make the edit, and this user is not
always the same as the block target, e.g. if the block target is
an IP range. Therefore the user's talk page is passed in to this
method. appliesToUsertalk can be called from anywhere where the
user is known
* uses the get/setters wherever Block::prevents was being used as
such
* uses appliesToRight whenever Block::prevents was being used to
determine if the block blocks a given right
* uses appliesToUsertalk in User::isBlockedFrom
Bug: T211578
Bug: T214508
Change-Id: I0e131696419211319082cb454f4f05297e55d22e
2019-02-09 12:17:54 +00:00
|
|
|
$this->assertSame( !$block->isUsertalkEditAllowed(), $fields['DisableUTEdit']['default'] );
|
2019-10-20 00:04:00 +00:00
|
|
|
$this->assertSame( $block->getReasonComment()->text, $fields['Reason']['default'] );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertSame( 'infinite', $fields['Expiry']['default'] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers ::maybeAlterFormDefaults()
|
|
|
|
|
*/
|
|
|
|
|
public function testMaybeAlterFormDefaultsPartial() {
|
2022-08-14 13:47:11 +00:00
|
|
|
$this->overrideConfigValue( MainConfigNames::EnablePartialActionBlocks, true );
|
2018-08-27 22:19:37 +00:00
|
|
|
$badActor = $this->getTestUser()->getUser();
|
|
|
|
|
$sysop = $this->getTestSysop()->getUser();
|
|
|
|
|
$pageSaturn = $this->getExistingTestPage( 'Saturn' );
|
|
|
|
|
$pageMars = $this->getExistingTestPage( 'Mars' );
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
$actionId = 100;
|
2018-08-27 22:19:37 +00:00
|
|
|
|
2019-05-13 14:18:07 +00:00
|
|
|
$block = new DatabaseBlock( [
|
2018-08-27 22:19:37 +00:00
|
|
|
'address' => $badActor->getName(),
|
|
|
|
|
'user' => $badActor->getId(),
|
2021-06-02 09:44:38 +00:00
|
|
|
'by' => $sysop,
|
2018-08-27 22:19:37 +00:00
|
|
|
'expiry' => 'infinity',
|
|
|
|
|
'sitewide' => 0,
|
|
|
|
|
'enableAutoblock' => true,
|
|
|
|
|
] );
|
|
|
|
|
|
|
|
|
|
$block->setRestrictions( [
|
|
|
|
|
new PageRestriction( 0, $pageSaturn->getId() ),
|
|
|
|
|
new PageRestriction( 0, $pageMars->getId() ),
|
2018-12-14 21:08:40 +00:00
|
|
|
new NamespaceRestriction( 0, NS_TALK ),
|
2019-01-30 23:45:36 +00:00
|
|
|
// Deleted page.
|
|
|
|
|
new PageRestriction( 0, 999999 ),
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
new ActionRestriction( 0, $actionId ),
|
2018-08-27 22:19:37 +00:00
|
|
|
] );
|
|
|
|
|
|
2022-01-12 20:13:39 +00:00
|
|
|
$this->getServiceContainer()->getDatabaseBlockStore()->insertBlock( $block );
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
// Refresh the block from the database.
|
2021-06-03 10:25:17 +00:00
|
|
|
$block = DatabaseBlock::newFromTarget( $block->getTargetUserIdentity() );
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
$page = $this->newSpecialPage();
|
|
|
|
|
|
|
|
|
|
$wrappedPage = TestingAccessWrapper::newFromObject( $page );
|
2021-06-03 10:25:17 +00:00
|
|
|
$wrappedPage->target = $block->getTargetUserIdentity();
|
2018-08-27 22:19:37 +00:00
|
|
|
$fields = $wrappedPage->getFormFields();
|
|
|
|
|
|
|
|
|
|
$titles = [
|
|
|
|
|
$pageMars->getTitle()->getPrefixedText(),
|
|
|
|
|
$pageSaturn->getTitle()->getPrefixedText(),
|
|
|
|
|
];
|
|
|
|
|
|
2021-06-03 10:25:17 +00:00
|
|
|
$this->assertSame( $block->getTargetName(), $fields['Target']['default'] );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertSame( 'partial', $fields['EditingRestriction']['default'] );
|
|
|
|
|
$this->assertSame( implode( "\n", $titles ), $fields['PageRestrictions']['default'] );
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
$this->assertSame( [ $actionId ], $fields['ActionRestrictions']['default'] );
|
2018-08-27 22:19:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers ::processForm()
|
|
|
|
|
*/
|
|
|
|
|
public function testProcessForm() {
|
2021-03-19 13:56:13 +00:00
|
|
|
$badActor = $this->getTestUser()->getUserIdentity();
|
2018-08-27 22:19:37 +00:00
|
|
|
$context = RequestContext::getMain();
|
2020-04-23 19:33:56 +00:00
|
|
|
$context->setUser( $this->getTestSysop()->getUser() );
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
$page = $this->newSpecialPage();
|
|
|
|
|
$reason = 'test';
|
|
|
|
|
$expiry = 'infinity';
|
|
|
|
|
$data = [
|
|
|
|
|
'Target' => (string)$badActor,
|
|
|
|
|
'Expiry' => 'infinity',
|
|
|
|
|
'Reason' => [
|
|
|
|
|
$reason,
|
|
|
|
|
],
|
|
|
|
|
'Confirm' => '1',
|
|
|
|
|
'CreateAccount' => '0',
|
|
|
|
|
'DisableUTEdit' => '0',
|
|
|
|
|
'DisableEmail' => '0',
|
|
|
|
|
'HardBlock' => '0',
|
|
|
|
|
'AutoBlock' => '1',
|
|
|
|
|
'HideUser' => '0',
|
|
|
|
|
'Watch' => '0',
|
|
|
|
|
];
|
|
|
|
|
$result = $page->processForm( $data, $context );
|
|
|
|
|
|
|
|
|
|
$this->assertTrue( $result );
|
|
|
|
|
|
2019-05-13 14:18:07 +00:00
|
|
|
$block = DatabaseBlock::newFromTarget( $badActor );
|
2019-10-20 00:04:00 +00:00
|
|
|
$this->assertSame( $reason, $block->getReasonComment()->text );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertSame( $expiry, $block->getExpiry() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers ::processForm()
|
|
|
|
|
*/
|
|
|
|
|
public function testProcessFormExisting() {
|
|
|
|
|
$badActor = $this->getTestUser()->getUser();
|
|
|
|
|
$sysop = $this->getTestSysop()->getUser();
|
|
|
|
|
$context = RequestContext::getMain();
|
2020-04-23 19:33:56 +00:00
|
|
|
$context->setUser( $sysop );
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
// Create a block that will be updated.
|
2019-05-13 14:18:07 +00:00
|
|
|
$block = new DatabaseBlock( [
|
2018-08-27 22:19:37 +00:00
|
|
|
'address' => $badActor->getName(),
|
|
|
|
|
'user' => $badActor->getId(),
|
2021-06-02 09:44:38 +00:00
|
|
|
'by' => $sysop,
|
2018-08-27 22:19:37 +00:00
|
|
|
'expiry' => 'infinity',
|
|
|
|
|
'sitewide' => 0,
|
|
|
|
|
'enableAutoblock' => false,
|
|
|
|
|
] );
|
2022-01-12 20:13:39 +00:00
|
|
|
$this->getServiceContainer()->getDatabaseBlockStore()->insertBlock( $block );
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
$page = $this->newSpecialPage();
|
|
|
|
|
$reason = 'test';
|
|
|
|
|
$expiry = 'infinity';
|
|
|
|
|
$data = [
|
|
|
|
|
'Target' => (string)$badActor,
|
|
|
|
|
'Expiry' => 'infinity',
|
|
|
|
|
'Reason' => [
|
|
|
|
|
$reason,
|
|
|
|
|
],
|
|
|
|
|
'Confirm' => '1',
|
|
|
|
|
'CreateAccount' => '0',
|
|
|
|
|
'DisableUTEdit' => '0',
|
|
|
|
|
'DisableEmail' => '0',
|
|
|
|
|
'HardBlock' => '0',
|
|
|
|
|
'AutoBlock' => '1',
|
|
|
|
|
'HideUser' => '0',
|
|
|
|
|
'Watch' => '0',
|
|
|
|
|
];
|
|
|
|
|
$result = $page->processForm( $data, $context );
|
|
|
|
|
|
|
|
|
|
$this->assertTrue( $result );
|
|
|
|
|
|
2019-05-13 14:18:07 +00:00
|
|
|
$block = DatabaseBlock::newFromTarget( $badActor );
|
2019-10-20 00:04:00 +00:00
|
|
|
$this->assertSame( $reason, $block->getReasonComment()->text );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertSame( $expiry, $block->getExpiry() );
|
2020-12-20 01:52:16 +00:00
|
|
|
$this->assertTrue( $block->isAutoblocking() );
|
2018-08-27 22:19:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers ::processForm()
|
|
|
|
|
*/
|
2018-12-14 21:08:40 +00:00
|
|
|
public function testProcessFormRestrictions() {
|
2022-08-14 13:47:11 +00:00
|
|
|
$this->overrideConfigValue( MainConfigNames::EnablePartialActionBlocks, true );
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
|
2018-08-27 22:19:37 +00:00
|
|
|
$badActor = $this->getTestUser()->getUser();
|
|
|
|
|
$context = RequestContext::getMain();
|
2020-04-23 19:33:56 +00:00
|
|
|
$context->setUser( $this->getTestSysop()->getUser() );
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
$pageSaturn = $this->getExistingTestPage( 'Saturn' );
|
|
|
|
|
$pageMars = $this->getExistingTestPage( 'Mars' );
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
$actionId = 100;
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
$titles = [
|
|
|
|
|
$pageSaturn->getTitle()->getText(),
|
|
|
|
|
$pageMars->getTitle()->getText(),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$page = $this->newSpecialPage();
|
|
|
|
|
$reason = 'test';
|
|
|
|
|
$expiry = 'infinity';
|
|
|
|
|
$data = [
|
|
|
|
|
'Target' => (string)$badActor,
|
|
|
|
|
'Expiry' => 'infinity',
|
|
|
|
|
'Reason' => [
|
|
|
|
|
$reason,
|
|
|
|
|
],
|
|
|
|
|
'Confirm' => '1',
|
|
|
|
|
'CreateAccount' => '0',
|
|
|
|
|
'DisableUTEdit' => '0',
|
|
|
|
|
'DisableEmail' => '0',
|
|
|
|
|
'HardBlock' => '0',
|
|
|
|
|
'AutoBlock' => '1',
|
|
|
|
|
'HideUser' => '0',
|
|
|
|
|
'Watch' => '0',
|
|
|
|
|
'EditingRestriction' => 'partial',
|
|
|
|
|
'PageRestrictions' => implode( "\n", $titles ),
|
2018-12-14 21:08:40 +00:00
|
|
|
'NamespaceRestrictions' => '',
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
'ActionRestrictions' => [ $actionId ],
|
2018-08-27 22:19:37 +00:00
|
|
|
];
|
|
|
|
|
$result = $page->processForm( $data, $context );
|
|
|
|
|
|
|
|
|
|
$this->assertTrue( $result );
|
|
|
|
|
|
2019-05-13 14:18:07 +00:00
|
|
|
$block = DatabaseBlock::newFromTarget( $badActor );
|
2019-10-20 00:04:00 +00:00
|
|
|
$this->assertSame( $reason, $block->getReasonComment()->text );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertSame( $expiry, $block->getExpiry() );
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
$this->assertCount( 3, $block->getRestrictions() );
|
2019-04-11 19:54:10 +00:00
|
|
|
$this->assertTrue( $this->getBlockRestrictionStore()->equals( $block->getRestrictions(), [
|
2018-08-27 22:19:37 +00:00
|
|
|
new PageRestriction( $block->getId(), $pageMars->getId() ),
|
|
|
|
|
new PageRestriction( $block->getId(), $pageSaturn->getId() ),
|
Introduce infrastructure for partial blocks for actions
This adds a new type of block restriction for actions, which extends
AbstractRestriction. Like page and namespace restrictions, action
restrictions are stored in the ipblocks_restrictions table.
Blockable actions are defined in a BlockActionInfo service, with a
method for getting all the blockable actions, getAllBlockActions.
Action blocks are checked for in PermissionManager::checkUserBlock
using DatabaseBlock::appliesToRight. To make this work, this patch
also removes the 'edit' case from AbstractBlock::appliesToRight,
which always returned true. This was incorrect, as blocks do not
always apply to edit, so cases that called appliesToRight('edit')
were fixed before this commit. appliesToRight('edit') now returns
null (i.e. unsure), which is correct because it is not possible to
determine whether a block applies to editing a particular page
without knowing what that page is, and appliesToRight doesn't know
that page.
There are some flags on sitewide blocks that predate partial blocks,
which block particular actions: 'createaccount' and 'sendemail'.
These are still handled in AbstractBlock::appliesToRight, and are
still checked for separately in the peripheral components.
The feature flag $wgEnablePartialActionBlocks must set to true to
enable partial action blocks.
Bug: T279556
Bug: T6995
Change-Id: I17962bb7c4247a12c722e7bc6bcaf8c36efd8600
2021-04-26 23:07:17 +00:00
|
|
|
new ActionRestriction( $block->getId(), $actionId ),
|
2018-08-27 22:19:37 +00:00
|
|
|
] ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers ::processForm()
|
|
|
|
|
*/
|
|
|
|
|
public function testProcessFormRestrictionsChange() {
|
|
|
|
|
$badActor = $this->getTestUser()->getUser();
|
|
|
|
|
$context = RequestContext::getMain();
|
2020-04-23 19:33:56 +00:00
|
|
|
$context->setUser( $this->getTestSysop()->getUser() );
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
$pageSaturn = $this->getExistingTestPage( 'Saturn' );
|
|
|
|
|
$pageMars = $this->getExistingTestPage( 'Mars' );
|
|
|
|
|
|
|
|
|
|
$titles = [
|
|
|
|
|
$pageSaturn->getTitle()->getText(),
|
|
|
|
|
$pageMars->getTitle()->getText(),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Create a partial block.
|
|
|
|
|
$page = $this->newSpecialPage();
|
|
|
|
|
$reason = 'test';
|
|
|
|
|
$expiry = 'infinity';
|
|
|
|
|
$data = [
|
|
|
|
|
'Target' => (string)$badActor,
|
|
|
|
|
'Expiry' => 'infinity',
|
|
|
|
|
'Reason' => [
|
|
|
|
|
$reason,
|
|
|
|
|
],
|
|
|
|
|
'Confirm' => '1',
|
2020-09-18 21:29:24 +00:00
|
|
|
'CreateAccount' => '1',
|
2018-08-27 22:19:37 +00:00
|
|
|
'DisableUTEdit' => '0',
|
|
|
|
|
'DisableEmail' => '0',
|
|
|
|
|
'HardBlock' => '0',
|
|
|
|
|
'AutoBlock' => '1',
|
|
|
|
|
'HideUser' => '0',
|
|
|
|
|
'Watch' => '0',
|
|
|
|
|
'EditingRestriction' => 'partial',
|
|
|
|
|
'PageRestrictions' => implode( "\n", $titles ),
|
2018-12-14 21:08:40 +00:00
|
|
|
'NamespaceRestrictions' => '',
|
2018-08-27 22:19:37 +00:00
|
|
|
];
|
|
|
|
|
$result = $page->processForm( $data, $context );
|
|
|
|
|
|
|
|
|
|
$this->assertTrue( $result );
|
|
|
|
|
|
2019-05-13 14:18:07 +00:00
|
|
|
$block = DatabaseBlock::newFromTarget( $badActor );
|
2019-10-20 00:04:00 +00:00
|
|
|
$this->assertSame( $reason, $block->getReasonComment()->text );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertSame( $expiry, $block->getExpiry() );
|
|
|
|
|
$this->assertFalse( $block->isSitewide() );
|
2020-09-18 21:29:24 +00:00
|
|
|
$this->assertTrue( $block->isCreateAccountBlocked() );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertCount( 2, $block->getRestrictions() );
|
2019-04-11 19:54:10 +00:00
|
|
|
$this->assertTrue( $this->getBlockRestrictionStore()->equals( $block->getRestrictions(), [
|
2018-08-27 22:19:37 +00:00
|
|
|
new PageRestriction( $block->getId(), $pageMars->getId() ),
|
|
|
|
|
new PageRestriction( $block->getId(), $pageSaturn->getId() ),
|
|
|
|
|
] ) );
|
|
|
|
|
|
|
|
|
|
// Remove a page from the partial block.
|
|
|
|
|
$data['PageRestrictions'] = $pageMars->getTitle()->getText();
|
|
|
|
|
$result = $page->processForm( $data, $context );
|
|
|
|
|
|
|
|
|
|
$this->assertTrue( $result );
|
|
|
|
|
|
2019-05-13 14:18:07 +00:00
|
|
|
$block = DatabaseBlock::newFromTarget( $badActor );
|
2019-10-20 00:04:00 +00:00
|
|
|
$this->assertSame( $reason, $block->getReasonComment()->text );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertSame( $expiry, $block->getExpiry() );
|
|
|
|
|
$this->assertFalse( $block->isSitewide() );
|
2020-09-18 21:29:24 +00:00
|
|
|
$this->assertTrue( $block->isCreateAccountBlocked() );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertCount( 1, $block->getRestrictions() );
|
2019-04-11 19:54:10 +00:00
|
|
|
$this->assertTrue( $this->getBlockRestrictionStore()->equals( $block->getRestrictions(), [
|
2018-08-27 22:19:37 +00:00
|
|
|
new PageRestriction( $block->getId(), $pageMars->getId() ),
|
|
|
|
|
] ) );
|
|
|
|
|
|
|
|
|
|
// Remove the last page from the block.
|
|
|
|
|
$data['PageRestrictions'] = '';
|
|
|
|
|
$result = $page->processForm( $data, $context );
|
|
|
|
|
|
|
|
|
|
$this->assertTrue( $result );
|
|
|
|
|
|
2019-05-13 14:18:07 +00:00
|
|
|
$block = DatabaseBlock::newFromTarget( $badActor );
|
2019-10-20 00:04:00 +00:00
|
|
|
$this->assertSame( $reason, $block->getReasonComment()->text );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertSame( $expiry, $block->getExpiry() );
|
|
|
|
|
$this->assertFalse( $block->isSitewide() );
|
2020-09-18 21:29:24 +00:00
|
|
|
$this->assertTrue( $block->isCreateAccountBlocked() );
|
2020-02-28 15:45:22 +00:00
|
|
|
$this->assertSame( [], $block->getRestrictions() );
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
// Change to sitewide.
|
|
|
|
|
$data['EditingRestriction'] = 'sitewide';
|
|
|
|
|
$result = $page->processForm( $data, $context );
|
|
|
|
|
|
|
|
|
|
$this->assertTrue( $result );
|
|
|
|
|
|
2019-05-13 14:18:07 +00:00
|
|
|
$block = DatabaseBlock::newFromTarget( $badActor );
|
2019-10-20 00:04:00 +00:00
|
|
|
$this->assertSame( $reason, $block->getReasonComment()->text );
|
2018-08-27 22:19:37 +00:00
|
|
|
$this->assertSame( $expiry, $block->getExpiry() );
|
|
|
|
|
$this->assertTrue( $block->isSitewide() );
|
2020-02-28 15:45:22 +00:00
|
|
|
$this->assertSame( [], $block->getRestrictions() );
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
// Ensure that there are no restrictions where the blockId is 0.
|
|
|
|
|
$count = $this->db->selectRowCount(
|
|
|
|
|
'ipblocks_restrictions',
|
|
|
|
|
'*',
|
|
|
|
|
[ 'ir_ipb_id' => 0 ],
|
|
|
|
|
__METHOD__
|
|
|
|
|
);
|
|
|
|
|
$this->assertSame( 0, $count );
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-10 11:28:42 +00:00
|
|
|
/**
|
|
|
|
|
* @dataProvider provideProcessFormUserTalkEditFlag
|
|
|
|
|
* @covers ::processForm()
|
|
|
|
|
*/
|
|
|
|
|
public function testProcessFormUserTalkEditFlag( $options, $expected ) {
|
2022-08-14 13:47:11 +00:00
|
|
|
$this->overrideConfigValue( MainConfigNames::BlockAllowsUTEdit, $options['configAllowsUserTalkEdit'] );
|
2020-09-10 11:28:42 +00:00
|
|
|
|
|
|
|
|
$performer = $this->getTestSysop()->getUser();
|
|
|
|
|
$target = $this->getTestUser()->getUser();
|
|
|
|
|
|
|
|
|
|
$context = new DerivativeContext( RequestContext::getMain() );
|
|
|
|
|
$context->setUser( $performer );
|
|
|
|
|
|
|
|
|
|
$data = [
|
|
|
|
|
'Target' => $target,
|
|
|
|
|
'PreviousTarget' => $target,
|
|
|
|
|
'Expiry' => 'infinity',
|
2020-09-18 23:07:17 +00:00
|
|
|
'CreateAccount' => '1',
|
2020-09-10 11:28:42 +00:00
|
|
|
'DisableEmail' => '0',
|
|
|
|
|
'HardBlock' => '0',
|
|
|
|
|
'AutoBlock' => '0',
|
|
|
|
|
'Watch' => '0',
|
|
|
|
|
'Confirm' => '1',
|
|
|
|
|
'DisableUTEdit' => $options['optionBlocksUserTalkEdit'],
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
if ( !$options['userTalkNamespaceBlocked'] ) {
|
|
|
|
|
$data['EditingRestriction'] = 'partial';
|
|
|
|
|
$data['PageRestrictions'] = '';
|
|
|
|
|
$data['NamespaceRestrictions'] = '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$result = $this->newSpecialPage()->processForm(
|
|
|
|
|
$data,
|
|
|
|
|
$context
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if ( $expected === 'ipb-prevent-user-talk-edit' ) {
|
2020-04-23 19:33:56 +00:00
|
|
|
$this->assertSame( $expected, $result->getErrorsArray()[0][0] );
|
2020-09-10 11:28:42 +00:00
|
|
|
} else {
|
|
|
|
|
$block = DatabaseBlock::newFromTarget( $target );
|
|
|
|
|
$this->assertSame( $expected, $block->isUsertalkEditAllowed() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test cases for whether own user talk edit is allowed, with different combinations of:
|
|
|
|
|
* - whether user talk namespace blocked
|
|
|
|
|
* - config BlockAllowsUTEdit true/false
|
|
|
|
|
* - block option specifying whether to block own user talk edit
|
|
|
|
|
* For more about the desired behaviour, see T252892.
|
|
|
|
|
*
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
2023-03-23 11:36:19 +00:00
|
|
|
public static function provideProcessFormUserTalkEditFlag() {
|
2020-09-10 11:28:42 +00:00
|
|
|
return [
|
|
|
|
|
'Always allowed if user talk namespace not blocked' => [
|
|
|
|
|
[
|
|
|
|
|
'userTalkNamespaceBlocked' => false,
|
|
|
|
|
'configAllowsUserTalkEdit' => true,
|
|
|
|
|
'optionBlocksUserTalkEdit' => false,
|
|
|
|
|
],
|
|
|
|
|
true,
|
|
|
|
|
],
|
|
|
|
|
'Always allowed if user talk namespace not blocked (config is false)' => [
|
|
|
|
|
[
|
|
|
|
|
'userTalkNamespaceBlocked' => false,
|
|
|
|
|
'configAllowsUserTalkEdit' => false,
|
|
|
|
|
'optionBlocksUserTalkEdit' => false,
|
|
|
|
|
],
|
|
|
|
|
true,
|
|
|
|
|
],
|
|
|
|
|
'Error if user talk namespace not blocked, but option blocks user talk edit' => [
|
|
|
|
|
[
|
|
|
|
|
'userTalkNamespaceBlocked' => false,
|
|
|
|
|
'configAllowsUserTalkEdit' => true,
|
|
|
|
|
'optionBlocksUserTalkEdit' => true,
|
|
|
|
|
],
|
|
|
|
|
'ipb-prevent-user-talk-edit',
|
|
|
|
|
],
|
|
|
|
|
'Always blocked if user talk namespace blocked and wgBlockAllowsUTEdit is false' => [
|
|
|
|
|
[
|
|
|
|
|
'userTalkNamespaceBlocked' => true,
|
|
|
|
|
'configAllowsUserTalkEdit' => false,
|
|
|
|
|
'optionBlocksUserTalkEdit' => false,
|
|
|
|
|
],
|
|
|
|
|
false,
|
|
|
|
|
],
|
|
|
|
|
'Option used if user talk namespace blocked and config is true (blocked)' => [
|
|
|
|
|
[
|
|
|
|
|
'userTalkNamespaceBlocked' => true,
|
|
|
|
|
'configAllowsUserTalkEdit' => true,
|
|
|
|
|
'optionBlocksUserTalkEdit' => true,
|
|
|
|
|
],
|
|
|
|
|
false,
|
|
|
|
|
],
|
|
|
|
|
'Option used if user talk namespace blocked and config is true (not blocked)' => [
|
|
|
|
|
[
|
|
|
|
|
'userTalkNamespaceBlocked' => true,
|
|
|
|
|
'configAllowsUserTalkEdit' => true,
|
|
|
|
|
'optionBlocksUserTalkEdit' => false,
|
|
|
|
|
],
|
|
|
|
|
true,
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-30 02:15:56 +00:00
|
|
|
/**
|
|
|
|
|
* @dataProvider provideProcessFormErrors
|
|
|
|
|
* @covers ::processForm()
|
|
|
|
|
*/
|
2020-04-24 11:54:41 +00:00
|
|
|
public function testProcessFormErrors( $data, $expected, $options = [] ) {
|
2022-08-14 13:47:11 +00:00
|
|
|
$this->overrideConfigValue( MainConfigNames::BlockAllowsUTEdit, true );
|
2019-07-30 02:15:56 +00:00
|
|
|
|
2020-04-24 11:54:41 +00:00
|
|
|
$performer = $this->getTestSysop()->getUser();
|
|
|
|
|
$target = !empty( $options['blockingSelf'] ) ? $performer : '1.2.3.4';
|
2019-07-30 02:15:56 +00:00
|
|
|
$defaultData = [
|
2020-04-24 11:54:41 +00:00
|
|
|
'Target' => $target,
|
|
|
|
|
'PreviousTarget' => $target,
|
2019-07-30 02:15:56 +00:00
|
|
|
'Expiry' => 'infinity',
|
2020-04-23 19:33:56 +00:00
|
|
|
'CreateAccount' => '0',
|
|
|
|
|
'DisableUTEdit' => '0',
|
|
|
|
|
'DisableEmail' => '0',
|
|
|
|
|
'HardBlock' => '0',
|
|
|
|
|
'AutoBlock' => '0',
|
2020-04-24 11:54:41 +00:00
|
|
|
'Confirm' => '0',
|
2020-04-23 19:33:56 +00:00
|
|
|
'Watch' => '0',
|
2019-07-30 02:15:56 +00:00
|
|
|
];
|
|
|
|
|
|
2020-04-24 11:54:41 +00:00
|
|
|
$context = new DerivativeContext( RequestContext::getMain() );
|
|
|
|
|
$context->setUser( $performer );
|
2019-07-30 02:15:56 +00:00
|
|
|
|
2020-04-24 11:54:41 +00:00
|
|
|
$result = $this->newSpecialPage()->processForm(
|
|
|
|
|
array_merge( $defaultData, $data ),
|
|
|
|
|
$context
|
|
|
|
|
);
|
|
|
|
|
|
2020-04-23 19:33:56 +00:00
|
|
|
if ( $result instanceof Status ) {
|
|
|
|
|
$result = $result->getErrorsArray();
|
|
|
|
|
}
|
|
|
|
|
$error = is_array( $result[0] ) ? $result[0][0] : $result[0];
|
|
|
|
|
$this->assertEquals( $expected, $error );
|
2019-07-30 02:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-23 11:36:19 +00:00
|
|
|
public static function provideProcessFormErrors() {
|
2019-07-30 02:15:56 +00:00
|
|
|
return [
|
|
|
|
|
'Invalid expiry' => [
|
|
|
|
|
[
|
|
|
|
|
'Expiry' => 'invalid',
|
|
|
|
|
],
|
|
|
|
|
'ipb_expiry_invalid',
|
|
|
|
|
],
|
|
|
|
|
'Expiry is in the past' => [
|
|
|
|
|
[
|
|
|
|
|
'Expiry' => 'yesterday',
|
|
|
|
|
],
|
|
|
|
|
'ipb_expiry_old',
|
|
|
|
|
],
|
|
|
|
|
'Bad ip address' => [
|
|
|
|
|
[
|
|
|
|
|
'Target' => '1.2.3.4/1234',
|
|
|
|
|
],
|
|
|
|
|
'badipaddress',
|
|
|
|
|
],
|
|
|
|
|
'Edit user talk page invalid with no restrictions' => [
|
|
|
|
|
[
|
|
|
|
|
'EditingRestriction' => 'partial',
|
2020-04-24 11:54:41 +00:00
|
|
|
'DisableUTEdit' => '1',
|
|
|
|
|
'PageRestrictions' => '',
|
|
|
|
|
'NamespaceRestrictions' => '',
|
2019-07-30 02:15:56 +00:00
|
|
|
],
|
|
|
|
|
'ipb-prevent-user-talk-edit',
|
|
|
|
|
],
|
2020-07-22 17:29:48 +00:00
|
|
|
'Edit user talk page invalid with namespace restriction !== NS_USER_TALK ' => [
|
2019-07-30 02:15:56 +00:00
|
|
|
[
|
|
|
|
|
'EditingRestriction' => 'partial',
|
2020-04-24 11:54:41 +00:00
|
|
|
'DisableUTEdit' => '1',
|
|
|
|
|
'PageRestrictions' => '',
|
|
|
|
|
'NamespaceRestrictions' => NS_USER,
|
2019-07-30 02:15:56 +00:00
|
|
|
],
|
|
|
|
|
'ipb-prevent-user-talk-edit',
|
|
|
|
|
],
|
2020-04-24 11:54:41 +00:00
|
|
|
'Blocking self and target changed' => [
|
|
|
|
|
[
|
|
|
|
|
'PreviousTarget' => 'other',
|
|
|
|
|
'Confirm' => '1',
|
|
|
|
|
],
|
|
|
|
|
'ipb-blockingself',
|
|
|
|
|
[
|
|
|
|
|
'blockingSelf' => true,
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
'Blocking self and no confirm' => [
|
|
|
|
|
[],
|
|
|
|
|
'ipb-blockingself',
|
|
|
|
|
[
|
|
|
|
|
'blockingSelf' => true,
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
'Empty expiry' => [
|
|
|
|
|
[
|
|
|
|
|
'Expiry' => '',
|
|
|
|
|
],
|
|
|
|
|
'ipb_expiry_invalid',
|
|
|
|
|
],
|
|
|
|
|
'Expiry valid but longer than 50 chars' => [
|
|
|
|
|
[
|
|
|
|
|
'Expiry' => '30th September 9999 19:19:19.532453 Europe/Amsterdam',
|
|
|
|
|
],
|
|
|
|
|
'ipb_expiry_invalid',
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideProcessFormErrorsReblock
|
|
|
|
|
* @covers ::processForm()
|
|
|
|
|
*/
|
|
|
|
|
public function testProcessFormErrorsReblock( $data, $permissions, $expected ) {
|
2022-08-14 13:47:11 +00:00
|
|
|
$this->overrideConfigValue( MainConfigNames::BlockAllowsUTEdit, true );
|
2020-04-24 11:54:41 +00:00
|
|
|
|
|
|
|
|
$performer = $this->getTestSysop()->getUser();
|
|
|
|
|
$this->overrideUserPermissions( $performer, $permissions );
|
|
|
|
|
$blockedUser = $this->getTestUser()->getUser();
|
|
|
|
|
|
|
|
|
|
$block = new DatabaseBlock( [
|
|
|
|
|
'address' => $blockedUser,
|
2021-06-02 09:44:38 +00:00
|
|
|
'by' => $performer,
|
2020-04-24 11:54:41 +00:00
|
|
|
'hideName' => true,
|
|
|
|
|
] );
|
2022-01-12 20:13:39 +00:00
|
|
|
$this->getServiceContainer()->getDatabaseBlockStore()->insertBlock( $block );
|
2020-04-24 11:54:41 +00:00
|
|
|
|
|
|
|
|
// Matches the existing block
|
|
|
|
|
$defaultData = [
|
|
|
|
|
'Target' => $blockedUser->getName(),
|
|
|
|
|
'PreviousTarget' => $blockedUser->getName(),
|
|
|
|
|
'Expiry' => 'infinity',
|
|
|
|
|
'DisableUTEdit' => '1',
|
|
|
|
|
'CreateAccount' => '0',
|
|
|
|
|
'DisableEmail' => '0',
|
|
|
|
|
'HardBlock' => '0',
|
|
|
|
|
'AutoBlock' => '0',
|
|
|
|
|
'HideUser' => '1',
|
|
|
|
|
'Confirm' => '1',
|
2020-04-23 19:33:56 +00:00
|
|
|
'Watch' => '0',
|
2020-04-24 11:54:41 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$context = new DerivativeContext( RequestContext::getMain() );
|
|
|
|
|
$context->setUser( $performer );
|
|
|
|
|
|
|
|
|
|
$result = $this->newSpecialPage()->processForm(
|
|
|
|
|
array_merge( $defaultData, $data ),
|
|
|
|
|
$context
|
|
|
|
|
);
|
|
|
|
|
|
2020-04-23 19:33:56 +00:00
|
|
|
if ( $result instanceof Status ) {
|
|
|
|
|
$result = $result->getErrorsArray();
|
|
|
|
|
}
|
2020-04-24 11:54:41 +00:00
|
|
|
$error = is_array( $result[0] ) ? $result[0][0] : $result[0];
|
|
|
|
|
$this->assertEquals( $expected, $error );
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-23 11:36:19 +00:00
|
|
|
public static function provideProcessFormErrorsReblock() {
|
2020-04-24 11:54:41 +00:00
|
|
|
return [
|
|
|
|
|
'Reblock user with Confirm false' => [
|
|
|
|
|
[
|
|
|
|
|
// Avoid error for hiding user with confirm false
|
|
|
|
|
'HideUser' => '0',
|
|
|
|
|
'Confirm' => '0',
|
|
|
|
|
],
|
2020-04-23 19:33:56 +00:00
|
|
|
[ 'block', 'hideuser' ],
|
2020-04-24 11:54:41 +00:00
|
|
|
'ipb_already_blocked',
|
|
|
|
|
],
|
|
|
|
|
'Reblock user with Reblock false' => [
|
|
|
|
|
[ 'Reblock' => '0' ],
|
2020-04-23 19:33:56 +00:00
|
|
|
[ 'block', 'hideuser' ],
|
2020-04-24 11:54:41 +00:00
|
|
|
'ipb_already_blocked',
|
|
|
|
|
],
|
|
|
|
|
'Reblock with confirm True but target has changed' => [
|
|
|
|
|
[ 'PreviousTarget' => '1.2.3.4' ],
|
2020-04-23 19:33:56 +00:00
|
|
|
[ 'block', 'hideuser' ],
|
2020-04-24 11:54:41 +00:00
|
|
|
'ipb_already_blocked',
|
|
|
|
|
],
|
|
|
|
|
'Reblock with same block' => [
|
|
|
|
|
[ 'HideUser' => '1' ],
|
2020-04-23 19:33:56 +00:00
|
|
|
[ 'block', 'hideuser' ],
|
2020-04-24 11:54:41 +00:00
|
|
|
'ipb_already_blocked',
|
|
|
|
|
],
|
|
|
|
|
'Reblock hidden user with wrong permissions' => [
|
|
|
|
|
[ 'HideUser' => '0' ],
|
2020-04-23 19:33:56 +00:00
|
|
|
[ 'block', 'hideuser' => false ],
|
2020-04-24 11:54:41 +00:00
|
|
|
'cant-see-hidden-user',
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideProcessFormErrorsHideUser
|
|
|
|
|
* @covers ::processForm()
|
|
|
|
|
*/
|
|
|
|
|
public function testProcessFormErrorsHideUser( $data, $permissions, $expected ) {
|
|
|
|
|
$performer = $this->getTestSysop()->getUser();
|
2020-04-23 19:33:56 +00:00
|
|
|
$this->overrideUserPermissions( $performer, array_merge( $permissions, [ 'block' ] ) );
|
2020-04-24 11:54:41 +00:00
|
|
|
|
|
|
|
|
$defaultData = [
|
|
|
|
|
'Target' => $this->getTestUser()->getUser(),
|
|
|
|
|
'HideUser' => '1',
|
|
|
|
|
'Expiry' => 'infinity',
|
|
|
|
|
'Confirm' => '1',
|
2020-04-23 19:33:56 +00:00
|
|
|
'CreateAccount' => '0',
|
|
|
|
|
'DisableUTEdit' => '0',
|
|
|
|
|
'DisableEmail' => '0',
|
|
|
|
|
'HardBlock' => '0',
|
|
|
|
|
'AutoBlock' => '0',
|
|
|
|
|
'Watch' => '0',
|
2020-04-24 11:54:41 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$context = new DerivativeContext( RequestContext::getMain() );
|
|
|
|
|
$context->setUser( $performer );
|
|
|
|
|
|
|
|
|
|
$result = $this->newSpecialPage()->processForm(
|
|
|
|
|
array_merge( $defaultData, $data ),
|
|
|
|
|
$context
|
|
|
|
|
);
|
|
|
|
|
|
2020-04-23 19:33:56 +00:00
|
|
|
if ( $result instanceof Status ) {
|
|
|
|
|
$result = $result->getErrorsArray();
|
|
|
|
|
}
|
|
|
|
|
$error = is_array( $result[0] ) ? $result[0][0] : $result[0];
|
|
|
|
|
$this->assertEquals( $expected, $error );
|
2020-04-24 11:54:41 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-23 11:36:19 +00:00
|
|
|
public static function provideProcessFormErrorsHideUser() {
|
2020-04-24 11:54:41 +00:00
|
|
|
return [
|
|
|
|
|
'HideUser with wrong permissions' => [
|
|
|
|
|
[],
|
|
|
|
|
[ 'hideuser' => '0' ],
|
|
|
|
|
'badaccess-group0',
|
|
|
|
|
],
|
|
|
|
|
'Hideuser with partial block' => [
|
|
|
|
|
[ 'EditingRestriction' => 'partial' ],
|
|
|
|
|
[ 'hideuser' ],
|
|
|
|
|
'ipb_hide_partial',
|
|
|
|
|
],
|
|
|
|
|
'Hideuser with finite expiry' => [
|
|
|
|
|
[ 'Expiry' => '1 hour' ],
|
|
|
|
|
[ 'hideuser' ],
|
|
|
|
|
'ipb_expiry_temp',
|
|
|
|
|
],
|
|
|
|
|
'Hideuser with no confirm' => [
|
|
|
|
|
[ 'Confirm' => '0' ],
|
|
|
|
|
[ 'hideuser' ],
|
|
|
|
|
'ipb-confirmhideuser',
|
|
|
|
|
],
|
2019-07-30 02:15:56 +00:00
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-24 11:54:41 +00:00
|
|
|
/**
|
|
|
|
|
* @covers ::processForm()
|
|
|
|
|
*/
|
|
|
|
|
public function testProcessFormErrorsHideUserProlific() {
|
2022-08-14 13:47:11 +00:00
|
|
|
$this->overrideConfigValue( MainConfigNames::HideUserContribLimit, 0 );
|
2020-04-24 11:54:41 +00:00
|
|
|
|
|
|
|
|
$performer = $this->getTestSysop()->getUser();
|
2020-04-23 19:33:56 +00:00
|
|
|
$this->overrideUserPermissions( $performer, [ 'block', 'hideuser' ] );
|
2020-04-24 11:54:41 +00:00
|
|
|
|
|
|
|
|
$userToBlock = $this->getTestUser()->getUser();
|
|
|
|
|
$pageSaturn = $this->getExistingTestPage( 'Saturn' );
|
2021-06-24 08:42:19 +00:00
|
|
|
$pageSaturn->doUserEditContent(
|
2020-04-24 11:54:41 +00:00
|
|
|
ContentHandler::makeContent( 'content', $pageSaturn->getTitle() ),
|
2021-06-24 08:42:19 +00:00
|
|
|
$userToBlock,
|
|
|
|
|
'summary'
|
2020-04-24 11:54:41 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$context = new DerivativeContext( RequestContext::getMain() );
|
|
|
|
|
$context->setUser( $performer );
|
|
|
|
|
|
|
|
|
|
$result = $this->newSpecialPage()->processForm(
|
|
|
|
|
[
|
|
|
|
|
'Target' => $userToBlock,
|
2020-04-23 19:33:56 +00:00
|
|
|
'CreateAccount' => '1',
|
2020-04-24 11:54:41 +00:00
|
|
|
'HideUser' => '1',
|
|
|
|
|
'Expiry' => 'infinity',
|
|
|
|
|
'Confirm' => '1',
|
2020-04-23 19:33:56 +00:00
|
|
|
'DisableUTEdit' => '0',
|
|
|
|
|
'DisableEmail' => '0',
|
|
|
|
|
'HardBlock' => '0',
|
|
|
|
|
'AutoBlock' => '0',
|
|
|
|
|
'Watch' => '0',
|
2020-04-24 11:54:41 +00:00
|
|
|
],
|
|
|
|
|
$context
|
|
|
|
|
);
|
|
|
|
|
|
2020-04-23 19:33:56 +00:00
|
|
|
if ( $result instanceof Status ) {
|
|
|
|
|
$result = $result->getErrorsArray();
|
|
|
|
|
}
|
|
|
|
|
$error = is_array( $result[0] ) ? $result[0][0] : $result[0];
|
|
|
|
|
$this->assertEquals( 'ipb_hide_invalid', $error );
|
2020-04-24 11:54:41 +00:00
|
|
|
}
|
|
|
|
|
|
2018-11-27 18:38:14 +00:00
|
|
|
/**
|
2020-08-27 09:27:10 +00:00
|
|
|
* TODO: Move to BlockPermissionCheckerTest
|
|
|
|
|
*
|
2018-11-27 18:38:14 +00:00
|
|
|
* @dataProvider provideCheckUnblockSelf
|
|
|
|
|
* @covers ::checkUnblockSelf
|
|
|
|
|
*/
|
|
|
|
|
public function testCheckUnblockSelf(
|
|
|
|
|
$blockedUser,
|
|
|
|
|
$blockPerformer,
|
|
|
|
|
$adjustPerformer,
|
|
|
|
|
$adjustTarget,
|
2020-04-02 14:23:03 +00:00
|
|
|
$sitewide,
|
2018-11-27 18:38:14 +00:00
|
|
|
$expectedResult,
|
|
|
|
|
$reason
|
|
|
|
|
) {
|
2023-03-17 14:37:51 +00:00
|
|
|
$this->hideDeprecated( 'MediaWiki\Specials\SpecialBlock::checkUnblockSelf' );
|
2020-09-18 19:24:00 +00:00
|
|
|
|
2022-08-14 13:47:11 +00:00
|
|
|
$this->overrideConfigValue( MainConfigNames::BlockDisablesLogin, false );
|
2018-11-27 18:38:14 +00:00
|
|
|
$this->setGroupPermissions( 'sysop', 'unblockself', true );
|
|
|
|
|
$this->setGroupPermissions( 'user', 'block', true );
|
|
|
|
|
// Getting errors about creating users in db in provider.
|
|
|
|
|
// Need to use mutable to ensure different named testusers.
|
|
|
|
|
$users = [
|
2020-12-20 01:52:16 +00:00
|
|
|
'u1' => $this->getMutableTestUser( 'sysop' )->getUser(),
|
|
|
|
|
'u2' => $this->getMutableTestUser( 'sysop' )->getUser(),
|
|
|
|
|
'u3' => $this->getMutableTestUser( 'sysop' )->getUser(),
|
|
|
|
|
'u4' => $this->getMutableTestUser( 'sysop' )->getUser(),
|
2018-11-27 18:38:14 +00:00
|
|
|
'nonsysop' => $this->getTestUser()->getUser()
|
|
|
|
|
];
|
|
|
|
|
foreach ( [ 'blockedUser', 'blockPerformer', 'adjustPerformer', 'adjustTarget' ] as $var ) {
|
|
|
|
|
$$var = $users[$$var];
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-13 14:18:07 +00:00
|
|
|
$block = new DatabaseBlock( [
|
2018-11-27 18:38:14 +00:00
|
|
|
'address' => $blockedUser->getName(),
|
|
|
|
|
'user' => $blockedUser->getId(),
|
2021-06-02 09:44:38 +00:00
|
|
|
'by' => $blockPerformer,
|
2018-11-27 18:38:14 +00:00
|
|
|
'expiry' => 'infinity',
|
2020-04-02 14:23:03 +00:00
|
|
|
'sitewide' => $sitewide,
|
2018-11-27 18:38:14 +00:00
|
|
|
'enableAutoblock' => true,
|
|
|
|
|
] );
|
|
|
|
|
|
2022-01-12 20:13:39 +00:00
|
|
|
$this->getServiceContainer()->getDatabaseBlockStore()->insertBlock( $block );
|
2018-11-27 18:38:14 +00:00
|
|
|
|
|
|
|
|
$this->assertSame(
|
|
|
|
|
$expectedResult,
|
2022-02-08 05:12:43 +00:00
|
|
|
SpecialBlock::checkUnblockSelf( $adjustTarget, $adjustPerformer ),
|
2018-11-27 18:38:14 +00:00
|
|
|
$reason
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-23 11:36:19 +00:00
|
|
|
public static function provideCheckUnblockSelf() {
|
2018-11-27 18:38:14 +00:00
|
|
|
// 'blockedUser', 'blockPerformer', 'adjustPerformer', 'adjustTarget'
|
|
|
|
|
return [
|
2020-04-02 14:23:03 +00:00
|
|
|
[ 'u1', 'u2', 'u3', 'u4', 1, true, 'Unrelated users' ],
|
|
|
|
|
[ 'u1', 'u2', 'u1', 'u4', 1, 'ipbblocked', 'Block unrelated while blocked' ],
|
|
|
|
|
[ 'u1', 'u2', 'u1', 'u4', 0, true, 'Block unrelated while partial blocked' ],
|
|
|
|
|
[ 'u1', 'u2', 'u1', 'u1', 1, true, 'Has unblockself' ],
|
|
|
|
|
[ 'nonsysop', 'u2', 'nonsysop', 'nonsysop', 1, 'ipbnounblockself', 'no unblockself' ],
|
|
|
|
|
[ 'nonsysop', 'nonsysop', 'nonsysop', 'nonsysop', 1, true,
|
|
|
|
|
'no unblockself but can de-selfblock'
|
|
|
|
|
],
|
|
|
|
|
[ 'u1', 'u2', 'u1', 'u2', 1, true, 'Can block user who blocked' ],
|
2018-11-27 18:38:14 +00:00
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-22 19:45:13 +00:00
|
|
|
/**
|
|
|
|
|
* @dataProvider provideGetTargetAndType
|
|
|
|
|
* @covers ::getTargetAndType
|
|
|
|
|
*/
|
|
|
|
|
public function testGetTargetAndType( $par, $requestData, $expectedTarget ) {
|
|
|
|
|
$request = $requestData ? new FauxRequest( $requestData ) : null;
|
|
|
|
|
$page = $this->newSpecialPage();
|
2022-10-21 04:32:38 +00:00
|
|
|
[ $target, $type ] = $page->getTargetAndType( $par, $request );
|
2022-02-08 05:12:43 +00:00
|
|
|
$this->assertSame( $expectedTarget, $target );
|
2020-04-22 19:45:13 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-23 11:36:19 +00:00
|
|
|
public static function provideGetTargetAndType() {
|
2020-04-22 19:45:13 +00:00
|
|
|
$invalidTarget = '';
|
|
|
|
|
return [
|
|
|
|
|
'Choose \'wpTarget\' parameter first' => [
|
|
|
|
|
'2.2.2.0/24',
|
|
|
|
|
[
|
|
|
|
|
'wpTarget' => '1.1.1.0/24',
|
|
|
|
|
'ip' => '3.3.3.0/24',
|
|
|
|
|
'wpBlockAddress' => '4.4.4.0/24',
|
|
|
|
|
],
|
|
|
|
|
'1.1.1.0/24',
|
|
|
|
|
],
|
|
|
|
|
'Choose subpage parameter second' => [
|
|
|
|
|
'2.2.2.0/24',
|
|
|
|
|
[
|
|
|
|
|
'wpTarget' => $invalidTarget,
|
|
|
|
|
'ip' => '3.3.3.0/24',
|
|
|
|
|
'wpBlockAddress' => '4.4.4.0/24',
|
|
|
|
|
],
|
|
|
|
|
'2.2.2.0/24',
|
|
|
|
|
],
|
|
|
|
|
'Choose \'ip\' parameter third' => [
|
|
|
|
|
$invalidTarget,
|
|
|
|
|
[
|
|
|
|
|
'wpTarget' => $invalidTarget,
|
|
|
|
|
'ip' => '3.3.3.0/24',
|
|
|
|
|
'wpBlockAddress' => '4.4.4.0/24',
|
|
|
|
|
],
|
|
|
|
|
'3.3.3.0/24',
|
|
|
|
|
],
|
|
|
|
|
'Choose \'wpBlockAddress\' parameter fourth' => [
|
|
|
|
|
$invalidTarget,
|
|
|
|
|
[
|
|
|
|
|
'wpTarget' => $invalidTarget,
|
|
|
|
|
'ip' => $invalidTarget,
|
|
|
|
|
'wpBlockAddress' => '4.4.4.0/24',
|
|
|
|
|
],
|
|
|
|
|
'4.4.4.0/24',
|
|
|
|
|
],
|
|
|
|
|
'No web request' => [
|
|
|
|
|
'2.2.2.0/24',
|
|
|
|
|
false,
|
|
|
|
|
'2.2.2.0/24',
|
|
|
|
|
],
|
|
|
|
|
'No valid request data or subpage parameter' => [
|
|
|
|
|
null,
|
|
|
|
|
[],
|
|
|
|
|
null,
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-27 22:19:37 +00:00
|
|
|
protected function insertBlock() {
|
|
|
|
|
$badActor = $this->getTestUser()->getUser();
|
|
|
|
|
$sysop = $this->getTestSysop()->getUser();
|
|
|
|
|
|
2019-05-13 14:18:07 +00:00
|
|
|
$block = new DatabaseBlock( [
|
2018-08-27 22:19:37 +00:00
|
|
|
'address' => $badActor->getName(),
|
|
|
|
|
'user' => $badActor->getId(),
|
2021-06-02 09:44:38 +00:00
|
|
|
'by' => $sysop,
|
2018-08-27 22:19:37 +00:00
|
|
|
'expiry' => 'infinity',
|
|
|
|
|
'sitewide' => 1,
|
|
|
|
|
'enableAutoblock' => true,
|
|
|
|
|
] );
|
|
|
|
|
|
2022-01-12 20:13:39 +00:00
|
|
|
$this->getServiceContainer()->getDatabaseBlockStore()->insertBlock( $block );
|
2018-08-27 22:19:37 +00:00
|
|
|
|
|
|
|
|
return $block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function resetTables() {
|
|
|
|
|
$this->db->delete( 'ipblocks', '*', __METHOD__ );
|
|
|
|
|
$this->db->delete( 'ipblocks_restrictions', '*', __METHOD__ );
|
|
|
|
|
}
|
2019-04-11 19:54:10 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get a BlockRestrictionStore instance
|
|
|
|
|
*
|
|
|
|
|
* @return BlockRestrictionStore
|
|
|
|
|
*/
|
2021-07-22 03:11:47 +00:00
|
|
|
private function getBlockRestrictionStore(): BlockRestrictionStore {
|
2023-05-05 13:13:06 +00:00
|
|
|
$dbProvider = $this->createMock( IConnectionProvider::class );
|
2019-04-11 19:54:10 +00:00
|
|
|
|
2023-05-05 13:13:06 +00:00
|
|
|
return new BlockRestrictionStore( $dbProvider );
|
2019-04-11 19:54:10 +00:00
|
|
|
}
|
2018-08-27 22:19:37 +00:00
|
|
|
}
|