diff --git a/composer.json b/composer.json index 1804c4c..0a6d7ed 100644 --- a/composer.json +++ b/composer.json @@ -11,10 +11,13 @@ "ext-pgsql": "*", "doctrine/doctrine-bundle": "^2.1", "guzzlehttp/guzzle": "^7.2", + "league/openapi-psr7-validator": "^0.13.0", + "nyholm/psr7": "^1.3", "symfony/console": "4.4.*", "symfony/dotenv": "4.4.*", "symfony/flex": "^1.3.1", "symfony/framework-bundle": "4.4.*", + "symfony/psr-http-message-bridge": "^2.0", "symfony/serializer": "4.4.*", "symfony/yaml": "4.4.*", "webmozart/assert": "^1.9" diff --git a/composer.lock b/composer.lock index 1d1f029..dc276b6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,133 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a68e0bb44d3b8d743a52061d73c9e53c", + "content-hash": "a3788c31a1db01c1afd47526734fcf2f", "packages": [ + { + "name": "cebe/php-openapi", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/cebe/php-openapi.git", + "reference": "672aea69aaeb0c8305ff64b6d6034d9eaadbebf4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cebe/php-openapi/zipball/672aea69aaeb0c8305ff64b6d6034d9eaadbebf4", + "reference": "672aea69aaeb0c8305ff64b6d6034d9eaadbebf4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "justinrainbow/json-schema": "^5.0", + "php": ">=7.1.0", + "symfony/yaml": "^3.0 | ^4.0 | ^5.0" + }, + "require-dev": { + "apis-guru/openapi-directory": "1.0.0", + "cebe/indent": "*", + "friendsofphp/php-cs-fixer": "~2.16.1", + "mermade/openapi3-examples": "1.0.0", + "nexmo/api-specification": "1.0.0", + "oai/openapi-specification": "3.0.2", + "phpstan/phpstan": "^0.12.0", + "phpunit/phpunit": "^6.5" + }, + "bin": [ + "bin/php-openapi" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "cebe\\openapi\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Carsten Brandt", + "email": "mail@cebe.cc", + "homepage": "https://cebe.cc/", + "role": "Creator" + } + ], + "description": "READ OpenAPI yaml files and make the content accessable in PHP objects.", + "homepage": "https://github.com/cebe/php-openapi#readme", + "keywords": [ + "openapi" + ], + "support": { + "issues": "https://github.com/cebe/php-openapi/issues", + "source": "https://github.com/cebe/php-openapi" + }, + "time": "2020-05-27T15:32:36+00:00" + }, + { + "name": "dflydev/fig-cookies", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-fig-cookies.git", + "reference": "733af78ddad60aec96f7c4a1204619dd4d62afff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-fig-cookies/zipball/733af78ddad60aec96f7c4a1204619dd4d62afff", + "reference": "733af78ddad60aec96f7c4a1204619dd4d62afff", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "php": "^7.2", + "psr/http-message": "^1" + }, + "require-dev": { + "doctrine/coding-standard": "^4", + "phpstan/phpstan": "^0.10.1", + "phpunit/phpunit": "^7.2.6", + "squizlabs/php_codesniffer": "^3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\FigCookies\\": "src/Dflydev/FigCookies" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Beau Simensen", + "email": "beau@dflydev.com" + } + ], + "description": "Cookies for PSR-7 HTTP Message Interface.", + "keywords": [ + "cookies", + "psr-7", + "psr7" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-fig-cookies/issues", + "source": "https://github.com/dflydev/dflydev-fig-cookies/tree/v2.0.1" + }, + "time": "2020-01-02T16:13:22+00:00" + }, { "name": "doctrine/annotations", "version": "1.10.4", @@ -1066,6 +1191,424 @@ ], "time": "2020-09-30T07:37:11+00:00" }, + { + "name": "justinrainbow/json-schema", + "version": "5.2.10", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "support": { + "issues": "https://github.com/justinrainbow/json-schema/issues", + "source": "https://github.com/justinrainbow/json-schema/tree/5.2.10" + }, + "time": "2020-05-27T16:41:55+00:00" + }, + { + "name": "league/openapi-psr7-validator", + "version": "0.13", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/openapi-psr7-validator.git", + "reference": "3a53f2d5755ced3b945e6e5cae02e329e760ecfc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/openapi-psr7-validator/zipball/3a53f2d5755ced3b945e6e5cae02e329e760ecfc", + "reference": "3a53f2d5755ced3b945e6e5cae02e329e760ecfc", + "shasum": "" + }, + "require": { + "cebe/php-openapi": "^1.3", + "dflydev/fig-cookies": "^2.0", + "ext-json": "*", + "league/uri": "^6.3", + "php": ">=7.2", + "psr/cache": "^1.0", + "psr/http-message": "^1.0", + "psr/http-server-middleware": "^1.0", + "respect/validation": "^1.1.3", + "riverline/multipart-parser": "^2.0.3", + "webmozart/assert": "^1.4" + }, + "require-dev": { + "cache/array-adapter": "^1.0", + "doctrine/coding-standard": "^6.0", + "guzzlehttp/psr7": "^1.5", + "phpunit/phpunit": "^7|^8" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\OpenAPIValidation\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Validate PSR-7 messages against OpenAPI (3.0.2) specifications expressed in YAML or JSON", + "homepage": "https://github.com/thephpleague/openapi-psr7-validator", + "keywords": [ + "http", + "openapi", + "psr7", + "validation" + ], + "support": { + "issues": "https://github.com/thephpleague/openapi-psr7-validator/issues", + "source": "https://github.com/thephpleague/openapi-psr7-validator/tree/0.13" + }, + "time": "2020-11-09T11:53:17+00:00" + }, + { + "name": "league/uri", + "version": "6.3.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "aa3babf16e9d7535544bd94e3def026ac56640f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/aa3babf16e9d7535544bd94e3def026ac56640f3", + "reference": "aa3babf16e9d7535544bd94e3def026ac56640f3", + "shasum": "" + }, + "require": { + "ext-json": "*", + "league/uri-interfaces": "^2.1", + "php": ">=7.2", + "psr/http-message": "^1.0" + }, + "conflict": { + "league/uri-schemes": "^1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^8.0" + }, + "suggest": { + "ext-fileinfo": "Needed to create Data URI from a filepath", + "ext-intl": "Needed to improve host validation", + "league/uri-components": "Needed to easily manipulate URI objects" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "URI manipulation library", + "homepage": "http://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "uri-template", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri/issues", + "source": "https://github.com/thephpleague/uri/tree/master" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2020-08-13T17:18:44+00:00" + }, + { + "name": "league/uri-interfaces", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "667f150e589d65d79c89ffe662e426704f84224f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/667f150e589d65d79c89ffe662e426704f84224f", + "reference": "667f150e589d65d79c89ffe662e426704f84224f", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common interface for URI representation", + "homepage": "http://github.com/thephpleague/uri-interfaces", + "keywords": [ + "rfc3986", + "rfc3987", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/thephpleague/uri-interfaces/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/2.2.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2020-10-31T13:45:51+00:00" + }, + { + "name": "nyholm/psr7", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "21b71a31eab5c0c2caf967b9c0fd97020254ed75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/21b71a31eab5c0c2caf967b9c0fd97020254ed75", + "reference": "21b71a31eab5c0c2caf967b9c0fd97020254ed75", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "php-http/message-factory": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "dev-master", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "http://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/Nyholm/psr7/issues", + "source": "https://github.com/Nyholm/psr7/tree/1.3.1" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2020-06-13T15:59:10+00:00" + }, + { + "name": "php-http/message-factory", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/message-factory.git", + "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message-factory/zipball/a478cb11f66a6ac48d8954216cfed9aa06a501a1", + "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Factory interfaces for PSR-7 HTTP Message", + "homepage": "http://php-http.org", + "keywords": [ + "factory", + "http", + "message", + "stream", + "uri" + ], + "support": { + "issues": "https://github.com/php-http/message-factory/issues", + "source": "https://github.com/php-http/message-factory/tree/master" + }, + "time": "2015-12-19T14:08:53+00:00" + }, { "name": "psr/cache", "version": "1.0.1", @@ -1210,6 +1753,61 @@ ], "time": "2020-06-29T06:28:15+00:00" }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, + "time": "2019-04-30T12:38:16+00:00" + }, { "name": "psr/http-message", "version": "1.0.1", @@ -1260,6 +1858,120 @@ ], "time": "2016-08-06T14:39:51+00:00" }, + { + "name": "psr/http-server-handler", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-handler.git", + "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7", + "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side request handler", + "keywords": [ + "handler", + "http", + "http-interop", + "psr", + "psr-15", + "psr-7", + "request", + "response", + "server" + ], + "support": { + "issues": "https://github.com/php-fig/http-server-handler/issues", + "source": "https://github.com/php-fig/http-server-handler/tree/master" + }, + "time": "2018-10-30T16:46:14+00:00" + }, + { + "name": "psr/http-server-middleware", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-middleware.git", + "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/2296f45510945530b9dceb8bcedb5cb84d40c5f5", + "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0", + "psr/http-server-handler": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side middleware", + "keywords": [ + "http", + "http-interop", + "middleware", + "psr", + "psr-15", + "psr-7", + "request", + "response" + ], + "support": { + "issues": "https://github.com/php-fig/http-server-middleware/issues", + "source": "https://github.com/php-fig/http-server-middleware/tree/master" + }, + "time": "2018-10-30T17:12:04+00:00" + }, { "name": "psr/log", "version": "1.1.3", @@ -1347,6 +2059,129 @@ "description": "A polyfill for getallheaders.", "time": "2019-03-08T08:55:37+00:00" }, + { + "name": "respect/validation", + "version": "1.1.31", + "source": { + "type": "git", + "url": "https://github.com/Respect/Validation.git", + "reference": "45d109fc830644fecc1145200d6351ce4f2769d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Respect/Validation/zipball/45d109fc830644fecc1145200d6351ce4f2769d0", + "reference": "45d109fc830644fecc1145200d6351ce4f2769d0", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "symfony/polyfill-mbstring": "^1.2" + }, + "require-dev": { + "egulias/email-validator": "~1.2 || ~2.1", + "mikey179/vfsstream": "^1.5", + "phpunit/phpunit": "~4.0 || ~5.0", + "symfony/validator": "~2.6.9", + "zendframework/zend-validator": "~2.3" + }, + "suggest": { + "egulias/email-validator": "Strict (RFC compliant) email validation", + "ext-bcmath": "Arbitrary Precision Mathematics", + "ext-mbstring": "Multibyte String Functions", + "friendsofphp/php-cs-fixer": "Fix PSR2 and other coding style issues", + "symfony/validator": "Use Symfony validator through Respect\\Validation", + "zendframework/zend-validator": "Use Zend Framework validator through Respect\\Validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Respect\\Validation\\": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Respect/Validation Contributors", + "homepage": "https://github.com/Respect/Validation/graphs/contributors" + } + ], + "description": "The most awesome validation engine ever created for PHP", + "homepage": "http://respect.github.io/Validation/", + "keywords": [ + "respect", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/Respect/Validation/issues", + "source": "https://github.com/Respect/Validation/tree/1.1.31" + }, + "time": "2019-05-28T06:10:06+00:00" + }, + { + "name": "riverline/multipart-parser", + "version": "2.0.8", + "source": { + "type": "git", + "url": "https://github.com/Riverline/multipart-parser.git", + "reference": "2fe9026789754c1ff07c06047f0acc113e90933a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Riverline/multipart-parser/zipball/2fe9026789754c1ff07c06047f0acc113e90933a", + "reference": "2fe9026789754c1ff07c06047f0acc113e90933a", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.6.0" + }, + "require-dev": { + "laminas/laminas-diactoros": "^1.8.7", + "phpunit/phpunit": "^5.2 || ^6.0 || ^7.0", + "psr/http-message": "^1.0", + "symfony/psr-http-message-bridge": "^1.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Riverline\\MultiPartParser\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Romain Cambien", + "email": "romain@cambien.net" + }, + { + "name": "Riverline", + "homepage": "http://www.riverline.fr" + } + ], + "description": "One class library to parse multipart content with encoding and charset support.", + "keywords": [ + "http", + "multipart", + "parser" + ], + "support": { + "issues": "https://github.com/Riverline/multipart-parser/issues", + "source": "https://github.com/Riverline/multipart-parser/tree/2.0.8" + }, + "time": "2020-01-24T09:39:24+00:00" + }, { "name": "symfony/cache", "version": "v4.4.15", @@ -3389,6 +4224,88 @@ ], "time": "2020-07-14T12:35:20+00:00" }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "51a21cb3ba3927d4b4bf8f25cc55763351af5f2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/51a21cb3ba3927d4b4bf8f25cc55763351af5f2e", + "reference": "51a21cb3ba3927d4b4bf8f25cc55763351af5f2e", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0", + "symfony/http-foundation": "^4.4 || ^5.0" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "symfony/phpunit-bridge": "^4.4 || ^5.0" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/symfony/psr-http-message-bridge/issues", + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.0.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-29T08:17:46+00:00" + }, { "name": "symfony/routing", "version": "v4.4.15", @@ -7262,5 +8179,5 @@ "platform-overrides": { "php": "7.4.3" }, - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.0.0" } diff --git a/config/packages/nyholm_psr7.yaml b/config/packages/nyholm_psr7.yaml new file mode 100644 index 0000000..f135723 --- /dev/null +++ b/config/packages/nyholm_psr7.yaml @@ -0,0 +1,21 @@ +services: + # Register nyholm/psr7 services for autowiring with PSR-17 (HTTP factories) + Psr\Http\Message\RequestFactoryInterface: '@nyholm.psr7.psr17_factory' + Psr\Http\Message\ResponseFactoryInterface: '@nyholm.psr7.psr17_factory' + Psr\Http\Message\ServerRequestFactoryInterface: '@nyholm.psr7.psr17_factory' + Psr\Http\Message\StreamFactoryInterface: '@nyholm.psr7.psr17_factory' + Psr\Http\Message\UploadedFileFactoryInterface: '@nyholm.psr7.psr17_factory' + Psr\Http\Message\UriFactoryInterface: '@nyholm.psr7.psr17_factory' + + # Register nyholm/psr7 services for autowiring with HTTPlug factories + Http\Message\MessageFactory: '@nyholm.psr7.httplug_factory' + Http\Message\RequestFactory: '@nyholm.psr7.httplug_factory' + Http\Message\ResponseFactory: '@nyholm.psr7.httplug_factory' + Http\Message\StreamFactory: '@nyholm.psr7.httplug_factory' + Http\Message\UriFactory: '@nyholm.psr7.httplug_factory' + + nyholm.psr7.psr17_factory: + class: Nyholm\Psr7\Factory\Psr17Factory + + nyholm.psr7.httplug_factory: + class: Nyholm\Psr7\Factory\HttplugFactory diff --git a/config/services.yaml b/config/services.yaml index 9757656..0e01b06 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -42,3 +42,17 @@ services: arguments: $client: '@guzzle.accuweather' $apiKey: '%env(ACCUWEATHER_API_KEY)%' + + Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface: + class: Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory + + League\OpenAPIValidation\PSR7\ValidatorBuilder: ~ + + openapi.validatorbuilder: + class: League\OpenAPIValidation\PSR7\ValidatorBuilder + factory: ['@League\OpenAPIValidation\PSR7\ValidatorBuilder', 'fromYamlFile'] + arguments: + - "%kernel.project_dir%/docs/openapi.yml" + + League\OpenAPIValidation\PSR7\RequestValidator: + factory: ['@openapi.validatorbuilder', 'getRequestValidator'] diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 1a016bf..82aa91f 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -48,8 +48,9 @@ public function currentTemperatureIs($temperature) */ public function iRegisterARunningSessionWith($id, $distance, $shoes) { + $server = ['CONTENT_TYPE' => 'application/json']; $body = RegisterRunningSessionDeserializerTest::createBody($id, $distance, $shoes); - $request = Request::create('/runningsessions/'.$id, 'PUT', [], [], [], [], $body); + $request = Request::create('/runningsessions/'.$id, 'PUT', [], [], [], $server, $body); $this->response = $this->kernel->handle($request); } diff --git a/src/Infrastructure/Symfony/Controller/OpenapiRequestValidator.php b/src/Infrastructure/Symfony/Controller/OpenapiRequestValidator.php new file mode 100644 index 0000000..ced3ac4 --- /dev/null +++ b/src/Infrastructure/Symfony/Controller/OpenapiRequestValidator.php @@ -0,0 +1,41 @@ +psr7Factory = $psr7Factory; + $this->requestValidator = $requestValidator; + } + + /** + * @throws BadRequestHttpException + */ + public function validateRequest(Request $symfonyRequest): void + { + $psr7Request = $this->psr7Factory->createRequest($symfonyRequest); + + try { + $this->requestValidator->validate($psr7Request); + } catch (ValidationFailed $e) { + //Real cause in previous + $e = $e->getPrevious() ?: $e; + throw new BadRequestHttpException($e->getMessage(), $e); + } + } +} diff --git a/src/Infrastructure/Symfony/Controller/RunningSessionController.php b/src/Infrastructure/Symfony/Controller/RunningSessionController.php index e71257b..e5674ce 100644 --- a/src/Infrastructure/Symfony/Controller/RunningSessionController.php +++ b/src/Infrastructure/Symfony/Controller/RunningSessionController.php @@ -16,15 +16,18 @@ class RunningSessionController extends AbstractController { + private OpenapiRequestValidator $requestValidator; private RegisterRunningSessionDeserializer $commandDeserializer; private RunningSessionSerializer $responseSerializer; private RegisterRunningSessionHandler $registerRunningSessionHandler; public function __construct( + OpenapiRequestValidator $requestValidator, RegisterRunningSessionDeserializer $commandDeserializer, RunningSessionSerializer $responseSerializer, RegisterRunningSessionHandler $registerRunningSessionHandler ) { + $this->requestValidator = $requestValidator; $this->commandDeserializer = $commandDeserializer; $this->responseSerializer = $responseSerializer; $this->registerRunningSessionHandler = $registerRunningSessionHandler; @@ -35,6 +38,8 @@ public function __construct( */ public function put(string $id, Request $request): Response { + $this->requestValidator->validateRequest($request); + $command = $this->commandDeserializer->deserialize($request->getContent()); Assert::same($command->getId(), (int) $id, 'id must be the same in payload and uri'); diff --git a/src/Infrastructure/Symfony/Serializer/RegisterRunningSessionDeserializer.php b/src/Infrastructure/Symfony/Serializer/RegisterRunningSessionDeserializer.php index 5150f62..4797e7b 100644 --- a/src/Infrastructure/Symfony/Serializer/RegisterRunningSessionDeserializer.php +++ b/src/Infrastructure/Symfony/Serializer/RegisterRunningSessionDeserializer.php @@ -10,7 +10,6 @@ class RegisterRunningSessionDeserializer { public function deserialize($content): RegisterRunningSession { - //@todo : validate data against json schema $data = json_decode($content, true, 512, JSON_THROW_ON_ERROR); return new RegisterRunningSession( diff --git a/symfony.lock b/symfony.lock index d6c772a..9d1f98d 100644 --- a/symfony.lock +++ b/symfony.lock @@ -23,12 +23,18 @@ "behat/transliterator": { "version": "v1.3.0" }, + "cebe/php-openapi": { + "version": "1.4.2" + }, "composer/semver": { "version": "1.7.1" }, "composer/xdebug-handler": { "version": "1.4.3" }, + "dflydev/fig-cookies": { + "version": "v2.0.1" + }, "doctrine/annotations": { "version": "1.0", "recipe": { @@ -104,6 +110,18 @@ "guzzlehttp/psr7": { "version": "1.7.0" }, + "justinrainbow/json-schema": { + "version": "5.2.10" + }, + "league/openapi-psr7-validator": { + "version": "0.13" + }, + "league/uri": { + "version": "6.3.0" + }, + "league/uri-interfaces": { + "version": "2.2.0" + }, "myclabs/deep-copy": { "version": "1.10.1" }, @@ -122,6 +140,18 @@ "nikic/php-parser": { "version": "v4.10.2" }, + "nyholm/psr7": { + "version": "1.0", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "1.0", + "ref": "7c0a9352a57376f04f5444e74565102c3a23d0c7" + }, + "files": [ + "config/packages/nyholm_psr7.yaml" + ] + }, "phar-io/manifest": { "version": "2.0.1" }, @@ -134,6 +164,9 @@ "php-cs-fixer/diff": { "version": "v1.3.1" }, + "php-http/message-factory": { + "version": "v1.0.2" + }, "phpdocumentor/reflection-common": { "version": "2.2.0" }, @@ -187,15 +220,30 @@ "psr/http-client": { "version": "1.0.1" }, + "psr/http-factory": { + "version": "1.0.1" + }, "psr/http-message": { "version": "1.0.1" }, + "psr/http-server-handler": { + "version": "1.0.1" + }, + "psr/http-server-middleware": { + "version": "1.0.1" + }, "psr/log": { "version": "1.1.3" }, "ralouphie/getallheaders": { "version": "3.0.3" }, + "respect/validation": { + "version": "1.1.31" + }, + "riverline/multipart-parser": { + "version": "2.0.8" + }, "sebastian/cli-parser": { "version": "1.0.1" }, @@ -377,6 +425,9 @@ "symfony/process": { "version": "v4.4.15" }, + "symfony/psr-http-message-bridge": { + "version": "v2.0.2" + }, "symfony/routing": { "version": "4.2", "recipe": { diff --git a/tests/Infrastructure/Symfony/Controller/RunningSessionControllerTest.php b/tests/Infrastructure/Symfony/Controller/RunningSessionControllerTest.php index 44e556e..4902bfe 100644 --- a/tests/Infrastructure/Symfony/Controller/RunningSessionControllerTest.php +++ b/tests/Infrastructure/Symfony/Controller/RunningSessionControllerTest.php @@ -37,8 +37,11 @@ public function testPutRouteSendsCommandToHandlerAndDisplayItsResult() $this->givenHandlerResponseIsARunningSession(); //When (Act) + $server = ['CONTENT_TYPE' => 'application/json']; $body = RegisterRunningSessionDeserializerTest::createBody(42); - $response = $this->whenISendThisRequest(Request::create('/runningsessions/42', 'PUT', [], [], [], [], $body)); + $response = $this->whenISendThisRequest( + Request::create('/runningsessions/42', 'PUT', [], [], [], $server, $body) + ); //Then (Assert) //less strict assertion (type only): see RegisterRunningSessionDeserializer for conversion from json to command object @@ -49,6 +52,21 @@ public function testPutRouteSendsCommandToHandlerAndDisplayItsResult() self::assertSame('application/json', $response->headers->get('Content-Type')); } + public function testPutRouteReturns400IfInvalidBody() + { + //When (Act) + $server = ['CONTENT_TYPE' => 'application/json']; + $body = '{"unexpected": "body"}'; + $response = $this->whenISendThisRequest( + Request::create('/runningsessions/42', 'PUT', [], [], [], $server, $body), + $letSymfonyConvertExceptions = true + ); + + //Then (Assert) + self::assertSame(400, $response->getStatusCode()); + self::assertSame('application/json', $response->headers->get('Content-Type')); + } + private function givenHandlerResponseIsARunningSession() { $this->registerRunningSessionHandler @@ -56,10 +74,10 @@ private function givenHandlerResponseIsARunningSession() ->willReturn(RunningSessionFactory::create()); } - private function whenISendThisRequest(Request $request): Response + private function whenISendThisRequest(Request $request, $letSymfonyConvertExceptions = false): Response { //$catch=false: prevents Symfony from catching exceptions - return self::$kernel->handle($request, HttpKernelInterface::MASTER_REQUEST, false); + return self::$kernel->handle($request, HttpKernelInterface::MASTER_REQUEST, $letSymfonyConvertExceptions); } private function thenARegisterRunningSessionCommandHasBeenSentToHandler()