Commit graph

382 commits

Author SHA1 Message Date
Gergő Tisza
f871f7b93e
Add WikiPageFactory
Replace WikiPage::factory with a proper factory object with dependency
injection (only for dependencies needed by the factory methods,
not WikiPage itself).

Change-Id: Ie7d6e40d8387d8bc4f8592a31fdd70d0aad510ae
2020-07-27 17:17:21 +02:00
jenkins-bot
6e971eb257 Merge "Check for unknown slot." 2020-07-20 15:20:13 +00:00
Cindy Cicalese
c69489f44c Check for unknown slot.
Bug: T220525
Change-Id: I89ac1679ea70cb403433f8b97fe11e8eb6811280
2020-07-20 10:39:28 -04:00
jenkins-bot
1334f4e9c8 Merge "MCR import" 2020-07-20 12:34:24 +00:00
daniel
7ffacacc6b MCR import
Bug: T220525
Change-Id: I7d41a8af12e33aed802526eb39a0880292c4f534
2020-07-18 20:34:16 -04:00
DannyS712
30cdc3500e ServiceWiring: Minor cleanup, fix a typo
Always acknowledge the $services passed to the function,
even if it isn't used.

Change-Id: Idd2a6237ba189e4ad2705e49f3912177f3721ef5
2020-07-16 16:09:24 +00:00
Nikki Nikkhoui
6c8187d4f8 UserFactory method for getting anonymous user
Create a method in UserFactory to instantiate an anonymous
user with an optional IP address.

Bug: T257464
Change-Id: I557620f9bcd4b646288b4a76b26c4730fccbc3d8
2020-07-15 00:07:45 +00:00
jenkins-bot
25d4b6cd38 Merge "Use DefaultOptionsLookup for default option in GenderCache" 2020-06-29 08:28:45 +00:00
Umherirrender
63eaa9ae89 Use DefaultOptionsLookup for default option in GenderCache
Change-Id: I778d2c4cd8de2aee138566fe82d658d046edf3f4
2020-06-28 16:53:24 +02:00
jenkins-bot
5b0e900eac Merge "Use TitleParser in UserNameUtils" 2020-06-28 11:42:10 +00:00
jenkins-bot
be7869b0a1 Merge "Use StatsdDataFactory service in ParserCache" 2020-06-28 11:41:49 +00:00
Umherirrender
fd666afbb0 Use MediaWikiServices::getAuthManager instead of AuthManager::singleton
Change-Id: I92c31b963095eab751df9f8c1715e8e23b7e8485
2020-06-22 00:57:08 +00:00
Umherirrender
be57334d8d Use TitleParser in UserNameUtils
Bug: T245231
Change-Id: I405c26f7a7a1bc3dedaeab4d28ff2d547922fc44
2020-06-21 21:28:03 +02:00
Umherirrender
381c934075 Use StatsdDataFactory service in ParserCache
New argument is optional, because extension extends this class

Change-Id: I710016c0ca9f8bb595d9f3ccd9452c76fdda3ef3
2020-06-21 21:15:17 +02:00
jenkins-bot
1e6fa3e186 Merge "Introduce BlockPermissionChecker service for validating block targets" 2020-06-16 15:06:32 +00:00
jenkins-bot
c41566413b Merge "skins: Port SkinFallback and SkinApiOutput to a generic SkinMustache class" 2020-06-15 18:13:50 +00:00
jdlrobson
26d5f78f84 skins: Port SkinFallback and SkinApiOutput to a generic SkinMustache class
The new SkinMustache class is based on the emerging class in Vector.
Having this in core, will allow Vector to make use of this class
immediately and provide a minimal generic mechanism going forward
for rendering skins using Mustache. For now, I've fleshed out the minimum
possible data in getTemplateData which are based on existing functions in
Vector.

The Skin class now takes a generic options parameter which allows
registration of a skin using the SkinMustache class with a templateDirectory
option pointing to the associated template. A `styles` option can be passed
to define stylesheets that should be associated with the skin.

The SkinApi and SkinFallback classes are reduced significantly.

There are no known uses of SkinApiTemplate and it is thus removed.

SkinFallbackTemplate is removed and its functions copied across to
SkinFallback

