Commit graph

39 commits

Author SHA1 Message Date
libraryupgrader
5357695270 build: Updating dependencies
composer:
* mediawiki/mediawiki-codesniffer: 36.0.0 → 37.0.0
  The following sniffs now pass and were enabled:
  * Generic.ControlStructures.InlineControlStructure
  * MediaWiki.PHPUnit.AssertCount.NotUsed

npm:
* svgo: 2.3.0 → 2.3.1
  * https://npmjs.com/advisories/1754 (CVE-2021-33587)

Change-Id: I2a9bbee2fecbf7259876d335f565ece4b3622426
2021-07-22 03:36:05 +00:00
DannyS712
b876af50cc Fix order of parameters in assertions
Should be expected, and then actual

Switched some assertEquals to assertSame to fix failing
phpcs sniffs

Change-Id: I7257c5afacd22fed78a58f3cc918b721ac11a46d
2021-05-03 15:50:53 +00:00
DannyS712
12ffb90aa8 Convert MWBasicRequestAuthorizerTest to a unit test
Already essentially a unit test, does not use any integration

Change-Id: I705c9e5fb04103f305e26b7cd677cf68fc7b73b5
2021-04-23 23:35:09 +00:00
Thiemo Kreuz
b95a07380a Remove meaningless ->expects( $this->any() ) from all tests
It is not entirely meaningless. It might be an indicator that
the number of calls to a method is intentionally unlimited.
This is similar to e.g. an @inheritDoc PHPDoc comment that
marks a method as being "intentionally undocumented".

However, what's the meaning of being "intentionally
unconstrained"? Let's just not have any constraint then.

I feel all these ->expects( $this->any() ) bloat the test
code so much that it's never worth it.

Change-Id: I9925e7706bd03e1666f6eb0b284cb42b0dd3be23
2021-04-23 11:58:58 +02:00
Thiemo Kreuz
f36808dddc Use UserIdentityValue in tests where possible
… instead of PHPUnit mocks. The tiny value class is made for
this.

Change-Id: Ie04cde57126fcafabf8906f9644c6e80345d8a48
2021-04-22 09:32:43 +02:00
Daimona Eaytoy
535d7abf59 phpunit: Mass-replace setMethods with onlyMethods and adjust
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
2021-04-16 20:15:00 +02:00
daniel
fed7f0b179 Remove $actor field from UsererIdentityValue
Code that needs to store an actor ID in the database to
represent a UserIdentity, or needs to construct a UserIdentity based on
an actor ID loaded from the database, should use the ActorNormalization
service.

Note: The getActorId() method is removed from the UserIdentity interface,
but all concrete classes continue to support it for now.
UsererIdentityValue::getActorId() is hard deprecated and should
be removed in 1.37. It always returns 0.
User::getActorId() is not deprecated at this point.

Bug: T274179
Depends-On: Id2b3ddf6a2a7cdf90f8936a69148d2cce6fde237
Change-Id: I9925906d11e47efaec3c1f48d5cb3f9896a982c1
2021-04-13 18:18:06 +00:00
DannyS712
60a4cc0a81 Remove unused EntryPointTest::$mockHandler
Change-Id: I253cdf9819828ea9ef13c9685fe92c6ed27ce9c4
2021-03-14 20:31:57 +00:00
Petr Pchelko
3a2e8883b4 Rest: use Authority in all core handlers
Bug: T239753
Change-Id: Idf2229255f49514dd8b68bf63573c5b619b4f2f1
2021-01-21 18:22:33 -06:00
Petr Pchelko
22c47c4edd Rest: inject Authority into Handler
Bug: T239753
Change-Id: Iddde137c5a86786357d67458f28fe3e4d6e98710
2021-01-21 15:09:34 -06:00
David Barratt
c36b320454
Handle CORS preflight request and prevent anon users from unsafe methods
Creates an OPTIONS handler that handles any OPTIONS requests that are
not already handled by a handler. CORS has no mechanism to ensure the
user is authenticated, so the Router will reject cross-origin requests
from anon users.

This change allows authenticated users to make cross-origin
requests if they authenticate with OAuth or if
$wgRestAllowCrossOriginCookieAuth is enabled.

