Functional changes:
* On account creation, if both a user block and an IP block apply,
return a CompositeBlock instead of picking a winner.
* On other actions, instead of returning the whole CompositeBlock if
some part of it matches the specified page and action, filter the
individual parts of the CompositeBlock by whether or not they match.
Refactoring:
* Add BlockManager::getBlock(), which is the same as getUserBlock()
except that it expects the caller to do IP exemption checking.
Deprecate getUserBlock().
* Migrate some callers of User::getBlock() to use BlockManager.
* Have PermissionManager use BlockManager instead of
User::getBlock().
* Add $request parameter to PermissionManager::getApplicableBlock(),
to fix the weird bundling of the request with the User.
* Move the createaccount block database fetch from PermissionManager to
BlockManager, where it can easily be cached.
* Fix code duplication between PermissionManager::isBlockedFrom() and
PermissionManager::getApplicableBlock() by having the former call the
latter.
* In CheckBlocksSecondaryAuthenticationProvider, use
AuthManager::getRequest(). Previously it used the global request and
also User::getRequest() via User::getBlock().
Bug: T345683
Change-Id: Icd75025665282a34d8854bda267a0eb3d759719c
All GetUserBlock hook handlers face a common problem: when there
are multiple blocks that match, or there is another block passed
down by core or previous extensions, they need to create a
composite block since they can only pass forward a single Block
object. Even though the logic for doing so is not complicated,
it's better to centralize it so it's one less thing the extension
author needs to think about.
Unlike the original code snippet, the target is not passed in
explicitly but taken from the first composing block. Since
CompositeBlock is created after target filtering already happend,
this shouldn't make much difference; and the target property of a
composite block which contains blocks with different targets
isn't particularly meaningful.
Change-Id: I14f754e3c479ce61d18d7d2ebd1656940088d67d
There are 7 callers of CompositeBlock::getOriginalBlocks() in code
search, and all are following a pattern like
$blocks = $block instanceof CompositeBlock
? $block->getOriginalBlock() : [ $block ]
or can be reorganised to follow such a pattern, which suggests the need
for a public interface along these lines.
So, add Block::toArray() which returns the list of blocks in a
CompositeBlock, or wraps the single block in an array if the block is
not a CompositeBlock.
Also, remove the need for a phan-var override by moving the instanceof
DatabaseBlock check from shouldTrackBlockWithCookie() to its caller.
Bug: T345683
Change-Id: If769db9a831f63a79b57fb3bc9c7cece511c70c3
* Make BlockManager internal methods private, since nothing calls them
anymore.
* In AbstractBlock and DatabaseBlock, remove deprecated public
properties mExpiry, mHideName, mTimestamp, mAuto and mParentBlockId.
* In BlockRestrictionStore, remove all the "instanceof Restriction"
checks. If someone passes in something that's not a Restriction, we
should throw, not ignore it, because we don't know the caller's
intention. Add a type declaration to $hasher in equals() so that it
will throw.
* Remove the "m" prefix from all private and protected properties.
AbstractBlock is not stable to override so this is not a stable
interface break.
* In BlockRestrictionStore::restrictionsToRemove(), use an O(N)
algorithm.
* In BlockRestrictionStore::rowToRestriction(), use a switch instead of
a type map, so that the calls are statically analyzable.
* In BlockUser::__construct(), fix the initialisation order issue by
inlining the relevant logic.
* Rename variable $actionRestriction.
* In Special:Block, fix call to deprecated method getTargetAndType(),
and hard deprecate it. @deprecated has the effect of deprecating a
method for both internal and external callers, there's no such thing
as an external-only deprecation. So it's necessary to rename it if you
want to keep it as a private method.
Bug: T345683
Change-Id: If4a4a18d7b5fec825417de81302266119c215fd3
In order to allow Authority to know about user blocks,
we need a narrow interface to represent such blocks.
This deprecates some methods on AbstractBlocks in favor
of new methods on the Block interface that avoid binding to
the User class.
Bug: T271494
Change-Id: I7bb950533970984a014de0434518fbbefb695131
System blocks (which tend to be against IP addresses) can apply to
anon users only, or to logged-in users too. This differs depending
on the type of system block.
This is enforced in BlockManager::getAdditionalIpBlocks by checking
whether the user is anonymous before constructing a given type of
system block. Before this commit, it is not codified in the block's
properties, meaning that there is no way to communicate via the
API whether the block blocks logged-in users too.
Database blocks have a property $isHardblock; move this up to
AbstractBlock, so that system blocks and composite blocks can set
this property too.
Bug: T261639
Change-Id: I4f6ddf6cca6e01e85c56eef1ca7496dd6fcf52e6
The motivations behind this change is T227892 and that a blocker for a System or
Composite block provides no useful information for the end user.
Here is what's changing:
* Move the $blocker property to DatabaseBlock, since this is the only type of
block that can be created by a user.
* Move handling of the 'by' and 'byName' constructor option from AbstractBlock to
DatabaseBlock.
* getBy(), getByName(), are now abstracts methods and each block type have to provide
their own implementation
* getBlocker(), setBlocker() are being deprecated in AbstractBlock and moved as internal
methods into DatabaseBlock
Bug: T227892
Depends-On: Ie2aa00cfec5e166460bcaeddba3c601fe0627c13
Change-Id: I1b17c652b12d98de3d996d309d4d3f22074be411
The main reasons for adding this service layer are:
* It allows error messages to be more consistent, by defining
a set of reportable information that can describe any block
type and is consistently formatted.
* It decouples formatting from the block classes, removing
their dependency on language, for the most part.
The service provides one public method, getMessage, which
returns a Message object whose key and parameters are
determined by the type of block. This should be used instead
of the deprecated AbstractBlock::getPermissionsError and
AbstractBlock::getBlockErrorParams.
Calls to AbstractBlock::getPermissionsError are replaced in
this patch.
Bug: T227174
Change-Id: I8caae7e30a46ef7120a86a4e5e6f30ae00855063
CompositeBlock::appliesToRight checks $block->appliesToRight()
for each of the original blocks from which it is made.
AbstractBlock::appliesToRight returns:
* true if the block applies to the right
* false if the block does not apply to the right
* null if unsure
Before this, CompositeBlock::appliesToRight can only return true
or false. After this, it returns:
* false if false for all of the original blocks
* true if true for one or more original blocks
* null otherwise
Bug: T229417
Bug: T231145
Change-Id: Ie93b7691b57ac6a8f86b3641ad07a1d54babcd42
For any messages that use CompositeBlock::getPermissionsError, include
details of the original blocks from which the composite block is made.
If there are any database blocks, give their IDs and also explain that
there may also be blocks due to IP blacklisting.
If there are no database blocks, then explain that the IP must be
blacklisted in multiple places.
Bug: T212326
Change-Id: Id6ad0019f8add4d5e000da5e872338e87cca485e
Give a custom reason and include the user's IP address and the
expiry of the longest block.
Bug: T225748
Change-Id: Ie147cca625365c1a01e2ed18819e5d6e3946865e
Create a CompositeBlock class which extends AbstractBlock and
adds the property $originalBlocks. This is for situations where
more than one block applies to a user/IP, and avoids the need
to choose just one of these blocks to enforce.
Behaviour of the resulting block is determined by combining the
strictest parameters of the original blocks.
Also add DatabaseBlock::newListFromTarget, which is similar to
DatabaseBlock::newFromTarget, but returns all relevant blocks,
rather than choosing the most specific one.
For tracking a CompositeBlock with a cookie, examine the
original blocks and only track the first trackable block that
is found.
Bug: T206163
Change-Id: I088401105ac8ceb2c6117c6d2fcdb277c754d882