Commit graph

85 commits

Author SHA1 Message Date
jenkins-bot
deba2439b7 Merge "REST: Allow specifying param descriptions as MessageValue objects" 2024-10-15 15:24:56 +00:00
bpirkle
08a2e410e6 REST: Allow specifying response body schemas in json files
Previously, response body schemas could be specified by handlers as
php associative arrays, that were included in the final OpenApi spec.
This mixed the schemas with code, and required developers to deal with
specs in multiple formats. Instead, allow specs to be specified in
JSON format, in separate files. In addition to keeping schemas in JSON,
this gives each schame its own git history.

Bug: T376290
Change-Id: Ic27f422df0ab12a3a0b1cbce79eb0be30f7b7815
2024-10-10 20:42:14 -05:00
bpirkle
27b5faf93b REST: Allow specifying param descriptions as MessageValue objects
Previously, parameter descriptions could only be specified as
strings. We want OpenAPI specs generated from parameter
definitions to be internationalizable, so allow specifying
descriptions as MessageValue objects, which can be translated
using normal MediaWiki mechanisms.

Associated improvements to ResponseFactory.

Bug: T376493
Change-Id: If1cbe4f7bfd5c375e64b802b666c0247d65b1ee0
2024-10-08 16:42:52 -05:00
James D. Forrester
91a37f53b4 Switch over a bunch of class_alias uses to actuals
Change-Id: Id175a83e71cc910eaee5d5890a9106872a3ca3b8
2024-10-03 17:09:36 +00:00
jenkins-bot
1b25d273f8 Merge "API: clarify the meaning of write access" 2024-08-20 16:53:21 +00:00
daniel
f26d068c33 API: clarify the meaning of write access
Improve docs for Handler::needsWriteAccess and ApiBase::isWriteMode()
by explaining the contract in terms of what is observable from the
client. Essentially, no write access is needed if the request is "safe"
in the sense defined by RFC 7231 section 4.2.1.

Change-Id: Ifab56a8d6bea3ad4c5282f30bb4eb8d8f5a719b9
2024-08-13 17:20:24 -07:00
Translation updater bot
e93d7f0705 Hard-deprecate getBodyValidator
This patch emits deprecation warnings when extensions override
Handler::getBodyValidator() or otherwise use JsonBodyValidator.
Request body validation should be performed based on body parameter
declarations returned from getBodyParamSettings().

Bug: T358560
Depends-On: I8b12c9c9d5a73c620e3c5d035f815d7c951c7b30
Change-Id: I44b3395b8d2489c5e7ec8de0077fd7a7c9f49bfe
2024-07-16 13:06:01 +00:00
jenkins-bot
d9f64a6287 Merge "REST: Generate request body specs from param settings." 2024-07-10 19:27:24 +00:00
daniel
e6d0adcc68 REST: Generate request body specs from param settings.
Bug: T323786
Change-Id: I49da2a07efa32759480070c9d93c31d46f211d26
2024-07-10 20:23:56 +02:00
Atieno
2b31f4c46f param-settings: Remove backward compatibility code from default
We no longer have to check for 'body' PARAM_SOURCE from within getParamSettings

Bug: T367394
Change-Id: I16075fde2db6ea47f61d1d2df1e07a4ef46b537b
2024-07-10 19:55:08 +03:00
Wendy Quarshie
5c61c65541 Normalise string params in MW Rest API
Bug: T340185
Change-Id: I1b7189d5951dea019897955f8f9749afcc325fe0
2024-07-08 17:20:14 +00:00
daniel
89be6e0c9f REST: detect mismatching value types in json request
DEPLOY: watch the api-warning channel for misbehaving clients.

We are now using TypeDef objects for validating fields in JSON
request bodies. Since TypeDef was designed for use in the action API, it
assumes that all client data is originally supplied as strings. These
strings are parsed and converted to the appropriate type.

But for JSON requests, we don't want that. If a field is defined to be a
boolean, it should be required to be a boolean, not the string "yes" or
"0".

This adds an option to TypeDefs that triggers strict type checks for
booleans and numbers. This option is enabled for all request types other
than form data.

For now, the check does not trigger a validation error. It just logs a
warning. This allows us to assess how often clients would trigger this
kind of error. The warning are logged to the "api-warning" channel.

Bug: T305973
Change-Id: I11e9e37af93bc3b9414eb77095e7cc0ce821a462
2024-06-28 11:10:07 +00:00
Jakob Warkotsch
33cfe4efeb REST: Allow other json request types
This changes parseBodyData() to treat request content types ending in
"+json" just like normal application/json requests in order to support
media types such as application/json-patch+json which is used by the
Wikibase REST API for patch endpoints.

