From 64b1d3b7f0a1d12ac6d66932e7f41b5bd29a621b Mon Sep 17 00:00:00 2001 From: Kamil Kokot Date: Tue, 21 Jan 2020 22:10:15 +0100 Subject: [PATCH] Filter serialization groups by default ones and allowed ones --- UPGRADE.md | 7 ++ .../RequestConfigurationFactory.php | 11 +- .../RequestConfigurationFactorySpec.php | 114 ++++++++++++++++-- 3 files changed, 121 insertions(+), 11 deletions(-) create mode 100644 UPGRADE.md diff --git a/UPGRADE.md b/UPGRADE.md new file mode 100644 index 000000000..d5f2e5b71 --- /dev/null +++ b/UPGRADE.md @@ -0,0 +1,7 @@ +## UPGRADE FOR `1.3.x` + +### FROM `1.3.x` TO `1.3.13` + +If you're using an "Accept" HTTP header to set the serialization groups, you need to define allowed groups +either by passing them as default in `serialization_groups` setting or marking them as allowed in +`allowed_serialization_groups` setting, both settings are set in the route definition (under `_sylius` key). diff --git a/src/Bundle/Controller/RequestConfigurationFactory.php b/src/Bundle/Controller/RequestConfigurationFactory.php index 5bc4b087c..fe5642694 100644 --- a/src/Bundle/Controller/RequestConfigurationFactory.php +++ b/src/Bundle/Controller/RequestConfigurationFactory.php @@ -56,7 +56,7 @@ public function create(MetadataInterface $metadata, Request $request): RequestCo */ private function parseApiParameters(Request $request): array { - $parameters = []; + $parameters = $request->attributes->get('_sylius', []); /** @var string[] $apiVersionHeaders */ $apiVersionHeaders = $request->headers->get(self::API_VERSION_HEADER, null, false); @@ -66,14 +66,19 @@ private function parseApiParameters(Request $request): array } } + $allowedSerializationGroups = array_merge( + $parameters['allowed_serialization_groups'] ?? [], + $parameters['serialization_groups'] ?? [] + ); + /** @var string[] $apiGroupsHeaders */ $apiGroupsHeaders = $request->headers->get(self::API_GROUPS_HEADER, null, false); foreach ($apiGroupsHeaders as $apiGroupsHeader) { if (preg_match(self::API_GROUPS_REGEXP, $apiGroupsHeader, $matches)) { - $parameters['serialization_groups'] = array_map('trim', explode(',', $matches['groups'])); + $parameters['serialization_groups'] = array_intersect($allowedSerializationGroups, array_map('trim', explode(',', $matches['groups']))); } } - return array_merge($request->attributes->get('_sylius', []), $parameters); + return $parameters; } } diff --git a/src/Bundle/spec/Controller/RequestConfigurationFactorySpec.php b/src/Bundle/spec/Controller/RequestConfigurationFactorySpec.php index 1e49918c0..4eba46002 100644 --- a/src/Bundle/spec/Controller/RequestConfigurationFactorySpec.php +++ b/src/Bundle/spec/Controller/RequestConfigurationFactorySpec.php @@ -85,15 +85,23 @@ function it_creates_configuration_for_serialization_group_from_single_header( $request->headers = $headersBag; $request->attributes = $attributesBag; + $attributesBag->get('_sylius', [])->willReturn([ + 'allowed_serialization_groups' => ['Default', 'Detailed', 'Other'], + ]); $headersBag->get('Accept', null, false)->willReturn(['groups=Default,Detailed']); - $attributesBag->get('_sylius', [])->willReturn([]); $parametersParser - ->parseRequestValues(['serialization_groups' => ['Default', 'Detailed']], $request) - ->willReturn(['template' => ':Product:list.html.twig']) + ->parseRequestValues( + [ + 'allowed_serialization_groups' => ['Default', 'Detailed', 'Other'], + 'serialization_groups' => ['Default', 'Detailed'], + ], + $request + ) + ->willReturn(['serialization_groups' => ['Default', 'Detailed']]) ; - $this->create($metadata, $request)->isSortable()->shouldReturn(false); + $this->create($metadata, $request)->getSerializationGroups()->shouldReturn(['Default', 'Detailed']); } function it_creates_configuration_for_serialization_group_from_multiple_headers( @@ -106,15 +114,105 @@ function it_creates_configuration_for_serialization_group_from_multiple_headers( $request->headers = $headersBag; $request->attributes = $attributesBag; + $attributesBag->get('_sylius', [])->willReturn([ + 'allowed_serialization_groups' => ['Default', 'Detailed', 'Other'], + ]); $headersBag->get('Accept', null, false)->willReturn(['application/json', 'groups=Default,Detailed']); - $attributesBag->get('_sylius', [])->willReturn([]); $parametersParser - ->parseRequestValues(['serialization_groups' => ['Default', 'Detailed']], $request) - ->willReturn(['template' => ':Product:list.html.twig']) + ->parseRequestValues( + [ + 'allowed_serialization_groups' => ['Default', 'Detailed', 'Other'], + 'serialization_groups' => ['Default', 'Detailed'], + ], + $request + ) + ->willReturn(['serialization_groups' => ['Default', 'Detailed']]) ; - $this->create($metadata, $request)->isSortable()->shouldReturn(false); + $this->create($metadata, $request)->getSerializationGroups()->shouldReturn(['Default', 'Detailed']); + } + + function it_creates_configuration_using_only_those_serialization_groups_that_are_allowed( + ParametersParserInterface $parametersParser, + MetadataInterface $metadata, + Request $request, + ParameterBag $headersBag, + ParameterBag $attributesBag + ): void { + $request->headers = $headersBag; + $request->attributes = $attributesBag; + + $attributesBag->get('_sylius', [])->willReturn([ + 'allowed_serialization_groups' => ['Default'], + ]); + $headersBag->get('Accept', null, false)->willReturn(['application/json', 'groups=Default,Detailed']); + + $parametersParser + ->parseRequestValues( + [ + 'allowed_serialization_groups' => ['Default'], + 'serialization_groups' => ['Default'], + ], + $request + ) + ->willReturn(['serialization_groups' => ['Default']]) + ; + + $this->create($metadata, $request)->getSerializationGroups()->shouldReturn(['Default']); + } + + function it_creates_configuration_using_only_those_serialization_groups_that_are_allowed_or_defined_as_default( + ParametersParserInterface $parametersParser, + MetadataInterface $metadata, + Request $request, + ParameterBag $headersBag, + ParameterBag $attributesBag + ): void { + $request->headers = $headersBag; + $request->attributes = $attributesBag; + + $attributesBag->get('_sylius', [])->willReturn([ + 'allowed_serialization_groups' => ['Default'], + 'serialization_groups' => ['Detailed'], + ]); + $headersBag->get('Accept', null, false)->willReturn(['application/json', 'groups=Default,Detailed,Other']); + + $parametersParser + ->parseRequestValues( + [ + 'allowed_serialization_groups' => ['Default'], + 'serialization_groups' => ['Default', 'Detailed'], + ], + $request + ) + ->willReturn(['serialization_groups' => ['Default', 'Detailed']]) + ; + + $this->create($metadata, $request)->getSerializationGroups()->shouldReturn(['Default', 'Detailed']); + } + + function it_creates_configuration_using_only_those_serialization_groups_that_are_defined_as_default( + ParametersParserInterface $parametersParser, + MetadataInterface $metadata, + Request $request, + ParameterBag $headersBag, + ParameterBag $attributesBag + ): void { + $request->headers = $headersBag; + $request->attributes = $attributesBag; + + $attributesBag->get('_sylius', [])->willReturn([ + 'serialization_groups' => ['Detailed'], + ]); + $headersBag->get('Accept', null, false)->willReturn(['application/json', 'groups=Default,Detailed,Other']); + + $parametersParser + ->parseRequestValues(['serialization_groups' => ['Detailed']], $request) + ->willReturn(['serialization_groups' => ['Detailed']]) + ; + + $this->create($metadata, $request)->getSerializationGroups()->shouldReturn(['Detailed']); } function it_creates_configuration_for_serialization_version_from_single_header(