diff --git a/CHANGELOG.md b/CHANGELOG.md index acede3f..6ddd305 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles. ## [Unreleased][unreleased] +### Added +* Allowed endpoints filter for OpenApiHandler ## 3.0.0 diff --git a/src/Handlers/OpenApiHandler.php b/src/Handlers/OpenApiHandler.php index 7f372c4..908ad58 100644 --- a/src/Handlers/OpenApiHandler.php +++ b/src/Handlers/OpenApiHandler.php @@ -44,24 +44,30 @@ class OpenApiHandler extends BaseHandler private $definitions = []; + private $allowedEndpoints = []; + /** * OpenApiHandler constructor. * @param ApiDecider $apiDecider * @param ApiLink $apiLink * @param Request $request * @param array $initData - structured data for initialization response + * @param array $allowedEndpoints - list of endpoint (path and methods) which should be included in output, empty means all, wildcard * is supported for path + * Example: ['user/*' => ['get', 'post', 'delete'], 'user/list' => 'post', 'user/list' => [], 'user/list'] */ public function __construct( ApiDecider $apiDecider, ApiLink $apiLink, Request $request, - array $initData = [] + array $initData = [], + array $allowedEndpoints = [] ) { parent::__construct(); $this->apiDecider = $apiDecider; $this->apiLink = $apiLink; $this->request = $request; $this->initData = $initData; + $this->allowedEndpoints = $allowedEndpoints; } public function params(): array @@ -248,6 +254,10 @@ private function getPaths(array $versionApis, string $baseUrl, string $basePath) $handler = $api->getHandler(); $path = str_replace([$baseUrl, $basePath], '', $this->apiLink->link($api->getEndpoint())); $responses = []; + $endpointPath = str_replace('v' . $api->getEndpoint()->getVersion() . '/', '', $api->getEndpoint()->getUrl()); + if (!$this->isPathAllowed($endpointPath, $api->getEndpoint()->getMethod())) { + continue; + } $settings = [ 'summary' => $handler->summary(), @@ -270,7 +280,7 @@ private function getPaths(array $versionApis, string $baseUrl, string $basePath) 'schema' => [ '$ref' => '#/components/schemas/ErrorWrongInput', ], - ] + ], ], ]; } @@ -311,15 +321,15 @@ private function getPaths(array $versionApis, string $baseUrl, string $basePath) 'application/json; charset=utf-8' => [ 'schema' => $schema, ], - ] + ], ]; if (!empty($examples = $output->getExamples())) { if (count($examples) === 1) { - $example = is_array($output->getExample())? $output->getExample() : json_decode($output->getExample(), true); + $example = is_array($output->getExample()) ? $output->getExample() : json_decode($output->getExample(), true); $responses[$output->getCode()]['content']['application/json; charset=utf-8']['example'] = $example; } else { foreach ($examples as $exampleKey => $example) { - $example = is_array($example)? $example : json_decode($example, true); + $example = is_array($example) ? $example : json_decode($example, true); $responses[$output->getCode()]['content']['application/json; charset=utf-8']['examples'][$exampleKey] = $example; } } @@ -345,9 +355,9 @@ private function getPaths(array $versionApis, string $baseUrl, string $basePath) 'description' => $output->getDescription(), 'schema' => [ 'type' => 'string', - ] + ], ], - ] + ], ]; } } @@ -397,6 +407,39 @@ private function getPaths(array $versionApis, string $baseUrl, string $basePath) return $list; } + private function isPathAllowed($path, $method): bool + { + if (empty($this->allowedEndpoints)) { + return true; + } + + foreach ($this->allowedEndpoints as $allowedPath => $allowedMethods) { + if (is_int($allowedPath)) { // ['user/list'] format + $pattern = str_replace('*', '.*?', preg_quote(strtolower($allowedMethods))); + if (preg_match("#$pattern#", strtolower($path))) { + return true; + } + + continue; + } + + // ['user/*' => ['get', 'post'], 'user/list' => 'post', 'user/list' => [], 'user/list' => '*'] format + $pattern = str_replace('*', '.*?', preg_quote(strtolower($allowedPath))); + if (preg_match("#$pattern#", strtolower($path))) { + if (empty($allowedMethods)) { + return true; + } + if (is_string($allowedMethods) && strtolower($allowedMethods) === strtolower($method)) { + return true; + } + if (is_array($allowedMethods) && in_array(strtolower($method), array_map('strtolower', $allowedMethods), true)) { + return true; + } + } + } + return false; + } + private function getBasePath(array $apis, string $baseUrl): string { $basePath = ''; @@ -489,10 +532,10 @@ private function createRequestBody(ApiHandlerInterface $handler) $schema = json_decode($param->getSchema(), true); if (!empty($examples = $param->getExamples())) { if (count($examples) === 1) { - $schema['example'] = is_array($param->getExample())? $param->getExample() : json_decode($param->getExample(), true); + $schema['example'] = is_array($param->getExample()) ? $param->getExample() : json_decode($param->getExample(), true); } else { foreach ($examples as $exampleKey => $example) { - $schema['examples'][$exampleKey] = is_array($example)? $example : json_decode($example, true); + $schema['examples'][$exampleKey] = is_array($example) ? $example : json_decode($example, true); } } }