This mostly reverts commit 28ad29ea0f.
Checking the validity of the provided email doesn't reveal any
information about any users, and it could help catch genuine mistakes,
e.g. if someone inputs the username in the email field.
Previously if an invalid email was provided, we showed a success
message that is an obvious lie (saying we sent an email to something
that isn't an email address).
Change-Id: Idec437b29b22e5b1e5aaff3846632fbc413a3dcb
* Favour early returns instead of long elseif chains that require
more context and awareness to understand and verify.
* Remove needless creation of newGood() for all but one return.
* Move $providerStatus out of conditional block, and remove the
apparent conditional check that implies that it can be falsey.
allowsAuthenticationDataChange() only returns Status.
* Flip the isListed condition to more clearly read as
setting isListed to false when disabled/!enabled, and delegating
to the parent method for other cases.
Change-Id: Ibd42b63b034e82b2e97c9a7f0ad074c14c45a6b9
Follows-up 64e6a78af3 (I1cb5f4c3ce), which started calling isListed
from ApiOpenSearch via PrefixSearch. These calls are pretty cheap,
and won't show up in production latencies or flame graphs since they're
limited to queries that explicitly search for "Special:" (including
colon).
However, when profiling it anyway, I noticed locally that the majority
of getListedPage is spent in one page, SpecialPasswordReset->isListed,
because it appears to be the only one that varies its response by
current User.
Varying access by user is perfectly fine, but this is something we do
at runtime via SpecialPage::execute/SpecialPage::checkPermissions/
SpecialPage::userCanExecute, e.g. as configured via the `$restriction`
parameter to the constructor, or getRestriction.
* The code comment above isListed implies that this varies by
feature enablement, which is now correct after this change.
* This change does not change who is allowed to reset passwords.
The definitive permission checks are elsewhere in PasswordReset,
we're only changing the inclusion of the page in UI listings.
* This change does not affect Special:Specialpages, because that
calls getUsablePages(), which applies the same permission
checks still via SpecialPasswordReset::userCanExecute().
Bug: T358938
Change-Id: I546ff0fd475fd386de5014cfdc30543aecaffd09
Changes to the use statements done automatically via script
Addition of missing use statements and changes to docs done manually
Change-Id: I443aada1c18c8628b02671aa9fd6f441961e5c2e
Replace all core calls to User::getQueryInfo() with an equivalent
SelectQueryBuilder.
Bug: T311866
Change-Id: Ib249a9d9098b1c09907a90607206edd8331bad3d
The motivation is to make the code less confusing. I hope this is the
case.
?? is an older PHP 7.0 feature.
??= was added in PHP 7.4, which we can finally use.
Change-Id: Id807affa52bd1151a74c064623b41d950a389560
Since f102d7b42e882b330030021bb3419af708b26fa5 in the
GlobalBlocking extension, global blocks are found when checking
for blocks, and do not need to be checked for separately from
core.
Bug: T317334
Depends-On: If0b19ef4cef084e83af27bd851ad3dd69bb0b4d9
Change-Id: I8415ff7bc2bfe2c935b986e1b99fd8684d1b330e
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
This covers all occurrences of /onfig->.*get( '/ in includes/.
Undoubtedly there are still plenty more to go.
Change-Id: I33196c4153437778496f40436bcde399638ac361
This allows the backend to do whatever it can to ensure atomicity, and
is also easier to read, since the intent is obvious.
Change-Id: Ibbfecd92a2c6d9a5997ca37ea101e068bd1e8202
* Convert everything that is protected to be private,
since the class is not stable to extend
* Remove PasswordReset::$hookContainer, unneeded
Additionally, add missing UserFactory::newFromRow,
for now just a wrapper for User::newFromRow
Bug: T253432
Change-Id: I1de57a08605ff6e0d2be8e276b7fcb08934fb5da
Deprecate lack of $hookContainer parameter to DefaultPreferencesFactory,
LinkHolderArray and PasswordReset constructors
This was split out from the main patch to create a migration window,
since deprecation messages from extensions now cause Jenkins to vote -1.
Depends-On: Ie097d8e12758f066aee14c740f9e07955aa510c1
Change-Id: I559640c9f4dc7ad5444fe1ef39d50e4504ae0b63
These were never meant to be part of the public interface and should not
ever have been marked with @since. They're only useful for constructing
the respective objects, which no outside users should be doing.
Change-Id: I86e01272d46fc72af32172d8a12b9180971d4613
Deprecating something means to say something nasty about it, or to draw
its character into question. For example, "this function is lazy and good
for nothing". Deprecatory remarks by a developer are generally taken as a
warning that violence will soon be done against the function in question.
Other developers are thus warned to avoid associating with the deprecated
function.
However, since wfDeprecated() was introduced, it has become obvious that
the targets of deprecation are not limited to functions. Developers can
deprecate literally anything: a parameter, a return value, a file
format, Mondays, the concept of being, etc. wfDeprecated() requires
every deprecatory statement to begin with "use of", leading to some
awkward sentences. For example, one might say: "Use of your mouth to
cough without it being covered by your arm is deprecated since 2020."
So, introduce wfDeprecatedMsg(), which allows deprecation messages to be
specified in plain text, with the caller description being optionally
appended. Migrate incorrect or gramatically awkward uses of wfDeprecated()
to wfDeprecatedMsg().
Change-Id: Ib3dd2fe37677d98425d0f3692db5c9e988943ae8
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
Followup patch for: b64b0f5. Show general message when an invalid email
is submitted.
Bug: T249730
Change-Id: I98a35af26930f3d66308065e271e9617fdbf5076
Add logic to reset users array that will receive the reset password email with
numeric keys. The array should have index 0 if it is not empty so that the
password reset process can run without 'Undefined' ErrorException.
Bug: T249709
Change-Id: Idc5456e0d3e77f2ae0542f6b972d168049e51d77
Hide the `requireemail` status from the resetting user when
requesting a password reset without supplying an email address.
Bug: T238961
Change-Id: Iee07564aac78d013ecc52192b536e92cb1ed4e8b
For all successfully submitted (i.e. valid input) password reset
requests, display the same information. This removes the
distinction between email and username resets, and only shows the
user what they've already submitted.
Bug: T238961
Change-Id: Ic17acecf1e44401f7607cdaf90dcee1a26b8405f
Add functionality that does not send password reset email to user accounts that turned on preference
that requires both username and email to be submitted in the PasswordReset form when only email is
provided.
Bug: T234401
Change-Id: I9bddc7073b8bcb52c4287b3d6c7343be29b717f2
User::trackBlockWithCookie and PasswordReset::isBlocked make decisions
about block behaviour based on the block parameters. This should be
done in the Block class.
Bug: T218905
Change-Id: Ia3f46abacdaf70e720b715b39dc60aed53be2d0a