diff --git a/CHANGELOG.md b/CHANGELOG.md index b0b03f98dbe..98a0e72a8aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ * OpenAPI: Fix `Link->requestBody` default value (#4116) * GraphQL: Fix "Resource class cannot be determined." error when a null iterable field is returned (#4092) * Metadata: Check the output class when calculating serializer groups (#3696) +* OpenAPI: Using an implicit flow is now valid, changes oauth configuration default values (#4115) ## 2.6.2 diff --git a/src/Bridge/Symfony/Bundle/DependencyInjection/Configuration.php b/src/Bridge/Symfony/Bundle/DependencyInjection/Configuration.php index de9a01c80a8..fe9c361c4fb 100644 --- a/src/Bridge/Symfony/Bundle/DependencyInjection/Configuration.php +++ b/src/Bridge/Symfony/Bundle/DependencyInjection/Configuration.php @@ -253,9 +253,9 @@ private function addOAuthSection(ArrayNodeDefinition $rootNode): void ->scalarNode('clientSecret')->defaultValue('')->info('The oauth client secret.')->end() ->scalarNode('type')->defaultValue('oauth2')->info('The oauth client secret.')->end() ->scalarNode('flow')->defaultValue('application')->info('The oauth flow grant type.')->end() - ->scalarNode('tokenUrl')->defaultValue('/oauth/v2/token')->info('The oauth token url.')->end() - ->scalarNode('authorizationUrl')->defaultValue('/oauth/v2/auth')->info('The oauth authentication url.')->end() - ->scalarNode('refreshUrl')->defaultValue('/oauth/v2/refresh')->info('The oauth refresh url.')->end() + ->scalarNode('tokenUrl')->defaultValue('')->info('The oauth token url.')->end() + ->scalarNode('authorizationUrl')->defaultValue('')->info('The oauth authentication url.')->end() + ->scalarNode('refreshUrl')->defaultValue('')->info('The oauth refresh url.')->end() ->arrayNode('scopes') ->prototype('scalar')->end() ->end() diff --git a/src/OpenApi/Options.php b/src/OpenApi/Options.php index 043c16f1b47..d4a995123af 100644 --- a/src/OpenApi/Options.php +++ b/src/OpenApi/Options.php @@ -33,7 +33,7 @@ final class Options private $licenseName; private $licenseUrl; - public function __construct(string $title, string $description = '', string $version = '', bool $oAuthEnabled = false, string $oAuthType = '', string $oAuthFlow = '', string $oAuthTokenUrl = '', string $oAuthAuthorizationUrl = '', string $oAuthRefreshUrl = '', array $oAuthScopes = [], array $apiKeys = [], string $contactName = null, string $contactUrl = null, string $contactEmail = null, string $termsOfService = null, string $licenseName = null, string $licenseUrl = null) + public function __construct(string $title, string $description = '', string $version = '', bool $oAuthEnabled = false, ?string $oAuthType = null, ?string $oAuthFlow = null, ?string $oAuthTokenUrl = null, ?string $oAuthAuthorizationUrl = null, ?string $oAuthRefreshUrl = null, array $oAuthScopes = [], array $apiKeys = [], string $contactName = null, string $contactUrl = null, string $contactEmail = null, string $termsOfService = null, string $licenseName = null, string $licenseUrl = null) { $this->title = $title; $this->description = $description; @@ -41,9 +41,9 @@ public function __construct(string $title, string $description = '', string $ver $this->oAuthEnabled = $oAuthEnabled; $this->oAuthType = $oAuthType; $this->oAuthFlow = $oAuthFlow; - $this->oAuthTokenUrl = $oAuthTokenUrl; - $this->oAuthAuthorizationUrl = $oAuthAuthorizationUrl; - $this->oAuthRefreshUrl = $oAuthRefreshUrl; + $this->oAuthTokenUrl = $oAuthTokenUrl ?: null; + $this->oAuthAuthorizationUrl = $oAuthAuthorizationUrl ?: null; + $this->oAuthRefreshUrl = $oAuthRefreshUrl ?: null; $this->oAuthScopes = $oAuthScopes; $this->apiKeys = $apiKeys; $this->contactName = $contactName; @@ -74,27 +74,27 @@ public function getOAuthEnabled(): bool return $this->oAuthEnabled; } - public function getOAuthType(): string + public function getOAuthType(): ?string { return $this->oAuthType; } - public function getOAuthFlow(): string + public function getOAuthFlow(): ?string { return $this->oAuthFlow; } - public function getOAuthTokenUrl(): string + public function getOAuthTokenUrl(): ?string { return $this->oAuthTokenUrl; } - public function getOAuthAuthorizationUrl(): string + public function getOAuthAuthorizationUrl(): ?string { return $this->oAuthAuthorizationUrl; } - public function getOAuthRefreshUrl(): string + public function getOAuthRefreshUrl(): ?string { return $this->oAuthRefreshUrl; } diff --git a/src/Swagger/Serializer/DocumentationNormalizer.php b/src/Swagger/Serializer/DocumentationNormalizer.php index e405251228d..9ce098bec77 100644 --- a/src/Swagger/Serializer/DocumentationNormalizer.php +++ b/src/Swagger/Serializer/DocumentationNormalizer.php @@ -675,11 +675,14 @@ private function computeDoc(bool $v3, Documentation $documentation, \ArrayObject if ($this->oauthEnabled) { $oauthAttributes = [ - 'tokenUrl' => $this->oauthTokenUrl, 'authorizationUrl' => $this->oauthAuthorizationUrl, - 'scopes' => $this->oauthScopes, + 'scopes' => new \ArrayObject($this->oauthScopes), ]; + if ($this->oauthTokenUrl) { + $oauthAttributes['tokenUrl'] = $this->oauthTokenUrl; + } + $securityDefinitions['oauth'] = [ 'type' => $this->oauthType, 'description' => sprintf( diff --git a/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php b/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php index 38f379dd726..bae66a199eb 100644 --- a/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php +++ b/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php @@ -1144,9 +1144,9 @@ private function getBaseContainerBuilderProphecy(array $doctrineIntegrationsToLo 'api_platform.oauth.clientSecret' => '', 'api_platform.oauth.type' => 'oauth2', 'api_platform.oauth.flow' => 'application', - 'api_platform.oauth.tokenUrl' => '/oauth/v2/token', - 'api_platform.oauth.authorizationUrl' => '/oauth/v2/auth', - 'api_platform.oauth.refreshUrl' => '/oauth/v2/refresh', + 'api_platform.oauth.tokenUrl' => '', + 'api_platform.oauth.authorizationUrl' => '', + 'api_platform.oauth.refreshUrl' => '', 'api_platform.oauth.scopes' => [], 'api_platform.enable_swagger_ui' => true, 'api_platform.enable_re_doc' => true, diff --git a/tests/Bridge/Symfony/Bundle/DependencyInjection/ConfigurationTest.php b/tests/Bridge/Symfony/Bundle/DependencyInjection/ConfigurationTest.php index 1df2208bb80..3133bca92e1 100644 --- a/tests/Bridge/Symfony/Bundle/DependencyInjection/ConfigurationTest.php +++ b/tests/Bridge/Symfony/Bundle/DependencyInjection/ConfigurationTest.php @@ -142,9 +142,9 @@ private function runDefaultConfigTests(array $doctrineIntegrationsToLoad = ['orm 'clientSecret' => '', 'type' => 'oauth2', 'flow' => 'application', - 'tokenUrl' => '/oauth/v2/token', - 'authorizationUrl' => '/oauth/v2/auth', - 'refreshUrl' => '/oauth/v2/refresh', + 'tokenUrl' => '', + 'authorizationUrl' => '', + 'refreshUrl' => '', 'scopes' => [], ], 'swagger' => [ diff --git a/tests/Fixtures/app/config/config_common.yml b/tests/Fixtures/app/config/config_common.yml index 69db4cfb002..0f9d4d27e07 100644 --- a/tests/Fixtures/app/config/config_common.yml +++ b/tests/Fixtures/app/config/config_common.yml @@ -47,6 +47,13 @@ api_platform: collection: order_parameter_name: 'order' order: 'ASC' + oauth: + enabled: true + clientId: my_client + type: 'oauth2' + flow: 'implicit' + authorizationUrl: 'http://my-custom-server/openid-connect/auth' + scopes: [] exception_to_status: Symfony\Component\Serializer\Exception\ExceptionInterface: !php/const Symfony\Component\HttpFoundation\Response::HTTP_BAD_REQUEST ApiPlatform\Core\Exception\InvalidArgumentException: !php/const Symfony\Component\HttpFoundation\Response::HTTP_BAD_REQUEST diff --git a/tests/Swagger/Serializer/DocumentationNormalizerV2Test.php b/tests/Swagger/Serializer/DocumentationNormalizerV2Test.php index 6afe6864eed..318f10774a8 100644 --- a/tests/Swagger/Serializer/DocumentationNormalizerV2Test.php +++ b/tests/Swagger/Serializer/DocumentationNormalizerV2Test.php @@ -529,7 +529,7 @@ private function doTestNormalizeWithNameConverter(bool $legacy = false): void 'flow' => 'application', 'tokenUrl' => '/oauth/v2/token', 'authorizationUrl' => '/oauth/v2/auth', - 'scopes' => ['scope param'], + 'scopes' => new \ArrayObject(['scope param']), ], ], 'security' => [['oauth' => []]], diff --git a/tests/Swagger/Serializer/DocumentationNormalizerV3Test.php b/tests/Swagger/Serializer/DocumentationNormalizerV3Test.php index 3ea56e07583..24d1b7cc241 100644 --- a/tests/Swagger/Serializer/DocumentationNormalizerV3Test.php +++ b/tests/Swagger/Serializer/DocumentationNormalizerV3Test.php @@ -583,7 +583,7 @@ private function doTestNormalizeWithNameConverter(bool $legacy = false): void 'authorizationCode' => [ 'tokenUrl' => '/oauth/v2/token', 'authorizationUrl' => '/oauth/v2/auth', - 'scopes' => ['scope param'], + 'scopes' => new \ArrayObject(['scope param']), ], ], ],