Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
soyuka committed Dec 16, 2024
1 parent 03ffbee commit 9ab6cd4
Show file tree
Hide file tree
Showing 16 changed files with 117 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/Metadata/Extractor/XmlResourceExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ private function buildExtendedBase(\SimpleXMLElement $resource): array
'paginationViaCursor' => $this->buildPaginationViaCursor($resource),
'exceptionToStatus' => $this->buildExceptionToStatus($resource),
'queryParameterValidationEnabled' => $this->phpize($resource, 'queryParameterValidationEnabled', 'bool'),
'strictQueryParameterValidation' => $this->phpize($resource, 'strictQueryParameterValidation', 'bool'),
'stateOptions' => $this->buildStateOptions($resource),
'links' => $this->buildLinks($resource),
'headers' => $this->buildHeaders($resource),
Expand Down
1 change: 1 addition & 0 deletions src/Metadata/Extractor/YamlResourceExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ private function buildOperations(array $resource, array $root): ?array
'write' => $this->phpize($operation, 'write', 'bool'),
'serialize' => $this->phpize($operation, 'serialize', 'bool'),
'queryParameterValidate' => $this->phpize($operation, 'queryParameterValidate', 'bool'),
'strictQueryParameterValidation' => $this->phpize($operation, 'strictQueryParameterValidation', 'bool'),
'priority' => $this->phpize($operation, 'priority', 'integer'),
'name' => $this->phpize($operation, 'name', 'string'),
'class' => (string) $class,
Expand Down
1 change: 1 addition & 0 deletions src/Metadata/Extractor/schema/resources.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@

<xsd:attributeGroup name="extendedBase">
<xsd:attributeGroup ref="base"/>
<xsd:attribute type="xsd:boolean" name="strictQueryParameterValidation"/>
<xsd:attribute type="xsd:boolean" name="queryParameterValidationEnabled"/>
<xsd:attribute type="xsd:string" name="routePrefix"/>
<xsd:attribute type="xsd:boolean" name="stateless"/>
Expand Down
12 changes: 1 addition & 11 deletions src/Metadata/HttpOperation.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ class: $class,
policy: $policy,
middleware: $middleware,
queryParameterValidationEnabled: $queryParameterValidationEnabled,
strictQueryParameterValidation: $strictQueryParameterValidation,
extraProperties: $extraProperties
);
}
Expand Down Expand Up @@ -631,17 +632,6 @@ public function withErrors(array $errors): self
{
$self = clone $this;
$self->errors = $errors;
}

public function getStrictQueryParameterValidation(): ?bool
{
return $this->strictQueryParameterValidation;
}

public function withStrictQueryParameterValidation(bool $strictQueryParameterValidation): self
{
$self = clone $this;
$self->strictQueryParameterValidation = $strictQueryParameterValidation;

return $self;
}
Expand Down
13 changes: 13 additions & 0 deletions src/Metadata/Metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -667,4 +667,17 @@ public function withExtraProperties(array $extraProperties = []): static

return $self;
}

public function getStrictQueryParameterValidation(): ?bool
{
return $this->strictQueryParameterValidation;
}

public function withStrictQueryParameterValidation(bool $strictQueryParameterValidation): static
{
$self = clone $this;
$self->strictQueryParameterValidation = $strictQueryParameterValidation;

return $self;
}
}
1 change: 1 addition & 0 deletions src/Metadata/Operation.php
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,7 @@ class: $class,
policy: $policy,
middleware: $middleware,
queryParameterValidationEnabled: $queryParameterValidationEnabled,
strictQueryParameterValidation: $strictQueryParameterValidation,
extraProperties: $extraProperties,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ final class XmlResourceAdapter implements ResourceAdapterInterface
'securityPostValidation',
'securityPostValidationMessage',
'queryParameterValidationEnabled',
'strictQueryParameterValidation',
'stateOptions',
'collectDenormalizationErrors',
'links',
Expand Down
2 changes: 1 addition & 1 deletion src/Metadata/Tests/Extractor/Adapter/resources.xml

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/Metadata/Tests/Extractor/Adapter/resources.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ resources:
exceptionToStatus:
Symfony\Component\Serializer\Exception\ExceptionInterface: 404
queryParameterValidationEnabled: false
strictQueryParameterValidation: false
read: true
deserialize: false
validate: false
Expand Down Expand Up @@ -339,6 +340,7 @@ resources:
policy: null
middleware: null
parameters: null
strictQueryParameterValidation: false
extraProperties:
custom_property: 'Lorem ipsum dolor sit amet'
another_custom_property:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ final class ResourceMetadataCompatibilityTest extends TestCase
'securityPostValidation' => 'is_granted(\'ROLE_OWNER\')',
'securityPostValidationMessage' => 'Sorry, you must the owner of this resource to access it.',
'queryParameterValidationEnabled' => true,
'strictQueryParameterValidation' => false,
'types' => ['someirischema', 'anotheririschema'],
'formats' => [
'json' => null,
Expand Down Expand Up @@ -399,6 +400,7 @@ final class ResourceMetadataCompatibilityTest extends TestCase
'Symfony\Component\Serializer\Exception\ExceptionInterface' => 404,
],
'queryParameterValidationEnabled' => false,
'strictQueryParameterValidation' => false,
'read' => true,
'deserialize' => false,
'validate' => false,
Expand Down Expand Up @@ -486,6 +488,7 @@ final class ResourceMetadataCompatibilityTest extends TestCase
'condition',
'controller',
'queryParameterValidationEnabled',
'strictQueryParameterValidation',
'exceptionToStatus',
'types',
'formats',
Expand Down
4 changes: 4 additions & 0 deletions src/Metadata/Tests/Extractor/XmlExtractorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public function testValidXML(): void
'securityPostValidation' => null,
'securityPostValidationMessage' => null,
'queryParameterValidationEnabled' => null,
'strictQueryParameterValidation' => null,
'input' => null,
'output' => null,
'types' => null,
Expand Down Expand Up @@ -136,6 +137,7 @@ public function testValidXML(): void
'securityPostValidation' => null,
'securityPostValidationMessage' => null,
'queryParameterValidationEnabled' => null,
'strictQueryParameterValidation' => null,
'input' => null,
'output' => null,
'types' => ['someirischema', 'anotheririschema'],
Expand Down Expand Up @@ -264,6 +266,7 @@ public function testValidXML(): void
'write' => null,
'serialize' => null,
'queryParameterValidate' => null,
'strictQueryParameterValidation' => null,
'collection' => null,
'method' => null,
'priority' => null,
Expand Down Expand Up @@ -367,6 +370,7 @@ public function testValidXML(): void
'write' => null,
'serialize' => null,
'queryParameterValidate' => null,
'strictQueryParameterValidation' => null,
'collection' => null,
'method' => null,
'priority' => null,
Expand Down
2 changes: 2 additions & 0 deletions src/Metadata/Tests/Extractor/YamlExtractorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ public function testValidYaml(): void
'securityPostValidation' => null,
'securityPostValidationMessage' => null,
'queryParameterValidationEnabled' => null,
'strictQueryParameterValidation' => null,
'input' => null,
'output' => null,
'types' => ['someirischema'],
Expand Down Expand Up @@ -353,6 +354,7 @@ public function testValidYaml(): void
'securityPostValidation' => null,
'securityPostValidationMessage' => null,
'queryParameterValidationEnabled' => null,
'strictQueryParameterValidation' => null,
'input' => null,
'output' => null,
'types' => ['anotheririschema'],
Expand Down
16 changes: 14 additions & 2 deletions src/State/Exception/ParameterNotSupportedException.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\State\Exception;