Change-Id: Ic47f8f115ec403cab0a8fdd7d53edcd18d130537
2024-06-26 14:21:16 +02:00
daniel
41daf4d0d5 REST: Deprecate using "post" as the parameter source
Note that "post" parameters remain accessible through
getValidatedParams(), while "body" parameters have to be
accessed though getValidatedBody().

This adds a number of tests that ensure that this remains to be the case,
while deprecation warnings are triggered when appropriate.

Code search to check that this is unused in prod: https://codesearch.wmcloud.org/things/?q=SOURCE+*%3D%3E+*%27post%27&files=&excludeFiles=&repos=

Previous reverted incarnation of this: Ia0eedb383e69b

Bug: T362850
Bug: T358560
Depends-On: Id94335b3ec8f0549ff7350d31cb7cfee8feaa012
Change-Id: I88accc52c5faab70b453709b02ed88a8af4bc181
2024-06-25 14:57:58 +02:00
daniel
79c61e80dc REST: Make module definition files more like OpenAPI specs
This splits RouteFileModule into two classes, ExtraRoutesModule and
SpecBasedModule.

ExtraRoutesModule has no module prefix and supports
only "flat" route definition files and additional routes from
extension.json.

SpecBasedModule represents a single module defined in a definition
file similar to an OpenAPI spec. The idea is that a full OpenAPI spec
can be generated by filling in any missing information based on
information provided by the Handler implementation. In particular, the
definition of parameters and request body schemas will be generated.

A JSON schema for the new file format is added under docs/rest/.

Support for the intermediate format introduced in Iebcde4645d4 is
removed. It was not included in a release and was not being used outside
core tests.

Bug: T366837
Change-Id: I4ce306b0997f80b78a3d901e38bbfa8445bed604
2024-06-24 16:42:59 +02:00
bpirkle
1b416164e3 Adjust comments referring to Handler::init(), which no longer exists
Change-Id: Iec50e276275935d3d8d1b7156b482738dd215d5c
2024-05-22 16:04:09 -05:00
daniel
020c7f5e75 REST: introduce getSupportedRequestTypes()
REST handlers should explicitly list content types they support for
request bodies. This is needed for generating OpenAPI specs.

NOTE: this removes default support for form data requests, unless
there are "post" parameters declared. "body" parameters require JSON.

Bug: T362850
Change-Id: I1339b1a1770719bd4a5d4d414a8e55fcbb498ac1
2024-05-15 15:10:25 +02:00
Bartosz Dziewoński
d116ea0bce Tweak docs stating that time values can be booleans
I just don't see how that could be correct.

Change-Id: I193d2df26db401b33bcc9e6a82f3842ff5b8b56e
2024-05-11 23:51:25 +00:00
daniel
91a1741787 Introduce Modules into the REST framework
Modules group together endpoints by a shared prefix. The idea is that each module has its own version and can generated self-contained self-documentation. This allows clients to have clear expectations about the endpoints of each module, no matter what wiki they are accessing. So far, each wiki may be exposing a different set of endpoints, with no way to provide a spec that describes that set of endpoints in a way that would be consistent across wikis and stable over time.

Bug: T362480
Change-Id: Iebcde4645d472d27eee5a30adb6eee12cc7d046b
2024-05-08 16:12:30 +02:00
jenkins-bot
0f0d228ec3 Merge "REST: introduce getBodyParamSettings" 2024-05-07 18:23:34 +00:00
daniel
97eae33cf5 REST: introduce getBodyParamSettings
Since we introduced support for the "body" PARAM_SOURCE in
getParamSettings, fields in the request body can be defined in the same
way that path and query parameters are defined. However, body fields are
treated separately by the framework, and the value of body fields are
available through getValidatedBody(), rather than getValidatedParams().

Because of that, it makes sense to have a method that returns the param
settings just for the body fields. This also allows handler classes to
override this method separately to specify body fields. That way, it
also becomes possible to have body fields that have the same name as
other parameters.

Bug: T362850
Change-Id: Ia85bf7e46c949a999052d91f1b0d7d579a880108
2024-05-07 17:35:36 +00:00
Tim Starling
917f0a5996 Replace all instances of "per default" with "by default"
According to the dictionary, "per" (or more conventionally "as per")
means "according to". Refer OED "per" sense II.3.a. For example:

"No value was passed, so return null, as per default".

In this sentence, we are not specifying the default, we are referring
to the default. This correct usage of "per default" was used nowhere
in MediaWiki core as far as I can see.

Instead we have "per default" being used to mean "by default", that is,
giving the value to use when no explicit value was specified.

In OED, the phrase "by default" is blessed with its own section just
for computing usage:

"P.1.e. Computing. As an option or setting adopted automatically by a
computer program whenever an alternative is not specified by the user
or programmer. Cf. sense I.7a."

There are highly similar pre-computing usages of the same phrase,
whereas the phrase "per default" is not mentioned.

As a matter of style, I think "per default" should not be used even
when it is strictly correct, since the common incorrect usage makes it
ambiguous and misleading.

Change-Id: Ibcccc65ead864d082677b472b34ff32ff41c60ae
2024-04-29 10:47:54 +10:00
jenkins-bot
6182df7d1b Merge "Disallow optional or empty path parameters" 2024-04-25 10:00:05 +00:00
bpirkle
d2d1ada290 Comment typo fixes
After merging gerrit change 1023933, I realized I missed a couple
of comment typos in code review. Also noticed another in Validator.
So just fixing these up for general tidiness.

Change-Id: I7c40274482136ac78dc8ace5f8a0dffa67e4a9cb
2024-04-24 16:03:10 -05:00
daniel
c7ee85d4e9 REST: skip unused path params when generating OpenAPI specs
Path parameters cannot be optional in OpenAPI specs: each route has a
fixed set of parameters. But the same REST handler can be used for
multiple routes, with some routes using certain parameters, while others
don't.

So from the handler's perspective, these parameters are optional. That
works fine, until we try to generate an OpenAPI spec from the parameter
definitions that the handler returns from getParamSettings. At that
point, we need to inspect the route that the handler was instantiated
for, to see which parameters are actually used in the path. Any
parameters not used in the path need to be excluded from the generated
spec.

Bug: T359652
Change-Id: I81d2c919c87727614a29f53e1dea498326928ef4
2024-04-24 19:38:28 +00:00
bpirkle
1e4b86b183 Disallow optional or empty path parameters
Do not allow optional path parameters or empty path segments
within the path. Handlers may still consider a path parameter
to be non-required. Normally this is when a handler services
multiple routes, and not all routes supply all parameters.

Bug: T359652
Change-Id: I4f82ee2b6ec5b631249d26496688e5f42696c1d0
2024-04-24 14:27:06 -05:00
frankie
73a0a6830d Typo fixes
Two small typo fixes for dev environment and gerrit setup.

Bug: T362742
Change-Id: I92399002019a8df51731f8c927ca606f91211b51
2024-04-23 15:21:03 -04:00
jenkins-bot
f80ea795aa Merge "REST: Improve documentation of methods related to body parsing" 2024-04-05 18:04:31 +00:00
daniel
68e1fb24f6 REST: detect extraneous body fields
Throw if a client sends unexpected body fields to a handler that supports body validation.

Bug: T360434
Change-Id: I7b8ed5fe23613183f941ab3b162e0a3c488167df
2024-03-30 20:32:54 +00:00
daniel
52577732c4 REST: Improve documentation of methods related to body parsing
This adds contracts for the new methods added for handling body parsing.

Bug: T357025
Change-Id: I113454b6f81e3d51893f5b96889ddd4d67923141
2024-03-29 21:57:11 +00:00
jenkins-bot
f581b94913 Merge "REST: Wrap parameter validation errors for the request body" 2024-03-28 14:29:10 +00:00
jenkins-bot
9a24b39080 Merge "handler: Declare known sources in Validator" 2024-03-28 14:28:53 +00:00
Atieno
36c16d9c96 handler: Declare known sources in Validator
Bug: T358558
Change-Id: I0536e0d659b53c8f85bf7685beffbb5c5d027998
2024-03-28 16:42:59 +03:00
daniel
637ab1165e REST: Wrap parameter validation errors for the request body
Since we are now using the parameter validation mechanism also for
fields in the request body, we need to wrap the validation errors to
make clear that the "parameters" are actually fields on the request
body.

Bug: T358850
Change-Id: I02e59a66459e8d88d1c5d0e454da9139ec1b42c6
2024-03-28 08:38:29 +00:00
daniel
1986f2bfb0 REST: Accept POST with empty body and no content-type
All POST requests must have a body, even if the body's is
empty, with content-length set to 0. When the body is empty, it should
not be necessary to specify a content-type either.

A typical use case would be some kind of "touch" semantics that would
update a resource's state without needing any additional information
from the client.

Change-Id: I7d20bb6a8c484b9b4725f056342ff8d015a171ac
2024-03-14 14:56:05 +01:00
Wendy Quarshie
e8699c23d6 Rest: make getValidatedBody return body parameters
Bug: T358850
Change-Id: Icf11749dcddd11e6a9b68f3795923157a108c107
2024-03-13 14:09:46 +00:00
daniel
d38708dbfe Rest: allow Handlers to disable body parsing.
Handlers should be able to opt out of automatic parsing of JSON body
content. This is inportantr in two cases:

1) The handler wants to process the body as a stream
2) The handler wants to use a custon BodyValidator.

Bug: T357025
Bug: T359149
Change-Id: Iac1ad0b723cbad4c79c7119ab0dca8a08b19fe32
2024-03-05 13:30:55 +01:00
Wendy Quarshie
f4de463f88 Rest router should provide parsed body data to handler.
bug: T358557
Change-Id: I41e81f1166a09a4409319cced20a76dc08c6869e
2024-03-04 12:54:02 +00:00
Atieno
3087ecea75 handler: Throw on unsupported body
Bug: T358557
Change-Id: I62c429521cce24303fa91c3a2e47db77f912b967
2024-02-29 14:23:52 +03:00
Wendy Quarshie
026d8d02a2 RequestInterface: add getParsedBody and setParsedBody.
Adding getParsedBody is intended to make it easier for us to implement proper request body validation. Also, it get us closer to PSR-7.

Bug: T357025
Change-Id: Ib36d22f15f9226f1f088e55bb335d05dbb7a0e6a
2024-02-27 10:21:26 +00:00
jenkins-bot
04decb07b8 Merge "Rest: Fix unspecific type hints in REST handler/validators" 2024-02-16 19:32:45 +00:00
thiemowmde
baaf65938f Rest: Fix unspecific type hints in REST handler/validators
Change-Id: I1b002b4dbd4a8ca90aad977029dcc97e5b3fe766
2024-02-16 09:49:27 +01:00
Daniel Kinzler
b73cc87dd1 Re-apply "REST: Emit swagger spec"
This reverts commit 890558f1fa.
This restores Id584208d9b67d877606a0add1d71c9b1784cdb1b with some fixes.

Bug: T323786
Bug: T352742
Change-Id: Ib31c451ddd75b06c95a544c8a3d2a64b32264126
2023-12-06 11:20:11 +01:00
Urbanecm
890558f1fa Revert "REST: Emit swagger spec"
This reverts commit bb4b5c5f87.

Reason for revert: patch breaks CI

Bug: T352742
Change-Id: Iaf57bad945f5cbd01508a513f0d219ec4b510ce8
2023-12-05 10:37:48 +00:00
daniel
bb4b5c5f87 REST: Emit swagger spec
This is only enabled in development mode for now.
It's intended as a baseline for further development,
the feature is not ready for production.

Bug: T323786
Change-Id: Id584208d9b67d877606a0add1d71c9b1784cdb1b
Co-authored-by: Atieno <pnjira@wikimedia.org>
2023-12-04 16:28:32 +03:00
Tim Starling
5114267deb Rest: Allow private caching of requests with a session
Change-Id: I1ca1c8b3400510e8ca29b24002fddd8edf78e93c
2023-05-19 11:42:38 +10:00
Máté Szabó
3e910f1d5c Rest: Prevent caching responses for logged-in users
d70fbfc691 introduced a new helper
function to Rest handlers that prevent caching the response if it sets
any cookies. However, responses to requests where a cookie-based session
(anonymous user with session cookies or logged-in user) are not safe to
cache at all because the session manager may itself attempt to set
cookies on the response outside of the Rest framework, and the response
contents themselves may depend on user-specific invariants, such as the
user's permissions if the current wiki is private (i.e. restricts the
'read' permission to a subset of user groups). We currently rely on
HeaderCallback to fix the first case for us, and don't cover the second
case, so fix it by explicitly sending Cache-Control: private for Rest
responses for requests with an active cookie-based session.

Bug: T264631
Bug: T285210
Change-Id: I9dec6d4accd5de2bd1bde352d45f82c433913d54
2023-05-19 11:11:58 +10:00
Alexander Vorwerk
c62ac1bf56 Rest: Check for the correct header when setting cache-control
The response header is called 'Set-Cookie', not 'Cookie'.

Change-Id: Ifbf8755f73bcb68e95d26cb1500e3526db308186
2023-01-21 04:01:59 +01:00
Daniel Kinzler
f2e9d5108d REST: collect metrics on endpoint access
This is a modified version of Ie282bc5b5f5df0bbd6a40c8362ba73fcbbf36c2e
which was reverted in 5c7cca8776.

Bug: T321969
Change-Id: I566d54a473aa51c4cdaada21a49d63c0624aab93
2023-01-12 14:50:58 +00:00
Daniel Kinzler
5c7cca8776 Revert "REST: collect metrics on endpoint access"
This reverts commit d32c260ed0.

Reason for revert: Timo has reservations, I'll submit an updated version later.

Change-Id: I71d4d61a879fda4dccfc105127446cfedde75a7b
2022-12-12 20:05:06 +00:00