Bug: T232176
Bug: T262712
Change-Id: I128b4bdbec4f6bea35142153c951fd7b79617106
2020-09-21 19:29:40 -04:00
C. Scott Ananian
4a1b4aeb2a Rest: Use try/catch to handle URIs with embedded colon
This is a follow up to a previous fix in
4079d328e7 which used parse_url()==false
as an indirect test to see if `new Uri()` would throw.  Avoid the
indirection and use a try/catch instead to be more robust against
fixes in the Uri library and/or the parse_url() implementation.

Bug: T256831
Bug: T261344
Change-Id: Ia52c5b2c77a4481afd82b468c2f7fb3c05996a91
2020-09-04 13:50:28 +00:00
David Barratt
ab06b05619
Add option to enable cross-origin resource sharing (CORS) in REST API
When MediaWiki is not behind an intranet, it is completely safe to
add the Access-Control-Allow-Origin: * header to responses and allow
cross-origin sites to access the REST API.

Bug: T232176
Change-Id: Ic0658039a6a46ee4f50c76f5d100450fdef7525a
2020-08-04 15:49:58 -04:00
Ammar Abdulhamid
6438a52c06 Fix RequestFromGlobalsTest failing in Travis CI
Add the port to the 'REQUEST_URI' index to ensure the stubbed
port is properly returned.

Stubbing $_SERVER['SERVER_PORT'] directly apparently does not
work because WebRequest::getGlobalRequestURL() does not ask for
the port from that index.

Follow-up: Ib829afc7b33419b01e69ababa147d33b30c0fbcb

Bug: T259094
Change-Id: Iff8fab7b7eeb4c3f44072b83dc92c6dd895841c3
2020-07-29 08:34:40 +01:00
Ammar Abdulhamid
4079d328e7 Rest: Handle Uri constructor exception
All titles that contain a colon followed by a number cannot, currently,
be accessed via the Rest endpoint.

For example https://en.wikipedia.org/wiki/3:33 is a valid title/article
on English Wikipedia and can be accessed there the index/api.php entry
points. But the rest endpoint will fatal:
https://en.wikipedia.org/w/rest.php/v1/page/3:33/history

The exception is thrown in Uri constructor of GuzzleHttp library
if parse_url() failed to parse the request URL. But parse_url() has
an open bug of failing to parse URLs that contain the above pattern.
The function returns false in such cases, (it previously raised warning
see I2715607);

To make our titles with this pattern accessible, we have to forestall
this exception.

Bug: T256831
Change-Id: Ib829afc7b33419b01e69ababa147d33b30c0fbcb
2020-07-14 16:54:29 +00:00
addshore
959bc315f2 MediaWikiTestCase to MediaWikiIntegrationTestCase
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
2020-06-30 17:02:22 +01: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
Pablo Grass
ff40270448
WebRequest & RequestFromGlobals: get HTTP headers in one way
apache_request_headers() is a vendor-specific function - it got used
when present and alternative code paths were exercised otherwise.
These preserved certain "special" headers, e.g. Content-Type, only
inconsistently.

The function getallheaders() is an alias[1] for apache_request_headers()
on systems where the latter is present. Alternatively, there is a
polyfill (ralouphie/getallheaders) which is already installed in
mediawiki-vendor[2] (by virtue of guzzle).

Using getallheaders() exclusively, will make sure these "special"
headers are consistently available alongside their "regular"[3] peers
and helps MediaWiki code focus on its domain.

The dependency to ralouphie/getallheaders is made explicit in the same
version in which it is currently locked in mediawiki-vendor[4].

This surfaced because the deprecation warning for API POST requests
without a Content-Type header, introduced in bba1a0f, appeared in my
development system (somewhat dated addshore/mediawiki-docker-dev/) even
though the client did a fine job.

Interesting implementation detail: While WebRequest keeps track of
headers using keys in all upper case, REST RequestFromGlobals does so in
all lower case - but both use retrieval logic complementary to their
respective approach however. In case of REST RequestFromGlobals this is
encapsulated inside of HeaderContainer (setting and retrieving), while
WebRequest does all of this by itself. Cf. [5] and [6]