End user changes:
* The fallback skin no longer prints the confusing warning message if the default
  skin is setup incorrectly. Previously viewing the fallback skin with useskin
  indicated that wgDefaultSkin was not set correctly which was misleading and confusing.
* Factory functions now receive skin options as a second parameter and the service as a
  first - this is due to how ObjectFactory handles the extraArgs key for 'factory' key
  - placing it at the beginning.

Bug: T254048
Change-Id: Ibbabd1d0f26efebf8f8ff068966685dc2191c527
2020-06-15 10:51:31 -07:00
jenkins-bot
c54e76c4ce Merge "Move autopromote groups logic into UserGroupManager" 2020-06-12 18:10:37 +00:00
Petr Pchelko
cd6b72ecd7 Move autopromote groups logic into UserGroupManager
Bug: T252621
Change-Id: Ic51119cd01771ab1b68294fa5dfacb8034e33b6b
2020-06-11 22:13:48 +00:00
DannyS712
61a3a8f734 UserFactory v.1 - wrapper for User::newFrom* static methods
Makes it possible to mock static User methods in tests;
actually introducing dependency injection to the User class is left for
the future.

New class has 100% code coverage

Bug: T253432
Change-Id: I0b93da09124d95beafd84e932b214909ce920230
2020-06-10 20:38:26 -07:00
Martin Urbanec
2cef6bc035 Introduce BlockPermissionChecker service for validating block targets
This intentionally doesn't change the usages of SpecialBlock
method nor does it mark it as deprecated, because that is planned
to be done in follow-up patches:

* Ide31da469297f4582ad0e3f7f1a7c40d542923f8
* Ifdced735b694b85116cb0e43dadbfa8e4cdb8cab

Bug: T189073
Bug: T251861
Change-Id: Ib230f1cdb745937fac7512924f1d79e7b3542ab0
2020-06-10 22:09:10 +00:00
Nikki Nikkhoui
300fcfd00b REST me/contributions: Returns 401 Unauthorized
This is the first in a chain of patches that iteratively create
the me/contributions endpoint that returns a list
of contributions by the currently logged in user.

This patch contains stubs for major classes needed
as well as implementation and test just for returning
a 401 Unauthorized for anonymous users.

Bug:T252202
Change-Id: Ib75711bb015f476e9d486cb3008eb7b06b148d00
2020-06-09 15:00:25 +00:00
jenkins-bot
748965cb95 Merge "Add new WatchlistNotificationManager service" 2020-06-04 20:24:20 +00:00
Petr Pchelko
40b88d635b Create UserGroupManager
Introduce a UserGroupManagerFactory and UserGroupManager.
The factory utilizes the same pattern as RevisionStore
for access to user groups of a foreign wiki.

Some user group related methods were ported from User
and UserGroupMembership and deprecated, more methods to
be moved over in future patches, not to make this one to large.

Eventually as all the group-related methods are moved and their
usages are replaced, the need for the UserRightsProxy will disappear,
thus it also will be deprecated and removed. Currently for backwards
compatibility, I've had to create artificial UserIdentityValue
objects in some of the deprecated methods to avoid making transitional
temporary methods in the UserGroupManager that would take user ID
instead of the UserIdentity. All of this will go away once migration
to UserGroupManager is completed.

Bug: T234921
Change-Id: If29c6a03dfdbb80b2e846243f7e384b334da9f07
2020-06-03 16:46:51 -07:00
DannyS712
c243c1b06e Add new WatchlistNotificationManager service
Replaces watchlist notification methods in Title and User classes:
* Title::getNotificationTimestamp -> ::getTitleNotificationTimestamp
* User::clearNotification -> ::clearTitleUserNotifications
* User::clearAllNotifications -> ::clearAllUserNotifications

New service has 67.90% code coverage with pure Unit tests; as well
as integration tests for the DeferredUpdates part

A follow-up patch will deprecate the replaced methods, as well
as document that the `UserClearNewTalkNotification` hook now only
provides a UserIdentity (typehint added in T253435 but until now
a full User was still provided).

