Similar to checkPasswordCannotMatchUsername, MediaWiki should ensure
that users are unable to accidentally create or edit their username
to include their password as a substring of said username.
Bug: T241845
Change-Id: I437e91a5b83a792c5ad31e291915491bbb382dfa
Drawing from comments associated with `User::newSystemUser` for
checking if a user is a system user, a new method, `User:isSystemUser`
is split out to avoid duplication elsewhere.
Bug: T237356
Change-Id: I73f25a10df2c28a69f612eb1db3e91b7125383d9
DatabaseBlock methods for handling block cookies are deprecated, so
stop using these methods in tests and throw warnings.
Change-Id: I2b5cfd579aa14bbfc7a292587a288ee5032eb5ab
To avoid preference bloat, this preference is hidden unless the new
sysadmin config $wgSearchMatchRedirectPreference is set.
Bug: T235263
Change-Id: Ic16f53a4e6ddb6da071d63cd5da28d937d4692c8
Various maintenance scripts assume reserved usernames like
"MediaWiki default" exist, but since they're reserved
User::isUsableName() returns false and therefore the actor migration
created them as anonymous actors. Which would then prevent those
maintenance scripts from using User::newSystemUser() to ensure they
actually exist.
This adjusts User::newSystemUser() to be able to create users for
those anonymous actors.
This also adjusts uses of "MediaWiki default" in core to create it as a
system user.
Bug: T236444
Change-Id: I59a646df36ff9343cc43c05aa20b2b69b2ee124a
Before this commit, several tests in UserTest set User::mBlock, then
call BlockManager::trackBlockWithCookie, which indirectly sets
User::mBlock. These lines are safe to remove, ahead of deprecating
public access to the property (see T229035).
Change-Id: I36a833ee0904ed1573ac414c8524b60210d97feb
This was previously hardcoded from three places: 1) Upon viewing EditPage,
2) Upon viewing SpecialCreateAccount, 3) For any url if the user is
logged-in (User::loadFromSession/isLoggedIn).
== User::loadFromSession
Performing cookie blocks from here created a circular dependency because
Block may need the user language for localisation, which is determined by
asking the User object. This was previously worked around by using a
DeferredUpdate (T180050, T226777). Moving this logic explicitly to the
end of the pre-send cycle in MediaWiki::preOutputCommit breaks the cycle.
This is also where other request-specific handling resides already.
== Limited effect on unregistered users
When an unregistered user performs an edit, and gets blocked,
the cookie block is not applied until they open built-in editor
or CreateAccount page. This makes it more likely for a user's
IP to change meanwhile. Either intentionally, or simply due to
IPs varying naturally (e.g. between mobile locations, or when
going on/off WiFi). By applying it throughout sessioned page
views for unregistered users, it is more likely to get set.
Similar to what was already done for logged-in users.
This commit also makes the intent of not caching EditPage and
SpecialCreateAccount explicit. This was previously implicit
through nothing having called setCdnMaxage() and/or due to
Session::persist being checked for by OutputPage::sendCacheControl.
Bug: T233594
Change-Id: Icf5a00f9b41d31bb6d4742c049feca0039d0c9d9
assertSame() is guaranteed to not do any type conversion. This can be
critical when acciden tially comparing, for example, 0 to 0.0.
Change-Id: Iffcc9bda69573623ba14af655dcd697d0fcce525
Blocks are checked from the User object. Specifically,
User::getBlockedStatus instantiates a BlockManager and calls
BlockManager::getUserBlock. However, checking the block often depends
on knowing more about the state than the User should know. As a result,
the global user and request objects were passed into the block manager
on construction.
Whether the global request object should be passed into a service
constructor is still up for debate, so this moves the check for the
global state back to User::getBlockedStatus for now. (Note that it
reintroduces the problem of the User knowing more about state than it
should.)
This change also makes clearer the cases in which
BlockManager::getUserBlock is called from the User.
Different blocks may be sought, depending on the user and their
permissions. The user may be:
(1) The global user (and can be affected by IP blocks). The global
request object is needed for checking the IP address, the XFF
header and the cookies.
(2) The global user (and exempt from IP blocks). The global request
object is needed for checking the cookies.
(3) Another user (not the global user). No request object is available
or needed; just look for a block against the user account.
Cases #1 and #2 check whether the global user is blocked in practice;
the block may due to their user account being blocked or to an IP
address block or cookie block (or multiple of these). Case #3 simply
checks whether a user's account is blocked, and does not determine
whether the person using that account is affected in practice by any
IP address or cookie blocks.
Bug: T231919
Change-Id: I3f51fd3579514b83b567dfe20926df2f0930dc85
This removes most of the pre-actor user and user_text columns, and the
$wgActorTableSchemaMigrationStage setting that used to determine
whether the columns were used.
rev_user and rev_user_text remain in the code, as on Wikimedia wikis the
revision table is too large to alter at this time. A future change will
combine that with the removal of rev_comment, rev_content_model, and
rev_content_format (and the addition of rev_comment_id and rev_actor).
ActorMigration's constructor continues to take a $stage parameter, and
continues to have the logic for handling it, for the benefit of
extensions that might need their own migration process. Code using
ActorMigration for accessing the core fields should be updated to use
the new actor fields directly. That will be done for in a followup.
Bug: T188327
Change-Id: Id35544b879af1cd708f3efd303fce8d9a1b9eb02
Was reverted by I549810a4cd2e424cc4a438887d2f24614a24cc00 due to
T224607.
Original change by Vedmaka Wakalaka was
Ia0d840b772ea5f20c9594ce151cc57adc270e48b.
Original commit message:
The following methods should are factored out of the User class into PermissionManager,
leaving only deprecated stubs:
- User::isAllowed -> PermissionManager::userHasRight
- User::getRights -> PermissionManager::getUserPermissions
- User::groupHasPermission -> PermissionManager::groupHasPermission
- User::getGroupPermissions -> PermissionManager::getGroupPermissions
-User::getGroupsWithPermission -> PermissionManager::getGroupsWithPermission
- User::groupHasPermission -> PermissionManager::groupHasPermission
- User::isEveryoneAllowed -> PermissionManager::isEveryoneAllowed
- User::getAllRights -> PermissionManager::getAllPermissions
Depends-On: I7909e9bd6bbfbd708c0a00b861a9b22a38c6665d
Bug: T218558
Bug: T223294
Change-Id: I8899240378f636ea70f447616710516c0a3c5c31
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
Move the cookie blocking logic into one place. Specifically, move
these methods to the BlockManager:
* User::trackBlockWithCookie
* DatabaseBlock::setCookie
* DatabaseBlock::clearCookie
* DatabaseBlock::getCookieValue
* DatabaseBlock::getIdFromCookieValue
* AbstractBlock::shouldTrackWithCookie
After this, BlockManager::trackBlockWithCookie should be called to
track a block, and BlockManager::clearBlockCookie should be called
to unset the cookie. The other methods in the above list are
helper methods that are made private or marked internal.
Also update places in core that call User::trackBlockWithCookie to
BlockManager::trackBlockWithCookie
Bug: T225141
Change-Id: I818962c6932c01c841a549a101637e00a7593e48
Keep Block as a deprecated class alias for DatabaseBlock.
Update calls to the Block constructor and Block static
methods from external classes.
Also update documentation in several places that refer to
blocks as Blocks.
Bug: T222737
Change-Id: I6d96b63ca0a84bee19486471e0a16a53a79d768a
This commit splits the existing Block class into AbstractBlock, Block
and SystemBlock.
Before this patch, the Block class represents several types of
blocks, which can be separated into blocks stored in the database,
and temporary blocks created by the system. These are now
represented by Block and SystemBlock, which inherit from
AbstractBlock.
This lays the foundations for:
* enforcing block parameters from multiple blocks that apply to a
user/IP address
* improvements to the Block API, including the addition of services
Breaking changes: functions expecting a Block object should still
expect a Block object if it came from the database, but other
functions may now need to expect an AbstractBlock or SystemBlock
object. (Note that an alternative naming scheme, in which the
abstract class is called Block and the subclasses are DatabaseBlock
and SystemBlock, avoids this breakage. However, it introduces more
breakages to calls to static Block methods and new Block
instantiations.)
Changes to tests: system blocks don't set the $blockCreateAccount or
$mExipry block properties, so remove/change any tests that assume
they do.
Bug: T222737
Change-Id: I83bceb5e5049e254c90ace060f8f8fad44696c67
Stop-gap solution for the problem described in T222212.
Force the User ID and Actor ID to zero for users loaded
from the database of another wiki, to prevent subtle data
corruption and confusing failure modes.
Bug: T222381
Change-Id: Ic585f972d61da136744d080df13d8eb1ecd04cf5
I wasn't able to port some places that rely on isAllowed, getOption, or
related methods.
This adds isRegistered() to UserIdentity, which works like
User::isLoggedIn() but with a better name.
I also cleaned up User mocks in WatchedItemQueryServiceUnitTest in the
course of debugging test failures when switching them to
UserIdentityValue instead of mock Users where possible. They now specify
explicitly which methods are allowed to be called on their User objects,
which I believe is good practice for mocks (and unfortunately PHPUnit
makes it awkward).
Bug: T207972
Depends-On: I883d506197a011fe4c102b72df4d9deb58ab5ca2
Change-Id: Iadbf7bc31a496899dbef44e49065ff89f37aea89
Probably good to start testing this in CI sometime soon.
This also updates a bunch of tests that were forcing an older stage to
force SCHEMA_COMPAT_NEW instead, or to test both ways (until a future
patch removes the _OLD version).
Bug: T188327
Change-Id: Icb9b55cb9d754f2d30d6883005658b9670834756
This patch makes sure, that idFromName always returns either an int
or null value. The $idCacheByName can contain string values so we cast
the values if necessary.
An alternative could have been to make sure that just int values go
into the cache. But since the cache is public the current approach
to seems to be better atm.
Change-Id: I3085d89b93db2b888c190ba193623b86dc93759a
This introduces a minimal BlockManager service, for getting blocks
that apply to a User.
Move the part of User::getBlockedStatus that checks for the blocks
into BlockManager::getUserBlock, and move the related helper
methods from User to BlockManager.
Hard deprecate or remove these helper methods, and move to private
methods in the BlockManager:
* User::getBlockFromCookieValue
* User::isLocallyBlockedProxy
* User::inDnsBlacklist
Soft deprecate these helper methods, and move to public methods in
the BlockManager:
* User::isDnsBlacklisted
Add tests to cover the methods moved to BlockManager.
Bug: T219441
Change-Id: I0af658d71288376735cebe541215383b56bb72e5
The method User::isBlocked() attempts to answer two questions:
(1) Does the user have a block?
(2) Is the user prevented from performing this action?
The method can answer #1, but it cannot answer #2. Since User::getBlock() can
also answer #1, this method is redundant. The method cannot answer #2 because
there is not enough context in order to answer that question.
If access is being checked against a Title object, all access checks can be
performed with PermissionManager:userCan() which will also check the user's
blocks.
If performing all access checks is not desirable, using
PermissionManager::isBlockedFrom() is also acceptable for only checking if the
user is blocked. This method does *not* determine if the action is allowed,
only that the user's block applies to that Title.
If access is being checked without an existing Title, User::getBlock() can be
used to get the user's block. Then Block::appliesToRight() can be used to
determine if the block applies explicitly to a right (or returns null if
it is unknown or false if explicitly allowed). If the user is creating a new
Title, but the text of the title is not yet known (as in the case of Wikibase),
access should be checked with Block::appliesToNamespace().
Bug: T209004
Change-Id: Ic0ad1b92e957797fee8dcd00bd1092fe69fa58f1
Use getters and setters for $mReason, $mTimestamp, $mExpiry and
$mHideName; use Block::getType to check if a block is an autoblock
instead of checking $mAuto; no change needed for $mParentBlockId,
which is not accessed externally.
Change-Id: I767ed44ce4c2e21f53962d75fb86891add2282f6
$wgUser is not guaranteed to exist until MediaWiki has been fully
initialized; block status needs to be checked early on for
authentication-related permission checks.
Bug: T218608
Change-Id: I16315c071855024bc0412d5360c95f843420d9a9
This will be used by the GrowthExperiments
Mentorship module to show when a user made their
latest contribution.
* Introduce a private function to reduce duplication with
getFirstEditTimestamp()
* Add unit tests for both
Bug: T216631
Change-Id: Ica3e6e7165496bdc9b8f12972cf93847ecfffa50