Merge "Rest: Fix unspecific type hints in REST handler/validators"

This commit is contained in:
jenkins-bot 2024-02-16 19:32:45 +00:00 committed by Gerrit Code Review
commit 04decb07b8
10 changed files with 30 additions and 14 deletions

View file

@ -48,7 +48,7 @@ abstract class Handler {
/** @var array|null */ /** @var array|null */
private $validatedParams; private $validatedParams;
/** @var mixed */ /** @var mixed|null */
private $validatedBody; private $validatedBody;
/** @var ConditionalHeaderUtil */ /** @var ConditionalHeaderUtil */
@ -212,10 +212,8 @@ abstract class Handler {
* @throws HttpException On validation failure. * @throws HttpException On validation failure.
*/ */
public function validate( Validator $restValidator ) { public function validate( Validator $restValidator ) {
$validatedParams = $restValidator->validateParams( $this->getParamSettings() ); $this->validatedParams = $restValidator->validateParams( $this->getParamSettings() );
$validatedBody = $restValidator->validateBody( $this->request, $this ); $this->validatedBody = $restValidator->validateBody( $this->request, $this );
$this->validatedParams = $validatedParams;
$this->validatedBody = $validatedBody;
$this->postValidationSetup(); $this->postValidationSetup();
} }
@ -487,7 +485,9 @@ abstract class Handler {
* @stable to override * @stable to override
* *
* @param string $contentType Content type of the request. * @param string $contentType Content type of the request.
* @return BodyValidator * @return BodyValidator A {@see NullBodyValidator} in this default implementation
* @throws HttpException It's possible to fail early here when e.g. $contentType is unsupported,
* or later when {@see BodyValidator::validateBody} is called
*/ */
public function getBodyValidator( $contentType ) { public function getBodyValidator( $contentType ) {
// TODO: Create a JsonBodyValidator if getParamSettings() returns body params. // TODO: Create a JsonBodyValidator if getParamSettings() returns body params.
@ -511,7 +511,7 @@ abstract class Handler {
/** /**
* Fetch the validated body * Fetch the validated body
* @return mixed Value returned by the body validator, or null if validate() was * @return mixed|null Value returned by the body validator, or null if validate() was
* not called yet, validation failed, there was no body, or the body was form data. * not called yet, validation failed, there was no body, or the body was form data.
*/ */
public function getValidatedBody() { public function getValidatedBody() {

View file

@ -19,11 +19,14 @@ class CreationHandler extends EditHandler {
* @inheritDoc * @inheritDoc
*/ */
protected function getTitleParameter() { protected function getTitleParameter() {
return $this->getValidatedBody()['title']; $body = $this->getValidatedBody();
'@phan-var array $body';
return $body['title'];
} }
/** /**
* @inheritDoc * @inheritDoc
* @return JsonBodyValidator
*/ */
public function getBodyValidator( $contentType ) { public function getBodyValidator( $contentType ) {
if ( $contentType !== 'application/json' ) { if ( $contentType !== 'application/json' ) {
@ -66,6 +69,7 @@ class CreationHandler extends EditHandler {
*/ */
protected function getActionModuleParameters() { protected function getActionModuleParameters() {
$body = $this->getValidatedBody(); $body = $this->getValidatedBody();
'@phan-var array $body';
$title = $this->getTitleParameter(); $title = $this->getTitleParameter();

View file

@ -55,6 +55,7 @@ class UpdateHandler extends EditHandler {
/** /**
* @inheritDoc * @inheritDoc
* @return JsonBodyValidator
*/ */
public function getBodyValidator( $contentType ) { public function getBodyValidator( $contentType ) {
if ( $contentType !== 'application/json' ) { if ( $contentType !== 'application/json' ) {
@ -93,6 +94,7 @@ class UpdateHandler extends EditHandler {
*/ */
protected function getActionModuleParameters() { protected function getActionModuleParameters() {
$body = $this->getValidatedBody(); $body = $this->getValidatedBody();
'@phan-var array $body';
$title = $this->getTitleParameter(); $title = $this->getTitleParameter();
$baseRevId = $body['latest']['id'] ?? 0; $baseRevId = $body['latest']['id'] ?? 0;
@ -188,6 +190,7 @@ class UpdateHandler extends EditHandler {
*/ */
private function getConflictData() { private function getConflictData() {
$body = $this->getValidatedBody(); $body = $this->getValidatedBody();
'@phan-var array $body';
$baseRevId = $body['latest']['id'] ?? 0; $baseRevId = $body['latest']['id'] ?? 0;
$title = $this->titleParser->parseTitle( $this->getValidatedParams()['title'] ); $title = $this->titleParser->parseTitle( $this->getValidatedParams()['title'] );

View file

@ -536,6 +536,7 @@ class Router {
* *
* @param Handler $handler * @param Handler $handler
* @return ResponseInterface * @return ResponseInterface
* @throws HttpException
*/ */
private function executeHandler( $handler ): ResponseInterface { private function executeHandler( $handler ): ResponseInterface {
ProfilingContext::singleton()->init( MW_ENTRY_POINT, $handler->getPath() ); ProfilingContext::singleton()->init( MW_ENTRY_POINT, $handler->getPath() );

View file

@ -21,7 +21,7 @@ interface BodyValidator {
* available to the handler via Handler::getValidatedBody(). * available to the handler via Handler::getValidatedBody().
* *
* @param RequestInterface $request * @param RequestInterface $request
* @return mixed * @return mixed|null
* @throws HttpException on validation failure * @throws HttpException on validation failure
*/ */
public function validateBody( RequestInterface $request ); public function validateBody( RequestInterface $request );

View file

@ -27,6 +27,10 @@ class JsonBodyValidator implements BodyValidator {
$this->bodyParamSettings = $bodyParamSettings; $this->bodyParamSettings = $bodyParamSettings;
} }
/**
* @inheritDoc
* @return array
*/
public function validateBody( RequestInterface $request ) { public function validateBody( RequestInterface $request ) {
$jsonStream = $request->getBody(); $jsonStream = $request->getBody();
$status = FormatJson::parse( "$jsonStream", FormatJson::FORCE_ASSOC ); $status = FormatJson::parse( "$jsonStream", FormatJson::FORCE_ASSOC );

View file

@ -9,6 +9,10 @@ use MediaWiki\Rest\RequestInterface;
*/ */
class NullBodyValidator implements BodyValidator { class NullBodyValidator implements BodyValidator {
/**
* @inheritDoc
* @return null
*/
public function validateBody( RequestInterface $request ) { public function validateBody( RequestInterface $request ) {
return null; return null;
} }

View file

@ -146,8 +146,8 @@ class Validator {
* available to the handler via Handler::getValidatedBody(). * available to the handler via Handler::getValidatedBody().
* *
* @param RequestInterface $request * @param RequestInterface $request
* @param Handler $handler Used to call getBodyValidator() * @param Handler $handler Used to call {@see Handler::getBodyValidator}
* @return mixed May be null * @return mixed|null Return value from {@see BodyValidator::validateBody}
* @throws HttpException on validation failure * @throws HttpException on validation failure
*/ */
public function validateBody( RequestInterface $request, Handler $handler ) { public function validateBody( RequestInterface $request, Handler $handler ) {

View file

@ -233,14 +233,14 @@ class HandlerTest extends \MediaWikiUnitTestCase {
public function testGetValidatedBody() { public function testGetValidatedBody() {
$validator = $this->createMock( Validator::class ); $validator = $this->createMock( Validator::class );
$validator->method( 'validateBody' )->willReturn( 'VALIDATED BODY' ); $validator->method( 'validateBody' )->willReturn( [ 'VALIDATED BODY' ] );
$handler = $this->newHandler(); $handler = $this->newHandler();
$this->initHandler( $handler, new RequestData() ); $this->initHandler( $handler, new RequestData() );
$handler->validate( $validator ); $handler->validate( $validator );
$body = $handler->getValidatedBody(); $body = $handler->getValidatedBody();
$this->assertSame( 'VALIDATED BODY', $body ); $this->assertSame( [ 'VALIDATED BODY' ], $body );
} }
public function testGetRequest() { public function testGetRequest() {

View file

@ -60,7 +60,7 @@ class JsonBodyValidatorTest extends \MediaWikiUnitTestCase {
/** /**
* @dataProvider provideValidateBody * @dataProvider provideValidateBody
*/ */
public function testValidateBody( $settings, RequestData $requestData, $expected ) { public function testValidateBody( array $settings, RequestData $requestData, array $expected ) {
$validator = new JsonBodyValidator( $settings ); $validator = new JsonBodyValidator( $settings );
$actual = $validator->validateBody( $requestData ); $actual = $validator->validateBody( $requestData );
$this->assertArrayEquals( $expected, $actual, false, true ); $this->assertArrayEquals( $expected, $actual, false, true );