Bug: T208777
Change-Id: I6f388c04cb9dc65b20ff028ece607c3dc131dfc5
2020-06-02 23:22:02 +00:00
DannyS712
1ccf066380 Add a new UserEditTracker service for user edit counts and timing
Moved to the new service are the following User:: methods:
* ::getEditCount
* ::getFirstEditTimestamp
* ::getLatestEditTimestamp
* ::getEditTimestamp
* ::initEditCountInternal

A subsequent patch will replace existing uses in core and deprecate the
User methods.

The new service has 100% test coverage with pure Unit tests.

Bug: T253431
Change-Id: If96f9d41026aa358c0fe269a3e078af5f6f058f2
2020-06-02 03:00:05 +00:00
Tim Starling
feba7ee306 Use HttpRequestFactory::createMultiClient() in core where possible
* Use createMultiClient() in CdnCacheUpdate. This will reduce the
  timeout from a hard-coded 900s to a configurable 25s. This is not
  used in WMF production.
* Use createMultiClient() in the VirtualRESTServiceClient service. This
  should have no effect in production since the service is broken per
  T175224.
* Use the new createMultiClient() in the old createMultiClient(). The
  configuration is the same except that the maximum timeouts are now
  respected.

Bug: T245170
Change-Id: I63139d29471bc59e9ef60032fd812a1f24644113
2020-06-02 10:51:43 +10:00
DannyS712
b6f020ff66 ContentHandlerFactory: Inject LoggerInstance instead of using wfDebugLog
Change-Id: Ifed1f2e28a5fec365103b1588a8cabff10ce6007
2020-06-01 22:37:12 +00:00
DannyS712
d6a38d0f10 Add ContentModelChangeFactory, implemented by PageCommandFactory
Bug: T253080
Change-Id: I62eda1163cd5b0472af912e8dbd5843df8303b8d
2020-05-30 22:36:16 +00:00
Tim Starling
68c433bd23 Hooks::run() call site migration
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
2020-05-30 14:23:28 +00:00
Aaron Schulz
f0039707a2 Avoid HtmlCacheUpdateJob purges for content no longer in CDN
Bug: T250205
Change-Id: I0ddac44ec40e51acb8c76feff37c11481d724798
2020-05-27 23:36:54 +00:00
jenkins-bot
d535ebeb51 Merge "WatchedItemStore: Enforce a maximum watchlist expiry duration" 2020-05-27 22:32:06 +00:00
jenkins-bot
500ece7e34 Merge "ServiceWiring for SlotRoleRegistry: use SlotRoleStore service directly" 2020-05-27 22:29:10 +00:00
DannyS712
56f5dcd36b ServiceWiring for SlotRoleRegistry: use SlotRoleStore service directly
The fact that it is retrieved from NameTableStoreFactory is an
implementation detail that the caller need not know about

Change-Id: Iaa2d56bd559f73b3b9067ad92a977eeabc08c9d3
2020-05-27 20:42:42 +00:00
jenkins-bot
003b68085b Merge "MediaWikiServices: All logic for services should be in ServiceWiring" 2020-05-27 19:54:58 +00:00
DannyS712
078972923c MediaWikiServices: All logic for services should be in ServiceWiring
Move handling of the different services that are created with
NameTableStoreFactory to ServiceWiring, so that MediaWikiServices
can just call $this->getService() and nothing else.

For objects created from specs via ObjectFactory, services are retrieved
via ContainerInterface::get( 'ServiceName' ), an alias for ::getService.
Since the different stores created with NameTableStoreFactory were not
individually defined as services, they would not have been usable
with an ObjectFactory spec.

Change-Id: I8f862efeffe91a8ca1c4cbc48a5c429d6c78973c
2020-05-27 15:00:01 +00:00
DannyS712
35c0518959 Inject SpamChecker where needed, hard deprecate EditPage static methods
Bug: T251015
Change-Id: I2df950d5ac9a7fc342409f778d7f9c2418cdd7af
2020-05-26 03:17:29 -07:00
Derick A
707567bd73 linker: Move Linker::normaliseSpecialPage to LinkRenderer class
Would have love to just kill Linker::normaliseSpecialPage() but
the deprecation policy has to be followed and we'll drop the above
method in 1.36.

For now, we'll just soft and hard deprecate it, also, callers have
been updated.