use ApiPlatform\Metadata\Exception\ProblemExceptionInterface;
use ApiPlatform\Metadata\Exception\RuntimeException;

final class ParameterNotSupportedException extends RuntimeException implements ProblemExceptionInterface
{
public function __construct(private readonly string $parameter, string $message = "Parameter not supported", int $code = 0, \Throwable|null $previous = null) {
public function __construct(private readonly string $parameter, string $message = 'Parameter not supported', int $code = 0, ?\Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
}

Expand All @@ -28,7 +40,7 @@ public function getStatus(): ?int

public function getDetail(): ?string
{
return sprintf('Parameter "%s" not supported', $this->parameter);
return \sprintf('Parameter "%s" not supported', $this->parameter);
}

public function getInstance(): ?string
Expand Down
5 changes: 2 additions & 3 deletions src/State/Provider/ParameterProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ public function provide(Operation $operation, array $uriVariables = [], array $c

if ($operation instanceof HttpOperation && true === $operation->getStrictQueryParameterValidation()) {
$keys = [];
foreach($parameters as $parameter) {
foreach ($parameters as $parameter) {
$keys[] = $parameter->getKey();
}

foreach (array_keys($request->attributes->get('_api_query_parameters')) as $key) {
if (!in_array($key, $keys)) {
if (!\in_array($key, $keys, true)) {
throw new ParameterNotSupportedException($key);
}
}
Expand Down Expand Up @@ -119,4 +119,3 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
return $this->decorated?->provide($operation, $uriVariables, $context);
}
}

21 changes: 21 additions & 0 deletions tests/Fixtures/TestBundle/ApiResource/StrictParameters.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace ApiPlatform\Tests\Fixtures\TestBundle\ApiResource;

use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\QueryParameter;

#[Get(
uriTemplate: 'strict_query_parameters',
strictQueryParameterValidation: true,
parameters: [
'foo' => new QueryParameter
],
provider: [self::class, 'provider']
)]
class StrictParameters {
public string $id;
static public function provider() {
return new self();
}
}
49 changes: 49 additions & 0 deletions tests/Functional/Parameters/StrictParametersTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\Tests\Functional\Parameters;

use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\StrictParameters;
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\WithSecurityParameter;
use ApiPlatform\Tests\SetupClassResourcesTrait;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\User\InMemoryUser;

final class StrictParametersTest extends ApiTestCase
{
use SetupClassResourcesTrait;

/**
* @return class-string[]
*/
public static function getResources(): array
{
return [StrictParameters::class];
}

public function testErrorAsParameterIsNotAllowed()
{
self::createClient()->request('GET', 'strict_query_parameters?bar=test');
$this->assertJsonContains(['detail' => 'Parameter not supported']);
$this->assertResponseStatusCodeSame(400);
}

public function testCorrectParameters()
{
self::createClient()->request('GET', 'strict_query_parameters');
$this->assertResponseStatusCodeSame(200);
self::createClient()->request('GET', 'strict_query_parameters?foo=test');
$this->assertResponseStatusCodeSame(200);
}
}

0 comments on commit 9ab6cd4

Please sign in to comment.