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
* 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
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
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
Temporary users are blocked if their IP address is listed in
$wgDnsBlacklistUrls or $wgSoftBlockRanges.
Bug: T343704
Change-Id: Ia3383bd10c3c6c35c586550b68f4af5f4659e815
Ended up using
grep -Prl '\->setMethods\(' . | xargs sed -r -i 's/setMethods\(/onlyMethods\(/g'
special-casing setMethods( null ) -> onlyMethods( [] )
and then manual fix of failing test (from PS2 onwards).
Bug: T278010
Change-Id: I012dca7ae774bb430c1c44d50991ba0b633353f1
The problem was that when using $user->getBlock
within checkCondition (APCOND_BLOCKED) caused a infinite
recursion as calling getBlock eventually leads back to checkCondition.
The fix here is to stop using userHasRight as that is the cause of the recursion.
This also fixes testGetUserAutopromoteBlockedDoesNotRecurse test so it
shouldn't fail.
Bug: T270145
Change-Id: Ic751eba70730de286bbd55772bd7562459fb30b4
Some User methods fail if they are called before $wgRequest is
set. But according to the Setup.php comment, it is only set for b/c.
The global request object can be lazy-initialised at any time.
This is sufficient to avoid T263911 (loss/obfuscation of the $wgServer
error message).
In tests, try to keep $wgRequest and RequestContext::$request in sync.
Introduce MediaWikiIntegrationTestCase::setRequest() which sets both at
once, and use that instead of setMwGlobals() or direct assignment.
BlockManagerTest was accidentally exploiting the fact that the global
context request and $wgRequest were separate objects. Making them the
same causes session cookies to appear in the response, breaking the
cookie counts. Use a new response for the test.
Bug: T263911
Bug: T245940
Change-Id: I2be99f7251a837bc6b62be0b152038157dec10f2
Following 23c3c70d7f, soft deprecate the static methods on
DatabaseBlock that have been moved to DatabaseBlockStore:
* ::insert
* ::delete
* ::update
* ::purgeExpired
Update calls to the deprecated methods from core.
Change-Id: I1272eb978594fd4f386bda12cbc24131ad7d882f
The name change happened some time ago, and I think its
about time to start using the name name!
(Done with a find and replace)
My personal motivation for doing this is that I have started
trying out vscode as an IDE for mediawiki development, and
right now it doesn't appear to handle php aliases very well
or at all.
Change-Id: I412235d91ae26e4c1c6a62e0dbb7e7cf3c5ed4a6
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
DatabaseBlock methods for handling block cookies are deprecated, so
stop using these methods in tests and throw warnings.
Change-Id: I2b5cfd579aa14bbfc7a292587a288ee5032eb5ab
Before this commit, clearing a block cookie happens as a
side-effect of checking for a block cookie. After, a block cookie
is cleared if trackBlockWithCookie finds that there should be no
block cookie, but there is one.
Bug: T233595
Change-Id: Id5777361f95c60d2849cacba82f2ed9add647abf
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
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