Dependency inject SpecialPageFactory to LinkRenderer service and
note that ->normalizeTarget() is only for internal use by Linker
& DummyLinker via their `->normaliseSpecialPage()` methods.

Also, updated unit tests to capture injecting the special page
factory class.

Change-Id: I951403c89ff497fd1f7441ad0304dd5bc9442ad7
2020-05-24 23:11:55 +00:00
MusikAnimal
0694cc02f1 WatchedItemStore: Enforce a maximum watchlist expiry duration
Introduces $wgWatchlistExpiryMaxDuration which is used instead of given
expiry if the given exceeds it. This is done in the storage layer. The
reasoning is to control the size of the watchlist_expiry table. Hence,
the max duration does not apply to indefinite expiries (since that would
mean now row in watchlist_expiry).

The frontend is responsible for disallowing expiries greater than the
max, if it choses to do so.

APIs should now pass in $wgWatchlistExpiryMaxDuration as the PARAM_MAX
setting for the 'expiry' type. They should also set PARAM_USE_MAX so
that the maximum value is used if it is exceeded.

Other APIs that watch pages will be updated in separate patches
(see T248512 and T248514).

Bug: T249672
Change-Id: I811c444c36c1da1470f2d6e185404b6121a263eb
2020-05-22 00:15:23 -04:00
jenkins-bot
b227bdd42c Merge "Respect configured default HTTP timeouts, and introduce max timeouts" 2020-05-21 20:00:45 +00:00
jenkins-bot
789088bc40 Merge "objectcache: dependency inject LoadBalancer into SqlBagOStuff" 2020-05-21 01:07:23 +00:00
jenkins-bot
3f2937810e Merge "mime: Convert built-in MIME mappings to PHP arrays" 2020-05-21 01:01:06 +00:00
Tim Starling
504fe2af11 Respect configured default HTTP timeouts, and introduce max timeouts
* Add HttpRequestFactory::createMultiClient(), which returns a
  MultiHttpClient with configured defaults applied. This is similar to
  the recently-deprecated Http::createMultiClient().
* Introduce $wgHTTPMaxTimeout and $wgHTTPMaxConnectTimeout which, if set
  to a lower value than their defaults of infinity, will limit the
  applied HTTP timeouts, whether configured or passed on a per-request
  basis. This is based on the frequently correct assumption that ops know
  more about timeouts than developers.
* In case developers believe, after becoming aware of this new situation,
  that they actually do know more about timeouts than ops, it is possible
  to override the configured maximum by passing similarly named options
  to HttpRequestFactory::createMultiClient() and
  HttpRequestFactory::create().
* Apply modern standards to HttpRequestFactory by injecting a logger and
  all configuration parameters used by its backends.
* As in Http, the new createMultiClient() will use a MediaWiki/1.35
  User-Agent and the 'http' channel for logging.
* Document that no proxy will be used for createMultiClient().
  Proxy config is weird and was previously a good reason to use
  MultiHttpClient over HttpRequestFactory.
* Deprecate direct construction of MWHttpRequest without a timeout
  parameter

Bug: T245170
Change-Id: I8252f6c854b98059f4916d5460ea71cf4b580149
2020-05-21 09:30:57 +10:00
Ori Livneh
cb44ddf85b mime: Convert built-in MIME mappings to PHP arrays
Currently, MimeAnalyzer builds the internal mappings of MIME types <=> file
extensions by concatenating several string buffers in mime.type format into a
giant string, and then parsing it. The mapping of MIME types to internal
media types is built up in a similar way, except we use a dubious homegrown
format with undocumented conventions. It's a mess, and an expensive one --
~1.5% of api.php CPU time on the WMF cluster is spent building these buffers
and parsing them. Converting the mappings to PHP associative arrays makes
them much cheaper to load and easier to maintain.

Doing this without breaking compatibility with existing behaviors requires
some delicate footwork. The current mime.types buffer is made up of the
following fragments, in order:

  1) MimeAnalyzer::$wellKnownTypes
  2) If $wgMimeTypeFile == 'includes/mime.types' (sic!):
       the contents of includes/libs/mime/mime.types.
     If $wgMimeTypeFile is another file path (e.g., '/etc/mime.types'):
       the contents of that file.
     If !wg$MimeTypeFile, this fragment is blank.
  3) MimeAnalyzer::$extraTypes (populated by extensions via hook).

