diff --git a/Makefile b/Makefile index b064e6c..768ae24 100755 --- a/Makefile +++ b/Makefile @@ -37,8 +37,6 @@ fix-style: php-cs-fixer.phar $(DOCKER_PHP) vendor/bin/indent --spaces .php_cs.dist $(DOCKER_PHP) ./php-cs-fixer.phar fix src/ --diff -cli: - docker-compose run --rm php bash install: composer.json package.json $(DOCKER_PHP) composer install --prefer-dist --no-interaction --no-progress --ansi diff --git a/src/spec/OpenApi.php b/src/spec/OpenApi.php index 4754eea..3214f81 100644 --- a/src/spec/OpenApi.php +++ b/src/spec/OpenApi.php @@ -27,9 +27,9 @@ */ class OpenApi extends SpecBaseObject { - const VERSION_3_0 = '3.0'; - const VERSION_3_1 = '3.1'; - const VERSION_UNSUPPORTED = 'unsupported'; + const VERSION_3_0 = "3.0"; + const VERSION_3_1 = "3.1"; + const VERSION_UNSUPPORTED = "unsupported"; /** * Pattern used to validate OpenAPI versions. @@ -42,15 +42,15 @@ class OpenApi extends SpecBaseObject protected function attributes(): array { return [ - 'openapi' => Type::STRING, - 'info' => Info::class, - 'servers' => [Server::class], - 'paths' => Paths::class, - 'webhooks' => [PathItem::class], - 'components' => Components::class, - 'security' => SecurityRequirements::class, - 'tags' => [Tag::class], - 'externalDocs' => ExternalDocumentation::class, + "openapi" => Type::STRING, + "info" => Info::class, + "servers" => [Server::class], + "paths" => Paths::class, + "webhooks" => [PathItem::class], + "components" => Components::class, + "security" => [SecurityRequirement::class], + "tags" => [Tag::class], + "externalDocs" => ExternalDocumentation::class, ]; } @@ -62,9 +62,7 @@ protected function attributeDefaults(): array return [ // Spec: If the servers property is not provided, or is an empty array, // the default value would be a Server Object with a url value of /. - 'servers' => [ - new Server(['url' => '/']) - ], + "servers" => [new Server(["url" => "/"])], ]; } @@ -73,8 +71,8 @@ public function __get($name) $ret = parent::__get($name); // Spec: If the servers property is not provided, or is an empty array, // the default value would be a Server Object with a url value of /. - if ($name === 'servers' && $ret === []) { - return $this->attributeDefaults()['servers']; + if ($name === "servers" && $ret === []) { + return $this->attributeDefaults()["servers"]; } return $ret; } @@ -85,13 +83,19 @@ public function __get($name) public function performValidation() { if ($this->getMajorVersion() === static::VERSION_3_0) { - $this->requireProperties(['openapi', 'info', 'paths']); + $this->requireProperties(["openapi", "info", "paths"]); } else { - $this->requireProperties(['openapi', 'info'], ['paths', 'webhooks', 'components']); + $this->requireProperties( + ["openapi", "info"], + ["paths", "webhooks", "components"], + ); } - if (!empty($this->openapi) && !preg_match(static::PATTERN_VERSION, $this->openapi)) { - $this->addError('Unsupported openapi version: ' . $this->openapi); + if ( + !empty($this->openapi) && + !preg_match(static::PATTERN_VERSION, $this->openapi) + ) { + $this->addError("Unsupported openapi version: " . $this->openapi); } } @@ -111,9 +115,9 @@ public function getMajorVersion() } if (preg_match(static::PATTERN_VERSION, $this->openapi, $matches)) { switch ($matches[1]) { - case '3.0': + case "3.0": return static::VERSION_3_0; - case '3.1': + case "3.1": return static::VERSION_3_1; } } diff --git a/src/spec/Operation.php b/src/spec/Operation.php index 8becca1..b052532 100644 --- a/src/spec/Operation.php +++ b/src/spec/Operation.php @@ -46,7 +46,7 @@ protected function attributes(): array 'responses' => Responses::class, 'callbacks' => [Type::STRING, Callback::class], 'deprecated' => Type::BOOLEAN, - 'security' => SecurityRequirements::class, + 'security' => [SecurityRequirement::class], 'servers' => [Server::class], ]; } diff --git a/src/spec/SecurityRequirement.php b/src/spec/SecurityRequirement.php index ec3e1d9..71f805c 100644 --- a/src/spec/SecurityRequirement.php +++ b/src/spec/SecurityRequirement.php @@ -10,20 +10,13 @@ use cebe\openapi\SpecBaseObject; /** - * A required security scheme to execute this operation. + * Lists the required security schemes to execute this operation. * * @link https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.2.md#securityRequirementObject * */ class SecurityRequirement extends SpecBaseObject { - private $_securityRequirement; - public function __construct(array $data) - { - parent::__construct($data); - $this->_securityRequirement = $data; - } - /** * @return array array of attributes available in this object. */ @@ -41,9 +34,4 @@ protected function attributes(): array protected function performValidation() { } - - public function getSerializableData() - { - return $this->_securityRequirement; - } } diff --git a/src/spec/SecurityRequirements.php b/src/spec/SecurityRequirements.php deleted file mode 100644 index cbda1ba..0000000 --- a/src/spec/SecurityRequirements.php +++ /dev/null @@ -1,78 +0,0 @@ - and contributors - * @license https://github.com/cebe/php-openapi/blob/master/LICENSE - */ - -namespace cebe\openapi\spec; - -use cebe\openapi\SpecBaseObject; - -/** - * Lists the required security schemes to execute this operation. - * - * @link https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.2.md#securityRequirementObject - * - */ -class SecurityRequirements extends SpecBaseObject -{ - private $_securityRequirements; - - public function __construct(array $data) - { - parent::__construct($data); - - foreach ($data as $index => $value) { - if (is_numeric($index)) { // read - $this->_securityRequirements[array_keys($value)[0]] = new SecurityRequirement(array_values($value)[0]); - } else { // write - $this->_securityRequirements[$index] = $value; - } - } - if ($data === []) { - $this->_securityRequirements = []; - } - } - - /** - * @return array array of attributes available in this object. - */ - protected function attributes(): array - { - // this object does not have a fixed set of attribute names - return []; - } - - /** - * Perform validation on this object, check data against OpenAPI Specification rules. - * - * Call `addError()` in case of validation errors. - */ - protected function performValidation() - { - } - - /** - * {@inheritDoc} - */ - public function getSerializableData() - { - $data = []; - foreach ($this->_securityRequirements ?? [] as $name => $securityRequirement) { - /** @var SecurityRequirement $securityRequirement */ - $data[] = [$name => $securityRequirement->getSerializableData()]; - } - return $data; - } - - public function getRequirement(string $name) - { - return $this->_securityRequirements[$name] ?? null; - } - - public function getRequirements() - { - return $this->_securityRequirements; - } -} diff --git a/tests/WriterTest.php b/tests/WriterTest.php index 355a744..fc415b5 100644 --- a/tests/WriterTest.php +++ b/tests/WriterTest.php @@ -1,13 +1,6 @@ createOpenAPI([ - 'security' => new SecurityRequirements([ - 'Bearer' => new SecurityRequirement([]) - ]), + 'security' => [new SecurityRequirement(['Bearer' => []])], ]); $json = \cebe\openapi\Writer::writeToJson($openapi); @@ -175,9 +166,7 @@ public function testWriteEmptySecurityPartJson() public function testWriteEmptySecurityPartYaml() { $openapi = $this->createOpenAPI([ - 'security' => new SecurityRequirements([ - 'Bearer' => new SecurityRequirement([]) - ]), + 'security' => [new SecurityRequirement(['Bearer' => []])], ]); $yaml = \cebe\openapi\Writer::writeToYaml($openapi); @@ -193,105 +182,6 @@ public function testWriteEmptySecurityPartYaml() - Bearer: [] -YAML - ), - $yaml - ); - } - - public function testSecurityAtPathOperationLevel() - { - $openapi = $this->createOpenAPI([ - 'components' => new Components([ - 'securitySchemes' => [ - 'BearerAuth' => new SecurityScheme([ - 'type' => 'http', - 'scheme' => 'bearer', - 'bearerFormat' => 'AuthToken and JWT Format' # optional, arbitrary value for documentation purposes - ]), - ], - ]), - 'paths' => [ - '/test' => new PathItem([ - 'get' => new Operation([ - 'security' => new SecurityRequirements([ - 'BearerAuth' => new SecurityRequirement([]), - ]), - 'responses' => new Responses([ - 200 => new Response(['description' => 'OK']), - ]) - ]) - ]) - ] - ]); - - $yaml = \cebe\openapi\Writer::writeToYaml($openapi); - - - $this->assertEquals(preg_replace('~\R~', "\n", <<createOpenAPI([ - 'components' => new Components([ - 'securitySchemes' => [ - 'BearerAuth' => new SecurityScheme([ - 'type' => 'http', - 'scheme' => 'bearer', - 'bearerFormat' => 'AuthToken and JWT Format' # optional, arbitrary value for documentation purposes - ]) - ], - ]), - 'security' => new SecurityRequirements([ - 'BearerAuth' => new SecurityRequirement([]) - ]), - 'paths' => [], - ]); - - $yaml = \cebe\openapi\Writer::writeToYaml($openapi); - - - $this->assertEquals(preg_replace('~\R~', "\n", <<assertInstanceOf(\cebe\openapi\spec\Components::class, $openapi->components); // security - $this->assertNull($openapi->security); # since it is not present in spec + $this->assertAllInstanceOf(\cebe\openapi\spec\SecurityRequirement::class, $openapi->security); // tags $this->assertAllInstanceOf(\cebe\openapi\spec\Tag::class, $openapi->tags); @@ -235,8 +235,7 @@ public function testSpecs($openApiFile) } // security - $openapi->security !== null && $this->assertInstanceOf(\cebe\openapi\spec\SecurityRequirements::class, $openapi->security); - $openapi->security !== null && $this->assertAllInstanceOf(\cebe\openapi\spec\SecurityRequirement::class, $openapi->security->getRequirements()); + $this->assertAllInstanceOf(\cebe\openapi\spec\SecurityRequirement::class, $openapi->security); // tags $this->assertAllInstanceOf(\cebe\openapi\spec\Tag::class, $openapi->tags); diff --git a/tests/spec/OperationTest.php b/tests/spec/OperationTest.php index 734db32..6e30566 100644 --- a/tests/spec/OperationTest.php +++ b/tests/spec/OperationTest.php @@ -79,11 +79,10 @@ public function testRead() $this->assertInstanceOf(\cebe\openapi\spec\Responses::class, $operation->responses); - $this->assertCount(1, $operation->security->getRequirements()); - $this->assertInstanceOf(\cebe\openapi\spec\SecurityRequirements::class, $operation->security); - $this->assertInstanceOf(\cebe\openapi\spec\SecurityRequirement::class, $operation->security->getRequirement('petstore_auth')); - $this->assertCount(2, $operation->security->getRequirement('petstore_auth')->getSerializableData()); - $this->assertEquals(['write:pets', 'read:pets'], $operation->security->getRequirement('petstore_auth')->getSerializableData()); + $this->assertCount(1, $operation->security); + $this->assertInstanceOf(\cebe\openapi\spec\SecurityRequirement::class, $operation->security[0]); + $this->assertCount(2, $operation->security[0]->petstore_auth); + $this->assertEquals(['write:pets', 'read:pets'], $operation->security[0]->petstore_auth); $this->assertInstanceOf(ExternalDocumentation::class, $operation->externalDocs); $this->assertEquals('Find more info here', $operation->externalDocs->description); diff --git a/tests/spec/SecuritySchemeTest.php b/tests/spec/SecuritySchemeTest.php index 4dc6a2a..5e14d5f 100644 --- a/tests/spec/SecuritySchemeTest.php +++ b/tests/spec/SecuritySchemeTest.php @@ -11,7 +11,6 @@ * @covers \cebe\openapi\spec\OAuthFlows * @covers \cebe\openapi\spec\OAuthFlow * @covers \cebe\openapi\spec\SecurityRequirement - * @covers \cebe\openapi\spec\SecurityRequirements */ class SecuritySchemeTest extends \PHPUnit\Framework\TestCase { @@ -200,10 +199,10 @@ public function testDefaultSecurity() YAML ); - $this->assertSame([], $openapi->paths->getPath('/path/one')->post->security->getRequirements()); + $this->assertSame([], $openapi->paths->getPath('/path/one')->post->security); $this->assertSame(null, $openapi->paths->getPath('/path/two')->post->security); - $this->assertCount(1, $openapi->security->getRequirements()); - $this->assertSame([], $openapi->security->getRequirement('Bearer')->getSerializableData()); + $this->assertCount(1, $openapi->security); + $this->assertSame([], $openapi->security[0]->Bearer); } }