[1]: https://www.php.net/manual/en/function.getallheaders.php
[2]: https://github.com/wikimedia/mediawiki-vendor/tree/8f2967d/ralouphie/getallheaders
[3]: https://www.php.net/manual/en/reserved.variables.server.php#110763
[4]: https://github.com/wikimedia/mediawiki-vendor/blob/8f2967d/composer.lock#L3250
[5]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
[6]: https://www.php.net/manual/en/function.apache-request-headers.php#124236

Bug: T245535
Change-Id: Iba52f152e15928473b729a2588c2462e76e85634
2020-04-03 09:32:41 +02:00
daniel
65342f8353 Define POST handler for /page/: create page
NOTE: once this is merged, also merge Ie7b47e6868cc on the OAuth repo,
to fix unit tests after a breaking change to Router's constructor
signature.

Bug: T230842
Change-Id: I8f5b92918a58e44a4f2d8c78d234d9f64c2d06bf
2020-03-25 20:49:20 +01:00
Clara Andrew-Wani
adb087f618 Remove sample REST API handler
Bug: T237540
Change-Id: Ie0a6ecbf9af6e53ed65b92c3b4c7414ae6ae5441
2020-03-18 13:47:24 -04:00
Clara Andrew-Wani
8715fc5121 Add Content-Type to Headers
Change-Id: I197366ef6f490bb7676c21d99568e4ffd229673b
2020-02-14 14:22:03 -05:00
James D. Forrester
4f2d1efdda Coding style: Auto-fix MediaWiki.Classes.UnsortedUseStatements.UnsortedUse
Change-Id: I94a0ae83c65e8ee419bbd1ae1e86ab21ed4d8210
2020-01-10 09:32:25 -08:00
Petr Pchelko
0df763f71d Use UserIdentity instead of User in REST
Change-Id: Ia6a517c6a64664be2363492108f9497fc949f299
2019-09-18 14:45:01 +10:00
Tim Starling
8b1a6cc58a Use TextFormatter in the REST API
* Add ResponseFactory::createLocalizedHttpError(), which generates a
  JSON response body from a MessageValue
* ResponseFactory::__construct() accepts an array of TextFormatter
  objects. For ease of testing, the array may be empty. The integrated
  ResponseFactory has a TextFormatter for English, and one for
  $wgContLang if that is different.
* Use createLocalizedHttpError() to show helpful error messages for
  errors generated by Router.

Change-Id: I897a0aee42227916c568333ab384966f1b87f599
2019-09-17 16:03:14 +10:00
Brad Jorsch
ebfbd2d42a rest: Use ParamValidator library, add BodyValidator
Parameter validation is based on parameter definitions like those in the
Action API, using the new ParamValidator library. Handlers should use
the provided Handler methods to access parameters rather than fetching
them directly from the RequestInterface.

Body validation allows the handler to have the (non-form-data) body of a
request parsed and validated. The only validator included in this patch
ignores the body entirely; future patches may implement validation for
JSON bodies based on JSON schemas, or the like.

Bug: T223239
Change-Id: I3c37ea2b432840514b6bff90007c8403989225d5
2019-09-04 10:12:35 -04:00
Aryeh Gregor
7fb4a95563 Remove unneeded overrideMwServices/resetServices
Change-Id: If6cbdec05b8f310ef3a0b4649aaa16d9fb80a047
2019-08-29 14:26:18 +03:00
Tim Starling
86693df247 REST: call MediaWiki::preOutputCommit and doPostOutputShutdown
As in api.php. Among other things, this enables profiling.

Move EntryPoint test out of unit/ so that it passes.

Use ob_start()/ob_end_clean() instead of assuming an output buffer is
open, so that EntryPoint::execute() can be run from CLI mode.

Change-Id: I38162a9eac6fd5acfed2035b87cac4a97ffd50d6
2019-08-26 14:19:43 +10:00
Petr Pchelko
6dd64b7b9b Convert PermissionManager constructor to use ServiceOptions.
Change-Id: I36a3a2f338506ef14cc5d65b8bee2961a92d60da
2019-08-21 10:12:34 -07:00
Amir Sarabadani
06f645c453 Load GlobalFunctions.php to tests/phpunit/bootstrap.php
That mostly enables testing global functions

