From 10a11a69e658d9f0980eb2a330346ece44888123 Mon Sep 17 00:00:00 2001 From: Victor Bocharsky Date: Sat, 2 Dec 2023 22:45:48 +0100 Subject: [PATCH] Allow Symfony 7 (#148) * Allow Symfony 7 * An empty commit * Try to fix tests with UriSignerFactory * Fix CS * Drop SensitiveParameter * Move UriSignerFactory into Factory namespace * Drop Psalm dependency - we set it up in the CI * Some minor tweaks + fix psalm issues * Simplify Psalm config * Create uri_signer service from the factory * Add uri_signer service to the tests too * Inject a specific service instead of factory * Fix CS --- composer.json | 13 +++--- psalm.xml | 21 ++++++---- .../SymfonyCastsVerifyEmailExtension.php | 3 ++ src/Factory/UriSignerFactory.php | 41 +++++++++++++++++++ src/Model/VerifyEmailSignatureComponents.php | 3 ++ .../config/verify_email_services.xml | 6 ++- src/SymfonyCastsVerifyEmailBundle.php | 2 +- src/VerifyEmailHelper.php | 8 +++- .../VerifyEmailHelperFunctionalTest.php | 11 ++++- .../VerifyEmailServiceDefinitionTest.php | 1 + tests/UnitTests/VerifyEmailHelperTest.php | 9 +++- 11 files changed, 94 insertions(+), 24 deletions(-) create mode 100644 src/Factory/UriSignerFactory.php diff --git a/composer.json b/composer.json index 767c0a8..127693f 100644 --- a/composer.json +++ b/composer.json @@ -7,18 +7,17 @@ "require": { "php": ">=7.2.5", "ext-json": "*", - "symfony/config": "^5.4 | ^6.0", - "symfony/dependency-injection": "^5.4 | ^6.0", - "symfony/http-kernel": "^5.4 | ^6.0", - "symfony/routing": "^5.4 | ^6.0", + "symfony/config": "^5.4 | ^6.0 | ^7.0", + "symfony/dependency-injection": "^5.4 | ^6.0 | ^7.0", + "symfony/http-kernel": "^5.4 | ^6.0 | ^7.0", + "symfony/routing": "^5.4 | ^6.0 | ^7.0", "symfony/deprecation-contracts": "^2.2 | ^3.0" }, "require-dev": { "doctrine/orm": "^2.7", "doctrine/persistence": "^2.0", - "symfony/framework-bundle": "^5.4 | ^6.0", - "symfony/phpunit-bridge": "^5.4 | ^6.0", - "vimeo/psalm": "^4.3" + "symfony/framework-bundle": "^5.4 | ^6.0 | ^7.0", + "symfony/phpunit-bridge": "^5.4 | ^6.0 | ^7.0" }, "autoload": { "psr-4": { diff --git a/psalm.xml b/psalm.xml index 0c6bd36..70ed8bd 100644 --- a/psalm.xml +++ b/psalm.xml @@ -50,20 +50,23 @@ - + + - + - - + + - + + - - + + - + + - + diff --git a/src/DependencyInjection/SymfonyCastsVerifyEmailExtension.php b/src/DependencyInjection/SymfonyCastsVerifyEmailExtension.php index b5419e5..50fe099 100644 --- a/src/DependencyInjection/SymfonyCastsVerifyEmailExtension.php +++ b/src/DependencyInjection/SymfonyCastsVerifyEmailExtension.php @@ -26,6 +26,9 @@ public function load(array $configs, ContainerBuilder $container): void $loader->load('verify_email_services.xml'); $configuration = $this->getConfiguration($configs, $container); + if (!$configuration) { + throw new \Exception('Configuration is not expected to be null'); + } $config = $this->processConfiguration($configuration, $configs); diff --git a/src/Factory/UriSignerFactory.php b/src/Factory/UriSignerFactory.php new file mode 100644 index 0000000..7493117 --- /dev/null +++ b/src/Factory/UriSignerFactory.php @@ -0,0 +1,41 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SymfonyCasts\Bundle\VerifyEmail\Factory; + +use Symfony\Component\HttpFoundation\UriSigner; +use Symfony\Component\HttpKernel\UriSigner as LegacyUriSigner; + +/** + * @author Victor Bocharsky + * @author Ryan Weaver + */ +class UriSignerFactory +{ + private $secret; + private $parameter; + + public function __construct(string $secret, string $parameter = '_hash') + { + $this->secret = $secret; + $this->parameter = $parameter; + } + + /** + * @return UriSigner|LegacyUriSigner + */ + public function createUriSigner(): object + { + if (class_exists(UriSigner::class)) { + return new UriSigner($this->secret, $this->parameter); + } + + return new LegacyUriSigner($this->secret, $this->parameter); + } +} diff --git a/src/Model/VerifyEmailSignatureComponents.php b/src/Model/VerifyEmailSignatureComponents.php index 77c9557..6ab5a5a 100644 --- a/src/Model/VerifyEmailSignatureComponents.php +++ b/src/Model/VerifyEmailSignatureComponents.php @@ -130,6 +130,9 @@ public function getExpiresAtIntervalInstance(): \DateInterval return $this->expiresAt->diff($createdAtTime); } + /** + * @psalm-suppress UndefinedFunction + */ private function triggerDeprecation(): void { trigger_deprecation( diff --git a/src/Resources/config/verify_email_services.xml b/src/Resources/config/verify_email_services.xml index cd3e0db..bdb93ea 100644 --- a/src/Resources/config/verify_email_services.xml +++ b/src/Resources/config/verify_email_services.xml @@ -11,11 +11,15 @@ - + %kernel.secret% signature + + + + diff --git a/src/SymfonyCastsVerifyEmailBundle.php b/src/SymfonyCastsVerifyEmailBundle.php index f97a972..8f6d640 100644 --- a/src/SymfonyCastsVerifyEmailBundle.php +++ b/src/SymfonyCastsVerifyEmailBundle.php @@ -21,7 +21,7 @@ class SymfonyCastsVerifyEmailBundle extends Bundle { public function getContainerExtension(): ?ExtensionInterface { - if (null === $this->extension) { + if (!$this->extension) { $this->extension = new SymfonyCastsVerifyEmailExtension(); } diff --git a/src/VerifyEmailHelper.php b/src/VerifyEmailHelper.php index 328b17c..377b0d9 100644 --- a/src/VerifyEmailHelper.php +++ b/src/VerifyEmailHelper.php @@ -9,7 +9,8 @@ namespace SymfonyCasts\Bundle\VerifyEmail; -use Symfony\Component\HttpKernel\UriSigner; +use Symfony\Component\HttpFoundation\UriSigner; +use Symfony\Component\HttpKernel\UriSigner as LegacyUriSigner; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use SymfonyCasts\Bundle\VerifyEmail\Exception\ExpiredSignatureException; use SymfonyCasts\Bundle\VerifyEmail\Exception\InvalidSignatureException; @@ -25,6 +26,9 @@ final class VerifyEmailHelper implements VerifyEmailHelperInterface { private $router; + /** + * @var UriSigner|LegacyUriSigner + */ private $uriSigner; private $queryUtility; private $tokenGenerator; @@ -34,7 +38,7 @@ final class VerifyEmailHelper implements VerifyEmailHelperInterface */ private $lifetime; - public function __construct(UrlGeneratorInterface $router, UriSigner $uriSigner, VerifyEmailQueryUtility $queryUtility, VerifyEmailTokenGenerator $generator, int $lifetime) + public function __construct(UrlGeneratorInterface $router, /* no typehint for BC with legacy PHP */ $uriSigner, VerifyEmailQueryUtility $queryUtility, VerifyEmailTokenGenerator $generator, int $lifetime) { $this->router = $router; $this->uriSigner = $uriSigner; diff --git a/tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php b/tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php index edf2d4f..63bc716 100644 --- a/tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php +++ b/tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php @@ -11,7 +11,8 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\PhpUnit\ClockMock; -use Symfony\Component\HttpKernel\UriSigner; +use Symfony\Component\HttpFoundation\UriSigner; +use Symfony\Component\HttpKernel\UriSigner as LegacyUriSigner; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use SymfonyCasts\Bundle\VerifyEmail\Generator\VerifyEmailTokenGenerator; use SymfonyCasts\Bundle\VerifyEmail\Util\VerifyEmailQueryUtility; @@ -105,9 +106,15 @@ private function getTestSignedUri(): string private function getHelper(): VerifyEmailHelperInterface { + if (class_exists(UriSigner::class)) { + $uriSigner = new UriSigner('foo', 'signature'); + } else { + $uriSigner = new LegacyUriSigner('foo', 'signature'); + } + return new VerifyEmailHelper( $this->mockRouter, - new UriSigner('foo', 'signature'), + $uriSigner, new VerifyEmailQueryUtility(), new VerifyEmailTokenGenerator('foo'), 3600 diff --git a/tests/IntegrationTests/VerifyEmailServiceDefinitionTest.php b/tests/IntegrationTests/VerifyEmailServiceDefinitionTest.php index efe4a2e..875e5b8 100644 --- a/tests/IntegrationTests/VerifyEmailServiceDefinitionTest.php +++ b/tests/IntegrationTests/VerifyEmailServiceDefinitionTest.php @@ -25,6 +25,7 @@ public function bundleServiceDefinitionDataProvider(): \Generator $prefix = 'symfonycasts.verify_email.'; yield [$prefix.'query_utility']; + yield [$prefix.'uri_signer_factory']; yield [$prefix.'uri_signer']; yield [$prefix.'helper']; yield [$prefix.'token_generator']; diff --git a/tests/UnitTests/VerifyEmailHelperTest.php b/tests/UnitTests/VerifyEmailHelperTest.php index d867cad..598f27d 100644 --- a/tests/UnitTests/VerifyEmailHelperTest.php +++ b/tests/UnitTests/VerifyEmailHelperTest.php @@ -11,7 +11,8 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\PhpUnit\ClockMock; -use Symfony\Component\HttpKernel\UriSigner; +use Symfony\Component\HttpFoundation\UriSigner; +use Symfony\Component\HttpKernel\UriSigner as LegacyUriSigner; use Symfony\Component\Routing\RouterInterface; use SymfonyCasts\Bundle\VerifyEmail\Exception\ExpiredSignatureException; use SymfonyCasts\Bundle\VerifyEmail\Exception\InvalidSignatureException; @@ -39,7 +40,11 @@ protected function setUp(): void ClockMock::register(VerifyEmailHelper::class); $this->mockRouter = $this->createMock(RouterInterface::class); - $this->mockSigner = $this->createMock(UriSigner::class); + if (class_exists(UriSigner::class)) { + $this->mockSigner = $this->createMock(UriSigner::class); + } else { + $this->mockSigner = $this->createMock(LegacyUriSigner::class); + } $this->mockQueryUtility = $this->createMock(VerifyEmailQueryUtility::class); $this->tokenGenerator = $this->createMock(VerifyEmailTokenGenerator::class); }