Skip to content

Commit

Permalink
feat(state): strict query parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
soyuka committed May 30, 2024
1 parent 73a4c32 commit 271d70d
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/Metadata/ApiResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,7 @@ public function __construct(
$processor = null,
protected ?OptionsInterface $stateOptions = null,
protected array|Parameters|null $parameters = null,
protected ?bool $strictQueryParameterValidation = null,
protected array $extraProperties = [],
) {
parent::__construct(
Expand Down Expand Up @@ -1002,6 +1003,7 @@ class: $class,
processor: $processor,
stateOptions: $stateOptions,
parameters: $parameters,
strictQueryParameterValidation: $strictQueryParameterValidation,
extraProperties: $extraProperties
);

Expand Down
2 changes: 2 additions & 0 deletions src/Metadata/Delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public function __construct(
$processor = null,
?OptionsInterface $stateOptions = null,
array|Parameters|null $parameters = null,
?bool $strictQueryParameterValidation = null,
array $extraProperties = [],
) {
parent::__construct(
Expand Down Expand Up @@ -172,6 +173,7 @@ class: $class,
extraProperties: $extraProperties,
collectDenormalizationErrors: $collectDenormalizationErrors,
parameters: $parameters,
strictQueryParameterValidation: $strictQueryParameterValidation,
stateOptions: $stateOptions,
);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Metadata/Get.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public function __construct(
$processor = null,
?OptionsInterface $stateOptions = null,
array|Parameters|null $parameters = null,
?bool $strictQueryParameterValidation = null,
array $extraProperties = [],
) {
parent::__construct(
Expand Down Expand Up @@ -171,6 +172,7 @@ class: $class,
processor: $processor,
stateOptions: $stateOptions,
parameters: $parameters,
strictQueryParameterValidation: $strictQueryParameterValidation,
extraProperties: $extraProperties,
);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Metadata/GetCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public function __construct(
$processor = null,
?OptionsInterface $stateOptions = null,
array|Parameters|null $parameters = null,
?bool $strictQueryParameterValidation = null,
array $extraProperties = [],
private ?string $itemUriTemplate = null,
) {
Expand Down Expand Up @@ -172,6 +173,7 @@ class: $class,
processor: $processor,
parameters: $parameters,
extraProperties: $extraProperties,
strictQueryParameterValidation: $strictQueryParameterValidation,
stateOptions: $stateOptions,
);
}
Expand Down
14 changes: 14 additions & 0 deletions src/Metadata/HttpOperation.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ public function __construct(
protected ?array $exceptionToStatus = null,
protected ?bool $queryParameterValidationEnabled = null,
protected ?array $links = null,
protected ?bool $strictQueryParameterValidation = null,

?string $shortName = null,
?string $class = null,
Expand Down Expand Up @@ -635,4 +636,17 @@ public function withLinks(array $links): self

return $self;
}

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

public function withStrictQueryParameterValidation(bool $strictQueryParameterValidation): self
{
$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 @@ -807,6 +807,7 @@ public function __construct(
protected $processor = null,
protected ?OptionsInterface $stateOptions = null,
protected array|Parameters|null $parameters = [],
protected ?bool $strictQueryParameterValidation = null,
protected array $extraProperties = [],
) {
parent::__construct(
Expand Down
2 changes: 2 additions & 0 deletions src/Metadata/Patch.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public function __construct(
$processor = null,
?OptionsInterface $stateOptions = null,
array|Parameters|null $parameters = null,
?bool $strictQueryParameterValidation = null,
array $extraProperties = [],
) {
parent::__construct(
Expand Down Expand Up @@ -172,6 +173,7 @@ class: $class,
processor: $processor,
stateOptions: $stateOptions,
parameters: $parameters,
strictQueryParameterValidation: $strictQueryParameterValidation,
extraProperties: $extraProperties
);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Metadata/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public function __construct(
?OptionsInterface $stateOptions = null,
array|Parameters|null $parameters = null,
array $extraProperties = [],
?bool $strictQueryParameterValidation = null,
private ?string $itemUriTemplate = null
) {
parent::__construct(
Expand Down Expand Up @@ -173,6 +174,7 @@ class: $class,
processor: $processor,
stateOptions: $stateOptions,
parameters: $parameters,
strictQueryParameterValidation: $strictQueryParameterValidation,
extraProperties: $extraProperties
);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Metadata/Put.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public function __construct(
?OptionsInterface $stateOptions = null,
array|Parameters|null $parameters = null,
array $extraProperties = [],
?bool $strictQueryParameterValidation = null,
private ?bool $allowCreate = null,
) {
parent::__construct(
Expand Down Expand Up @@ -173,6 +174,7 @@ class: $class,
processor: $processor,
stateOptions: $stateOptions,
parameters: $parameters,
strictQueryParameterValidation: $strictQueryParameterValidation,
extraProperties: $extraProperties
);
}
Expand Down
38 changes: 38 additions & 0 deletions src/State/Exception/ParameterNotSupportedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

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) {
parent::__construct($message, $code, $previous);
}

public function getType(): string
{
return '/error/400';
}

public function getTitle(): ?string
{
return $this->message;
}

public function getStatus(): ?int
{
return 400;
}

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

public function getInstance(): ?string
{
return $this->parameter;
}
}
16 changes: 16 additions & 0 deletions src/State/Provider/ParameterProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
namespace ApiPlatform\State\Provider;

use ApiPlatform\Metadata\HeaderParameterInterface;
use ApiPlatform\Metadata\HttpOperation;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\Metadata\Parameter;
use ApiPlatform\Metadata\Parameters;
use ApiPlatform\State\Exception\ParameterNotSupportedException;
use ApiPlatform\State\Exception\ProviderNotFoundException;
use ApiPlatform\State\ParameterProviderInterface;
use ApiPlatform\State\ProviderInterface;
Expand Down Expand Up @@ -52,6 +54,20 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
$context = ['operation' => $operation] + $context;
$parameters = $operation->getParameters() ?? [];
$operationParameters = $parameters instanceof Parameters ? iterator_to_array($parameters) : $parameters;

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

foreach (array_keys($request->attributes->get('_api_query_parameters')) as $key) {
if (!in_array($key, $keys)) {
throw new ParameterNotSupportedException($key);
}
}
}

foreach ($operationParameters as $parameter) {
$key = $parameter->getKey();
$parameters = $this->extractParameterValues($parameter, $request, $context);
Expand Down

0 comments on commit 271d70d

Please sign in to comment.