Bug: T87781
Change-Id: Ib42c56a67926ebcdba53f4c6c54a5bff98cb77a3
2019-07-14 01:28:07 +02:00
Tim Starling
f7ed8615e1 REST: add write access checks to BasicAccess
This is a stub implementation which just checks for the apiwrite
permission.

Change-Id: Ib84cd93e7f0f5e31cf620b2d30609035c4448c95
2019-07-09 15:23:57 +10:00
Tim Starling
94c0baaa2f REST: basic read restrictions
Protect private wikis by providing basic read restrictions,
closely following the example of the action API.

The BasicAccess module provides a narrow interface for this
functionality, without exposing the whole session/user concept to the
router.

Also, add RouterTest and fix a bug in Router::getRelativePath() thus
discovered.

Change-Id: I82319d56f08b2eec4a585ff6dbd348ccdbadc5b5
2019-07-09 15:23:20 +10:00
Amir Sarabadani
095f5583cb Move trivial unit tests, round II
Change-Id: I18e5a1514d7372b34f7fb460adf506a1ac65001f
2019-07-02 19:52:29 +02:00
Máté Szabó
344481f60d Move trivially compatible tests to the unit tests suite
This changeset resumes work on T89432 and related tickets
by porting an initial set of tests to the new unit test suite
separated out in I69b92db3e70093570e05cc0a64c7780a278b321a.
The tests were only ported if they worked immediately without
requiring any changes other than changing the test case class
to MediaWikiUnitTestCase and moving the test to the new suite.
If a test failed for any reason (even trivial misconfiguration),
it was NOT ported.

With this change, the unit tests suite now consits of a total
of 455 tests. As before, you can run these tests via the following
command:
$ composer phpunit:unit

Bug: T84948
Bug: T89432
Bug: T87781
Change-Id: Ibb8175981092d7f41864e641cc3c118af70a5c76
2019-06-30 15:23:53 +02:00
Gergő Tisza
19ad413d5d
ResponseFactory: support 302 redirects
Needed to match existing Parsoid behavior.

Also fixes redirect factory methods mistaking claiming to support
relative URLs. Most clients accept a relative URL in the Location
header, but the spec requires an absolute one, so better say that.

Change-Id: I03f5e776f7629eff6440698655277d8cd01e4a15
2019-06-26 11:42:31 +02:00
Tim Starling
4e0e36397c REST: Testable EntryPoint
* Split EntryPoint into a static main() and a non-static execute()
* Add tests for execute()

Change-Id: I025356b04ddc5a16494f98c446d785d6bb05ab10
2019-06-14 17:01:15 +10:00
Tim Starling
f1c11c2c49 REST: HeaderContainer should start empty not null
Change-Id: I30b68862307f2b44e4f5708c06464e0a218c1ed5
2019-06-14 17:01:15 +10:00
Tim Starling
b36002fbb1 StringStream and PathMatcher tests
Change-Id: Ic4c6e15ef9a107608fe8e72d469987ccce21f98f
2019-06-14 17:01:15 +10:00
Tim Starling
d0016a8b64 REST: tests for HelloHandler and HeaderContainer
Change-Id: Ia214d4ad85bb2041e49b6cfe8278775387c30138
2019-06-12 10:22:34 +10:00
Tim Starling
0ae06654d7 Expand ResponseFactory
* Factor out json_encode() call into ResponseFactory::encodeJson().
* Add createJson() and standardize on JSON for 4xx and 5xx responses
* Add methods for redirect generation, providing an HTML link in the
  body as recommended by RFC 7231

Most of the code was written by Gergő Tisza. The differences compared to
I747e34faecbcd are:

* Remove JsonResponse.
* Swap parameter order of createJson() reflecting the fact that the
  value is now usually provided.
* Remove unnecessary ResponseFactory::setStatus()
* Don't do ['code' => 'http500'] by default, use httpCode and httpReason
  to provide that information
* In createFromReturnValue(), don't wrap numerically-indexed arrays.
* Added tests.

Bug: T223240
Change-Id: Ie185b2bd43690633f1ccbe6328a0518e43a9f2f9
2019-06-12 10:22:34 +10:00