MediaWiki  master
Validator.php
Go to the documentation of this file.
1 <?php
2 
4 
21 
29 class Validator {
30 
32  private const TYPE_DEFS = [
33  'boolean' => [ 'class' => BooleanDef::class ],
34  'enum' => [ 'class' => EnumDef::class ],
35  'integer' => [ 'class' => IntegerDef::class ],
36  'float' => [ 'class' => FloatDef::class ],
37  'double' => [ 'class' => FloatDef::class ],
38  'NULL' => [
39  'class' => StringDef::class,
40  'args' => [ [
41  'allowEmptyWhenRequired' => true,
42  ] ],
43  ],
44  'password' => [ 'class' => PasswordDef::class ],
45  'string' => [ 'class' => StringDef::class ],
46  'timestamp' => [ 'class' => TimestampDef::class ],
47  'upload' => [ 'class' => UploadDef::class ],
48  ];
49 
51  private const NO_BODY_METHODS = [ 'GET', 'HEAD', 'DELETE' ];
52 
54  private const BODY_METHODS = [ 'POST', 'PUT' ];
55 
57  private const FORM_DATA_CONTENT_TYPES = [
58  'application/x-www-form-urlencoded',
59  'multipart/form-data',
60  ];
61 
63  private $paramValidator;
64 
72  public function __construct(
73  ObjectFactory $objectFactory,
74  PermissionManager $permissionManager,
75  RequestInterface $request,
76  UserIdentity $user
77  ) {
78  $this->paramValidator = new ParamValidator(
79  new ParamValidatorCallbacks( $permissionManager, $request, $user ),
80  $objectFactory,
81  [
82  'typeDefs' => self::TYPE_DEFS,
83  ]
84  );
85  }
86 
93  public function validateParams( array $paramSettings ) {
94  $validatedParams = [];
95  foreach ( $paramSettings as $name => $settings ) {
96  try {
97  $validatedParams[$name] = $this->paramValidator->getValue( $name, $settings, [
98  'source' => $settings[Handler::PARAM_SOURCE] ?? 'unspecified',
99  ] );
100  } catch ( ValidationException $e ) {
101  throw new HttpException( 'Parameter validation failed', 400, [
102  'error' => 'parameter-validation-failed',
103  'name' => $e->getParamName(),
104  'value' => $e->getParamValue(),
105  'failureCode' => $e->getFailureCode(),
106  'failureData' => $e->getFailureData(),
107  ] );
108  }
109  }
110  return $validatedParams;
111  }
112 
125  public function validateBody( RequestInterface $request, Handler $handler ) {
126  $method = strtoupper( trim( $request->getMethod() ) );
127 
128  // If the method should never have a body, don't bother validating.
129  if ( in_array( $method, self::NO_BODY_METHODS, true ) ) {
130  return null;
131  }
132 
133  // Get the content type
134  list( $ct ) = explode( ';', $request->getHeaderLine( 'Content-Type' ), 2 );
135  $ct = strtolower( trim( $ct ) );
136  if ( $ct === '' ) {
137  // No Content-Type was supplied. RFC 7231 ยง 3.1.1.5 allows this, but since it's probably a
138  // client error let's return a 415. But don't 415 for unknown methods and an empty body.
139  if ( !in_array( $method, self::BODY_METHODS, true ) ) {
140  $body = $request->getBody();
141  $size = $body->getSize();
142  if ( $size === null ) {
143  // No size available. Try reading 1 byte.
144  if ( $body->isSeekable() ) {
145  $body->rewind();
146  }
147  $size = $body->read( 1 ) === '' ? 0 : 1;
148  }
149  if ( $size === 0 ) {
150  return null;
151  }
152  }
153  throw new HttpException( "A Content-Type header must be supplied with a request payload.", 415, [
154  'error' => 'no-content-type',
155  ] );
156  }
157 
158  // Form data is parsed into $_POST and $_FILES by PHP and from there is accessed as parameters,
159  // don't bother trying to handle these via BodyValidator too.
160  if ( in_array( $ct, self::FORM_DATA_CONTENT_TYPES, true ) ) {
161  return null;
162  }
163 
164  // Validate the body. BodyValidator throws an HttpException on failure.
165  return $handler->getBodyValidator( $ct )->validateBody( $request );
166  }
167 
168 }
getBodyValidator( $contentType)
Fetch the BodyValidator.
Definition: Handler.php:159
validateBody(RequestInterface $request, Handler $handler)
Validate the body of a request.
Definition: Validator.php:125
getFailureCode()
Fetch the validation failure code.
This is the base exception class for non-fatal exceptions thrown from REST handlers.
const PARAM_SOURCE
(string) ParamValidator constant to specify the source of the parameter.
Definition: Handler.php:15
validateParams(array $paramSettings)
Validate parameters.
Definition: Validator.php:93
getMethod()
Retrieves the HTTP method of the request.
getBody()
Gets the body of the message.
Interface for objects representing user identity.
getParamValue()
Fetch the parameter value that failed validation.
__construct(ObjectFactory $objectFactory, PermissionManager $permissionManager, RequestInterface $request, UserIdentity $user)
Definition: Validator.php:72
getParamName()
Fetch the parameter name that failed validation.
A request interface similar to PSR-7&#39;s ServerRequestInterface.
Error reporting for ParamValidator.
Service for formatting and validating API parameters.
Wrapper for ParamValidator.
Definition: Validator.php:29
getHeaderLine( $name)
Retrieves a comma-separated string of the values for a single header.
getFailureData()
Fetch the validation failure data.
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...