The mime.info buffer is built up in the exact same way, except it's
MimeAnalyzer::$wellKnownInfo, $wgMimeInfoFile, and MimeAnalyzer::$extraInfo.

What this means in effect is that some built-in MediaWiki MIME mappings are
"baked in" (anything in MimeAnalyzer::$wellKnown*), and others can be
overridden (anything in includes/libs/mime/mime.*).

To avoid breaking backward compatibility, we have to preserve the
distinction.  Thus this change has two MIME mappings, encapsulated in two
classes: 'MimeMapMinimal', which contains just the baked-in mappings, and
'MimeMap' which contains both the baked-in and overridable mappings.  We also
have to keep the code for parsing mime.types and the ad-hoc mime.info format,
at least for now.

In a FUTURE change (i.e., not here), I think we can:

* Deprecate $wgMimeTypeFile in favor of a new config var,
  $wgExtraMimeTypeFile. $wgMimeTypeFile is evil because if you are using to
  add support for additional MIME types, you can end up unwittingly dropping
  support for other types that exist in MediaWiki's mime.types but not your
  file. The new $wgExtraMimeTypeFile would only be used to add new MIME
  mappings on top of the standard MimeMappings, which was probably the
  original intent for $wgMimeTypeFile.
* Deprecate $wgMimeInfoFile. I don't think we need to provide a replacement,
  because extensions can use the hook, and I doubt anyone is using the config
  var. But if we wanted to provide an alternative, we could have a
  $wgExtraMimeInfoMap that has an array of extra mappings.
* Deprecate MimeAnalyzer::addExtraTypes and MimeAnalyzer::addExtraInfo, and
  provide alternative interfaces that take structured input instead of string
  blobs.

I tested this by dumping the internal state of MimeAnalyzer before and after
this CL using the script in Ib856a69fe, using both default and custom values
for $wgMimeInfo(File|Type).

Bug: T252228
Change-Id: I9b2979d3c9c0dee96bb19e0290f680724e718891
2020-05-19 00:59:52 -04:00
Aaron Schulz
6a8943d8c5 objectcache: dependency inject LoadBalancer into SqlBagOStuff
Clean up the recursive DB dependency mitigation logic by having
ServiceContainer detect recursion and throw an appropriate error.
Catch the error and use EmptyBagOStuff in such cases. This works
better than checking getQoS() since that begs the question by
requiring the cache instance to begin with.

Also add support for using different LoadBalancer instances for
local and global keys in SqlBagOStuff. This makes it easier to
share keys between projects.

Bug: T229062
Change-Id: Ib8ec1845bcf1b86cbb3bededa0ca7621a0ca293a
2020-05-18 21:04:17 -07:00
jenkins-bot
14c81b90b6 Merge "skins: Allow $wgValidSkinNames to take ObjectFactory spec" 2020-05-16 02:17:08 +00:00
Reedy
1b1a17bcef skins: Allow $wgValidSkinNames to take ObjectFactory spec
Bug: T252760
Change-Id: I189de448c3b2c56dfe6bf49170d7746943cf2417
2020-05-16 01:57:25 +00:00
jenkins-bot
7a0cfac4e6 Merge "Add HookRegistry" 2020-05-14 13:33:49 +00:00
DannyS712
29aa36c06e Add MergeHistoryFactory interface, implemented by PageCommandFactory
Bug: T249446
Change-Id: I94676e065a8aed5cad2fe2d5cf16ca586adce97d
2020-05-13 19:08:09 +00:00
Tim Starling
b3d762e148 Add HookRegistry
Add a HookRegistry interface and two concrete implementations,
representing HookContainer's view of its environment. This simplifies
creation of a HookContainer for testing.

Add MediaWikiTestCaseTrait::createHookContainer() which can be used
in most of the places that were previously creating mock hook
containers. It can also replace setTemporaryHook() in some cases.

Change-Id: I9ce15591dc40b3d717c203fa973141aa45a2500c
2020-05-13 11:51:02 +10:00