The array spread operator is documented to behave identical to
array_merge. The syntax is just much shorter and easier to read in
situations like this, in my opinion.
Change-Id: I3b016e896e552af53d87d5e72436dc4e29070ce1
The idea is that all formatters that need the user language or
other request specific context should be instantiated by
FormatterFactory.
Change-Id: I8334cc89dcf0f293298b82e004116be50a90f0d1
Support migration stages when reading and writing blocks.
I tried to set it up for an easy next stage, in which support for the
old schema is removed. I tried to avoid factoring out of shared code
between the two schemas, so that the old schema cases can simply be
deleted without the need to revert unnecessary abstractions.
However, I added HideUserUtils to factor out ipb_deleted queries. Code
review showed that this was already quite complex, with multiple
approaches to the problem, so it benefits from refactoring even without
the schema abstraction.
HideUserUtils is a service rather than a standalone class to support
unit tests, since unit tests do not allow global config access. When
the migration stage config is removed, it will be a service with no
constructor parameters -- an unnecessary abstraction which should
ideally be resolved at that time.
When interpreting result rows, it is possible to share code by using
field aliases. But when constructing WHERE conditions, the actual field
names need to be used, so the migration is more intrusive in
ApiQueryBlocks and SpecialBlockList, where complex conditions are used.
Bug: T346293
Bug: T51504
Bug: T349883
Change-Id: I408acf7a57b0100fe18c455fc13141277a598925
Implicit rights represent actions granted to all users.
They can be rate limited, but not revoked.
Bug: T350202
Bug: T350117
Bug: T350347
Change-Id: I22bf5e60c38900f881d43577351761827066a25c
* Move to DatabaseBlockStore the DatabaseBlock methods newFromID,
getQueryInfo, getRangeCond, newFromRow, isExemptedFromAutoblocks,
doAutoblock, updateTimestamp, getAutoblockExpiry, newFromTarget,
newListFromTarget.
* Split DatabaseBlock::getBlocksForIPList. Now
BlockManager::getBlocksForIPList() is responsible for XFF header
validation and trusted proxy handling. DatabaseBlockStore::
newListFromIPs() just does the queries and constructs the Block
objects.
* In DatabaseBlockStore::newFromRow() and doAutoblock(), use the
DatabaseBlock constructor instead of calling many setter methods. Add
constructor options decodedExpiry, decodedTimestamp, id,
parentBlockId and restrictions to support this.
* Move isExemptedFromAutoblocks() to its own service. Remove the cache
since in my testing with production eval.php, the WAN cache fetch is
10 times slower than just using the message cache, contradicting the
comment written in 2008.
* Fix AuthManagerTest which was previously passing an unrecognised
"restrictions" option to DatabaseBlock. Now that the option actually
works, we have to use the right type.
Bug: T255433
Change-Id: I5049e60be1681f67fcca133e569e315792dc42dd
* In AuthManager::autoCreateUser(), check the permissions of the
performer instead of relying on the secondary providers. This means
that auto-creation will be denied when the anonymous user is globally
IP-blocked.
* Remove create account block check from
CheckBlocksSecondaryAuthenticationProvider. testUserForCreation() is
supposed to only do target name checks, but it's not actually
possible to block a non-existent local name. So we don't need this
code.
* Add a $performer parameter to autoCreateUser() so that
Special:CreateLocalAccount can have elevated permissions when it
creates an account with IP block exemption.
* When a performer is passed, don't use the session as a cache.
* Since we are passing autocreateaccount as the action to
PermissionManager instead of createaccount, some special cases need to
be tweaked. Previously AuthManager checked for either
autocreateaccount or createaccount rights. Now PermissionManager does
that when the action is autocreateaccount.
By removing redundant checks from testUserForCreation(), the number of
ipblocks queries during a normal Special:CreateAccount post request is
reduced from 8 to 6.
The CentralAuth change I7e7a7fc8bcd86285f857063a38de02b41b5175d0 should
be merged immediately after this one.
Bug: T234371
Bug: T345683
Change-Id: If2937c7d717d2adc249f608d4585122b02a43fff
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
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
* Use a consistent single-line comment style.
* Start each sentence with a capital letter.
* Use imperative mood.
* Put a space between the adjective and the noun in "hardblock" and
"rangeblock".
* Capitalise acronyms.
* Break long lines.
* Remove excessively obvious or off-topic comments.
* Indent the non-initial lines of a multi-line @ command.
* Don't try to apply @deprecated to a parameter. Doxygen and PHPStorm
interpret this as method deprecation.
Bug: T345683
Change-Id: I7df126f7a031dde241dd46f66e5e83722f9b383c
This is unfortunately by necessity a breaking change to the soon-to-
be-removed mBlockreason from string to CommentStoreComment. Oh well.
Change-Id: Iac918def95fb0600f2d805d2d95732b280d8fd81
Why:
* A soft block against an IP address does not block logged-in
users, but it should block temporary users, otherwise anonymous
users can circumvent it by creating a temporary account.
What:
* Return a block for a temporary user if a soft block is found
against their IP address, from DatabaseBlock::newLoad
* Return soft blocks for temporary users in
BlockManager::getXffBlocks
* Update documentation to make clear that soft blocks apply to
temporary users, including where they are referred to as
anon-only blocks
Bug: T343714
Change-Id: I5a2928eb3370bd47544b164b08014ef62297ce36
so that extensions (i.e. CheckUser) can implement their own comment
store without having a lot of code duplication
basically the comment store version of I3a6486532f2ef36
Bug: T233004
Change-Id: Ib40f99e00a514d41776ce521baf113e46d37e9cd
Mainly, document some parameters as non-empty-array so that phan knows
the list of arguments won't be empty when unpacking.
In EditPage, account for hooks potentially unsetting the copyright
notice.
Also rewrite some code in LogPager, so it's hopefully easier for phan to
understand what's going on.
Change-Id: Ic0638571554424098d0743db32dd46723a08e103
This method is supposed to return a single message in array form
(['key', 'param1', ...]), as can be seen e.g. in includes/Block.php
in MediaWiki 1.31 of the includes/block classes in 1.34.
Allow for the key to be a Message object, which means passing the
array contents as a functions parameter list will work with most
message-related functions, is already used by the GlobalBlocking
extension, and allows more complex messages not possible with plain
arrays.
Change-Id: Ic19dc1dde25794f9bb3b3b5d8abba8ddf8948886
The getConfig of a ContextSource should only be used, if the
ContextSource is available. Getting the global context just for the
config looks harder to fix/inject as using the MainConfig from
MediaWikiServices
Change-Id: Iaf14bfc7bd68cc315672e1c256887faf87e22542
Now largely automated:
VARS=$(grep -o "'[A-Za-z0-9_]*'" includes/MainConfigNames.php | \
tr "\n" '|' | sed "s/|$/\n/;s/'//g")
sed -i -E "s/'($VARS)'/MainConfigNames::\1/g" \
$(grep -ERIl "'($VARS)'" includes/)
Then git add -p with lots of error-prone manual checking. Then
semi-manually add all the necessary "use" lines:
vim $(grep -L 'use MediaWiki\\MainConfigNames;' \
$(git diff --cached --name-only --diff-filter=M HEAD^))
I didn't bother fixing lines that were over 100 characters unless they
were over 120 and triggered phpcs.
Bug: T305805
Change-Id: I74e0ab511abecb276717ad4276a124760a268147
Replace all uses of AbstractBlock::getTarget with
Block ::getTargetName and ::getTargetUserIdentity.
Create AbstractBlockTest and two test cases for
AbstractBlock::getTarget and ::getTargetAndType.
It tests triggering of the deprecation warning.
Bug: T282247
Depends-On: I0543f363af66c57f5763b91320d87a69f23f9466
Change-Id: Iaeca824cac30172178de72f3cf7b7ae4cdd6f880
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
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