MediaWiki  master
Validator.php
Go to the documentation of this file.
1 <?php
2 
4 
12 use Wikimedia\ObjectFactory;
24 
32 class Validator {
33 
35  private const TYPE_DEFS = [
36  'boolean' => [ 'class' => BooleanDef::class ],
37  'enum' => [ 'class' => EnumDef::class ],
38  'integer' => [ 'class' => IntegerDef::class ],
39  'float' => [ 'class' => FloatDef::class ],
40  'double' => [ 'class' => FloatDef::class ],
41  'NULL' => [
42  'class' => StringDef::class,
43  'args' => [ [
44  'allowEmptyWhenRequired' => true,
45  ] ],
46  ],
47  'password' => [ 'class' => PasswordDef::class ],
48  'string' => [ 'class' => StringDef::class ],
49  'timestamp' => [ 'class' => TimestampDef::class ],
50  'upload' => [ 'class' => UploadDef::class ],
51  'expiry' => [ 'class' => ExpiryDef::class ],
52  'title' => [
53  'class' => TitleDef::class,
54  'services' => [ 'TitleFactory' ],
55  ],
56  'user' => [
57  'class' => UserDef::class,
58  'services' => [ 'UserIdentityLookup', 'TitleParser', 'UserNameUtils' ]
59  ],
60  ];
61 
63  private const NO_BODY_METHODS = [ 'GET', 'HEAD', 'DELETE' ];
64 
66  private const BODY_METHODS = [ 'POST', 'PUT' ];
67 
69  private const FORM_DATA_CONTENT_TYPES = [
70  'application/x-www-form-urlencoded',
71  'multipart/form-data',
72  ];
73 
75  private $paramValidator;
76 
83  public function __construct(
84  ObjectFactory $objectFactory,
85  RequestInterface $request,
86  Authority $authority
87  ) {
88  $this->paramValidator = new ParamValidator(
89  new ParamValidatorCallbacks( $request, $authority ),
90  $objectFactory,
91  [
92  'typeDefs' => self::TYPE_DEFS,
93  ]
94  );
95  }
96 
103  public function validateParams( array $paramSettings ) {
104  $validatedParams = [];
105  foreach ( $paramSettings as $name => $settings ) {
106  try {
107  $validatedParams[$name] = $this->paramValidator->getValue( $name, $settings, [
108  'source' => $settings[Handler::PARAM_SOURCE] ?? 'unspecified',
109  ] );
110  } catch ( ValidationException $e ) {
111  throw new LocalizedHttpException( $e->getFailureMessage(), 400, [
112  'error' => 'parameter-validation-failed',
113  'name' => $e->getParamName(),
114  'value' => $e->getParamValue(),
115  'failureCode' => $e->getFailureMessage()->getCode(),
116  'failureData' => $e->getFailureMessage()->getData(),
117  ] );
118  }
119  }
120  return $validatedParams;
121  }
122 
135  public function validateBody( RequestInterface $request, Handler $handler ) {
136  $method = strtoupper( trim( $request->getMethod() ) );
137 
138  // If the method should never have a body, don't bother validating.
139  if ( in_array( $method, self::NO_BODY_METHODS, true ) ) {
140  return null;
141  }
142 
143  // Get the content type
144  list( $ct ) = explode( ';', $request->getHeaderLine( 'Content-Type' ), 2 );
145  $ct = strtolower( trim( $ct ) );
146  if ( $ct === '' ) {
147  // No Content-Type was supplied. RFC 7231 ยง 3.1.1.5 allows this, but since it's probably a
148  // client error let's return a 415. But don't 415 for unknown methods and an empty body.
149  if ( !in_array( $method, self::BODY_METHODS, true ) ) {
150  $body = $request->getBody();
151  $size = $body->getSize();
152  if ( $size === null ) {
153  // No size available. Try reading 1 byte.
154  if ( $body->isSeekable() ) {
155  $body->rewind();
156  }
157  $size = $body->read( 1 ) === '' ? 0 : 1;
158  }
159  if ( $size === 0 ) {
160  return null;
161  }
162  }
163  throw new HttpException( "A Content-Type header must be supplied with a request payload.", 415, [
164  'error' => 'no-content-type',
165  ] );
166  }
167 
168  // Form data is parsed into $_POST and $_FILES by PHP and from there is accessed as parameters,
169  // don't bother trying to handle these via BodyValidator too.
170  if ( in_array( $ct, self::FORM_DATA_CONTENT_TYPES, true ) ) {
171  return null;
172  }
173 
174  // Validate the body. BodyValidator throws an HttpException on failure.
175  return $handler->getBodyValidator( $ct )->validateBody( $request );
176  }
177 
178 }
MediaWiki\Rest\Handler
Definition: AbstractContributionHandler.php:3
Wikimedia\ParamValidator\ValidationException
Error reporting for ParamValidator.
Definition: ValidationException.php:16
MediaWiki\Rest\Validator\Validator
Wrapper for ParamValidator.
Definition: Validator.php:32
MediaWiki\Rest\Handler\PARAM_SOURCE
const PARAM_SOURCE
(string) ParamValidator constant to specify the source of the parameter.
Definition: Handler.php:26
Wikimedia\ParamValidator\TypeDef\EnumDef
Type definition for enumeration types.
Definition: EnumDef.php:32
Wikimedia\ParamValidator\ValidationException\getParamName
getParamName()
Fetch the parameter name that failed validation.
Definition: ValidationException.php:71
MediaWiki\Rest\Handler
Base class for REST route handlers.
Definition: Handler.php:17
Wikimedia\ParamValidator\ParamValidator::TypeDef\UserDef
Type definition for user types.
Definition: UserDef.php:26
MediaWiki\Rest\Validator\ParamValidatorCallbacks
Definition: ParamValidatorCallbacks.php:12
MediaWiki\Rest\RequestInterface\getBody
getBody()
Gets the body of the message.
MediaWiki\Rest\Validator\Validator\__construct
__construct(ObjectFactory $objectFactory, RequestInterface $request, Authority $authority)
Definition: Validator.php:83
Wikimedia\ParamValidator\ValidationException\getParamValue
getParamValue()
Fetch the parameter value that failed validation.
Definition: ValidationException.php:79
Wikimedia\ParamValidator\TypeDef\ExpiryDef
Type definition for expiry timestamps.
Definition: ExpiryDef.php:17
Wikimedia\ParamValidator\ValidationException\getFailureMessage
getFailureMessage()
Fetch the validation failure message.
Definition: ValidationException.php:63
MediaWiki\Rest\Validator\Validator\validateParams
validateParams(array $paramSettings)
Validate parameters.
Definition: Validator.php:103
MediaWiki\Rest\RequestInterface\getMethod
getMethod()
Retrieves the HTTP method of the request.
Wikimedia\ParamValidator\TypeDef\FloatDef
Type definition for a floating-point type.
Definition: FloatDef.php:29
Wikimedia\ParamValidator\TypeDef\StringDef
Type definition for string types.
Definition: StringDef.php:24
Wikimedia\ParamValidator\TypeDef\BooleanDef
Type definition for boolean types.
Definition: BooleanDef.php:23
MediaWiki\Permissions\Authority
This interface represents the authority associated the current execution context, such as a web reque...
Definition: Authority.php:37
Wikimedia\ParamValidator\TypeDef\TimestampDef
Type definition for timestamp types.
Definition: TimestampDef.php:32
MediaWiki\Rest\RequestInterface
A request interface similar to PSR-7's ServerRequestInterface.
Definition: RequestInterface.php:39
MediaWiki\Rest\HttpException
This is the base exception class for non-fatal exceptions thrown from REST handlers.
Definition: HttpException.php:12
Wikimedia\ParamValidator\TypeDef\PasswordDef
Type definition for "password" types.
Definition: PasswordDef.php:16
MediaWiki\Rest\Validator\Validator\validateBody
validateBody(RequestInterface $request, Handler $handler)
Validate the body of a request.
Definition: Validator.php:135
Wikimedia\ParamValidator\TypeDef\IntegerDef
Type definition for integer types.
Definition: IntegerDef.php:23
Wikimedia\ParamValidator\ParamValidator::TypeDef\TitleDef
Type definition for page titles.
Definition: TitleDef.php:22
Wikimedia\ParamValidator\TypeDef\UploadDef
Type definition for upload types.
Definition: UploadDef.php:34
MediaWiki\Rest\Validator
Definition: BodyValidator.php:3
MediaWiki\Rest\RequestInterface\getHeaderLine
getHeaderLine( $name)
Retrieves a comma-separated string of the values for a single header.
MediaWiki\Rest\Validator\Validator\$paramValidator
ParamValidator $paramValidator
Definition: Validator.php:68
Wikimedia\ParamValidator\ParamValidator
Service for formatting and validating API parameters.
Definition: ParamValidator.php:42
MediaWiki\Rest\Handler\getBodyValidator
getBodyValidator( $contentType)
Fetch the BodyValidator.
Definition: Handler.php:271
MediaWiki\Rest\LocalizedHttpException
@newable
Definition: LocalizedHttpException.php:10