The idea is that all formatters that need the user language or
other request specific context should be instantiated by
FormatterFactory.
Change-Id: I8334cc89dcf0f293298b82e004116be50a90f0d1
In DatabaseBlockTest changed from addDBDataOnce() to addDBData() as
ChangedTablesTracker cannot reset tables changed by addDBDataOnce()
between each test run.
Remove also User::clearInstanceCache done together with the deletion as
the TestUser class is calling this already between tests.
Change-Id: Ibd5e544138a2a9b554abc2dea54a5db38f9a828f
Why:
Temporary accounts (introduced as part of IP Masking)
are supposed to expire 1 year after their registration.
Automatic account expiration can be done via a maintenance
script, which would be periodically executed via cron / systemd.
Make it possible for extensions to provide their own logic
for generating a list of temporary accounts to invalidate.
This is used in CentralAuth to base registration timestamp
on the global registration timestamp.
The default behavior is "temporary accounts do not expire",
given the feature requires a maintenance script to run
periodically, which will not be the case on third party
instances.
What:
* Add `expireAfterDays` to $wgAutoCreateTempUser, controlling
how many days temporary accounts have.
* Add UserSelectQueryBuilder::whereRegisteredTimestamp(),
filtering accounts based on user_registration.
* Add ExpireTemporaryAccounts maintenance script, which is
@stable to extend.
Bug: T344695
Change-Id: If17bf84ee6620c8eb784b7d835682ad5e7afdfcc
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
Remove the 'user' option from the documentation and defaults. It has
been ignored since a3b4881f6f (2021, 1.37).
Fix tests which pass unknown constructor options. I found these by
temporarily patching the constructor to throw when an unknown option is
given.
Change-Id: I95cb2a38a5688d83c90ad501786f6d6bb02765ba
* Migrate callers of DatabaseBlock methods newListFromTarget,
newFromID, newFromTarget, doAutoblock.
* Deprecate DatabaseBlock methods newFromID and getAutoblockExpiry.
These are the methods with no extension callers in code search.
Bug: T255433
Change-Id: If0358459f53d32e7fe984c2fb8b61e0088f28922
* Add getMessages method to BlockErrorFormatter that will get
error messages for all the applicable blocks.
* Call getMessages from PermissionManager, UserAuthority and
EditPage.
* ApiBase and UserBlockedError still call getMessage since
they work with a single message.
Bug: T344463
Change-Id: If240562dd25435d9c6c824dd595d58bb8672de2b
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
PermissionManager has an extensive need for block information, and it
gets it from the global state with User::getBlock(). In the future it
should get block information from BlockManager.
However, this is complicated because BlockManager already depends on
PermissionManager, solely for ipblock-exempt rights. For now, have
BlockManager use the service container for this information.
To simplify review, the changes which use
PermissionManager::$blockManager will be in a subsequent commit.
Bug: T345683
Change-Id: I7a92eed142dcf2595cc3e2c5fa85a362c2a10d99
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
- UserEditTrackerTest: determine whether to create the page based on
WikiPage::exists() instead of a method parameter. The current
implementation only works because the page is not deleted between test
runs, and the creation query is ignored. However, if the first call to
`editTrackerDoEdit` doesn't have $create=true, tests would fail. For
instance, testGetEditTimestamp would fail when run on its own because
the revision cannot be inserted if the page doesn't exist. Just use
WikiPage::exists instead of forcing callers to handle this correctly.
- DatabaseBlockTest: use addDBDataOnce instead of a DIY implementation.
This also makes the tests more deterministic, because the records
needed by the test class are created immediately. Also avoid redundant
User::addToDatabase and ::saveSettings, these are already done by
TestUser.
- PageRestrictionTest: avoid Title::newFromID which is not guaranteed to
succeed if all pages have been deleted by that point. The second part
of the test was effectively doing the same thing as the first part, so
just remove it.
- WikiPageDbTest: avoid expensive page deletions in tearDown. These are
all unnecessary because the DB is cleaned up after each test (and
'page' is explicitly included in $tablesUsed). In fact, deleting test
pages as done there can be even worse than not doing anything, because
it creates log entries etc. Add page_restrictions to tablesUsed as
that's not truncated automatically.
- DBSiteStoreTest: testReset would fail when run on its own because it
depends on test sites being inserted in testGetSites. Make the test
add the sites it needs, so that they can safely be cleared between
test runs.
Change-Id: I1065fb3e8507b4b1a3bf185181f2f3059a97fd04
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
Temporary users are blocked if their IP address is listed in
$wgDnsBlacklistUrls or $wgSoftBlockRanges.
Bug: T343704
Change-Id: Ia3383bd10c3c6c35c586550b68f4af5f4659e815
Mock the relevant services that need the DB instead, when possible. When
not possible, e.g. because DB access is needed for the test to make
sense, add the test to the Database group instead.
Change-Id: Iefbfe00bedc243906c6b860572568343268646cc
Remove BlockRestrictionStore::deleteByBlockId and replace by
select on parent id and delete on primary key.
This avoids that restriction store needs to determine the rows via
deleteJoin and the block store via parent select. Just use the primary
key in both functions for deletion and combine the delete for parent and
normal block id where possible.
In case there are no parent blocks this also removes a possible gap
lock. In case the unblock and the autoblock happens in same second the
autoblock may there without its block
Change-Id: I274d35834ce1e3e1d67fabd698d9a1cb3de9687a
Instead of passing a custom database to DatabaseBlockStore::instertBlock
callers should rather just fetch a correct DatabaseBlockStore
using the new DatabaseBlockStoreFactory service.
Bug: T291849
Change-Id: Ia1319f35bbc5bd786d1d96d330f94255d7b3582a
It was decided that deleteJoin() should continue to return void, so the
comment in BlockRestrictionStoreTest and the pass through in
BlockRestrictionStore were not correct.
Change-Id: I634e1e722d25d0cddeb27e051cb0d6da414ee393