From d235c11ec74a7ee88a8990a1270400fda3f8c008 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Sun, 10 Mar 2024 14:03:53 +0100 Subject: [PATCH] Add automated parameter validation based on Valinor --- .../files/lib/action/ApiAction.class.php | 24 +++++++++++++++++++ ...ditorGetMentionSuggestionsAction.class.php | 20 +++++++++++++++- .../lib/system/endpoint/Parameters.class.php | 12 ++++++++++ .../messages/MentionSuggestions.class.php | 14 +++++------ 4 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 wcfsetup/install/files/lib/system/endpoint/Parameters.class.php diff --git a/wcfsetup/install/files/lib/action/ApiAction.class.php b/wcfsetup/install/files/lib/action/ApiAction.class.php index 6ed0d5f479..db18ca6986 100644 --- a/wcfsetup/install/files/lib/action/ApiAction.class.php +++ b/wcfsetup/install/files/lib/action/ApiAction.class.php @@ -6,6 +6,7 @@ use Laminas\Diactoros\Response\JsonResponse; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Server\RequestHandlerInterface; +use wcf\http\Helper; use wcf\system\endpoint\error\ControllerError; use wcf\system\endpoint\error\RouteParameterError; use wcf\system\endpoint\event\ControllerCollecting; @@ -13,6 +14,7 @@ use wcf\system\endpoint\exception\ControllerMalformed; use wcf\system\endpoint\exception\RouteParameterMismatch; use wcf\system\endpoint\GetRequest; use wcf\system\endpoint\IController; +use wcf\system\endpoint\Parameters; use wcf\system\endpoint\PostRequest; use wcf\system\endpoint\RequestType; use wcf\system\event\EventHandler; @@ -153,6 +155,28 @@ final class ApiAction implements RequestHandlerInterface return $request; } + // Support the mapping of parameters based on the request type. + $mappingAttribute = current($parameter->getAttributes(Parameters::class)); + if ($mappingAttribute !== false) { + if ($type->getName() === 'array') { + $classStringOrShape = $mappingAttribute->newInstance()->arrayShape; + } else { + $classStringOrShape = $type->getName(); + } + + if ($request->getMethod() === 'GET' || $request->getMethod() === 'DELETE') { + return Helper::mapQueryParameters( + $request->getQueryParams(), + $classStringOrShape, + ); + } else { + return Helper::mapRequestBody( + $request->getParsedBody(), + $classStringOrShape, + ); + } + } + throw new ControllerMalformed( ControllerError::ParameterTypeUnknown, $parameter, diff --git a/wcfsetup/install/files/lib/action/EditorGetMentionSuggestionsAction.class.php b/wcfsetup/install/files/lib/action/EditorGetMentionSuggestionsAction.class.php index 4cc3790b1b..ffdd20b6bc 100644 --- a/wcfsetup/install/files/lib/action/EditorGetMentionSuggestionsAction.class.php +++ b/wcfsetup/install/files/lib/action/EditorGetMentionSuggestionsAction.class.php @@ -5,7 +5,9 @@ namespace wcf\action; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; +use wcf\http\Helper; use wcf\system\endpoint\controller\core\messages\MentionSuggestions; +use wcf\system\endpoint\Parameters; /** * Suggests users that may be mentioned. @@ -20,6 +22,22 @@ final class EditorGetMentionSuggestionsAction implements RequestHandlerInterface { public function handle(ServerRequestInterface $request): ResponseInterface { - return (new MentionSuggestions())->mentionSuggestions($request); + $reflectionClass = new \ReflectionClass(MentionSuggestions::class); + $relfectionMethod = $reflectionClass->getMethod('mentionSuggestions'); + $parameters = $relfectionMethod->getParameters(); + + \assert(\count($parameters) === 1); + \assert($parameters[0]->getName() === 'parameters'); + + $attribute = current($parameters[0]->getAttributes(Parameters::class)); + + \assert($attribute !== false); + + $parameters = Helper::mapQueryParameters( + $request->getQueryParams(), + $attribute->newInstance()->arrayShape, + ); + + return (new MentionSuggestions())->mentionSuggestions($parameters); } } diff --git a/wcfsetup/install/files/lib/system/endpoint/Parameters.class.php b/wcfsetup/install/files/lib/system/endpoint/Parameters.class.php new file mode 100644 index 0000000000..4c508d6df9 --- /dev/null +++ b/wcfsetup/install/files/lib/system/endpoint/Parameters.class.php @@ -0,0 +1,12 @@ +getQueryParams(), + public function mentionSuggestions( + #[Parameters( <<<'EOT' array { query: non-empty-string } EOT, - ); - + )] + array $parameters + ): ResponseInterface { $query = \mb_strtolower($parameters['query']); $matches = []; -- 2.20.1