From c82ea8634eea5847e3f17e8ad3b46be7056fa68b Mon Sep 17 00:00:00 2001 From: Kevin Bond Date: Wed, 15 Nov 2023 13:19:25 -0500 Subject: [PATCH 1/2] minor: adjust deprecation reporting in tests --- phpunit.xml.dist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 194efc1..7e7143f 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -2,7 +2,7 @@ - + From 06b85512ced652f092efe36169dd2486cd199f24 Mon Sep 17 00:00:00 2001 From: Kevin Bond Date: Wed, 15 Nov 2023 13:28:36 -0500 Subject: [PATCH 2/2] feat: support Symfony 7 --- composer.json | 10 +++---- src/Uri/Signed/SymfonySigner.php | 33 ++++++++++++++------- tests/Bridge/Symfony/Fixture/TestKernel.php | 2 +- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/composer.json b/composer.json index bb3fcb3..47f503f 100644 --- a/composer.json +++ b/composer.json @@ -19,11 +19,11 @@ "phpstan/phpstan": "^1.4", "phpunit/phpunit": "^9.5", "rize/uri-template": "^0.3.5", - "symfony/browser-kit": "^5.4|^6.0", - "symfony/framework-bundle": "^5.4|^6.0", - "symfony/phpunit-bridge": "^6.1", - "symfony/twig-bundle": "^5.4|^6.0", - "symfony/web-link": "^5.4|^6.0" + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/framework-bundle": "^5.4|^6.0|^7.0", + "symfony/phpunit-bridge": "^6.1|^7.0", + "symfony/twig-bundle": "^5.4|^6.0|^7.0", + "symfony/web-link": "^5.4|^6.0|^7.0" }, "provide": { "psr/link-implementation": "1.0|2.0" diff --git a/src/Uri/Signed/SymfonySigner.php b/src/Uri/Signed/SymfonySigner.php index cbc4854..b228976 100644 --- a/src/Uri/Signed/SymfonySigner.php +++ b/src/Uri/Signed/SymfonySigner.php @@ -11,7 +11,8 @@ namespace Zenstruck\Uri\Signed; -use Symfony\Component\HttpKernel\UriSigner; +use Symfony\Component\HttpFoundation\UriSigner; +use Symfony\Component\HttpKernel\UriSigner as LegacyUriSigner; use Zenstruck\Uri; use Zenstruck\Uri\ParsedUri; use Zenstruck\Uri\Signed\Exception\AlreadyUsed; @@ -27,15 +28,12 @@ final class SymfonySigner private const SINGLE_USE_TOKEN_KEY = '_token'; private const HASH_KEY = '_hash'; - private UriSigner $signer; + /** @var UriSigner|LegacyUriSigner */ + private $signer; // @phpstan-ignore-line public function __construct(string $secret) { - if (!\class_exists(UriSigner::class)) { - throw new \LogicException('symfony/http-kernel is required to sign URIs. Install with "composer require symfony/http-kernel".'); - } - - $this->signer = new UriSigner($secret, self::HASH_KEY); + $this->signer = self::createSigner($secret, self::HASH_KEY); } public static function create(self|string $secret): self @@ -57,10 +55,10 @@ public function sign(Uri|string $uri, ?\DateTimeImmutable $expiresAt, ?string $s } if ($singleUseToken) { - $uri = (new UriSigner($singleUseToken, self::SINGLE_USE_TOKEN_KEY))->sign($uri); + $uri = self::createSigner($singleUseToken, self::SINGLE_USE_TOKEN_KEY)->sign($uri); // @phpstan-ignore-line } - return [new ParsedUri($this->signer->sign($uri)), $expiresAt, (bool) $singleUseToken]; + return [new ParsedUri($this->signer->sign($uri)), $expiresAt, (bool) $singleUseToken]; // @phpstan-ignore-line } /** @@ -73,7 +71,7 @@ public function verify(Uri|string $uri, ?string $singleUseToken): array $uri = ParsedUri::wrap($uri); $expiresAt = null; - if (!$this->signer->check($uri)) { + if (!$this->signer->check($uri)) { // @phpstan-ignore-line throw new InvalidSignature($uri); } @@ -101,10 +99,23 @@ public function verify(Uri|string $uri, ?string $singleUseToken): array $withoutHash = $uri->withoutQueryParams(self::HASH_KEY); // @phpstan-ignore-line - if (!(new UriSigner($singleUseToken, self::SINGLE_USE_TOKEN_KEY))->check($withoutHash)) { + if (!self::createSigner($singleUseToken, self::SINGLE_USE_TOKEN_KEY)->check($withoutHash)) { throw new AlreadyUsed($uri); } return [$uri, $expiresAt, true]; } + + private static function createSigner(#[\SensitiveParameter] string $secret, string $parameter = '_hash'): UriSigner|LegacyUriSigner // @phpstan-ignore-line + { + if (\class_exists(UriSigner::class)) { + return new UriSigner($secret, $parameter); + } + + if (\class_exists(LegacyUriSigner::class)) { + return new LegacyUriSigner($secret, $parameter); + } + + throw new \LogicException('symfony/http-foundation is required to sign URIs. Install with "composer require symfony/http-foundation".'); + } } diff --git a/tests/Bridge/Symfony/Fixture/TestKernel.php b/tests/Bridge/Symfony/Fixture/TestKernel.php index d928c5d..ffb6351 100644 --- a/tests/Bridge/Symfony/Fixture/TestKernel.php +++ b/tests/Bridge/Symfony/Fixture/TestKernel.php @@ -60,6 +60,6 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load protected function configureRoutes(RoutingConfigurator $routes): void { - $routes->import(__DIR__, 'annotation'); + $routes->import(__DIR__, self::MAJOR_VERSION < 6 ? 'annotation' : 'attribute'); } }