From cf9a1be2b5f719045cd69d8af8bd2967eb137137 Mon Sep 17 00:00:00 2001 From: Matthias Schuhmayer <38959016+mattamon@users.noreply.github.com> Date: Tue, 9 Jul 2024 10:14:45 +0200 Subject: [PATCH] [Task] Introduce lifetime and hubservice (#236) * Introduce lifetime and hubservice * Apply php-cs-fixer changes * Add doc --------- Co-authored-by: mattamon --- config/mercure.yaml | 3 +- doc/02_Mercure_Setup.md | 10 ++++ src/DependencyInjection/Configuration.php | 4 ++ .../PimcoreStudioBackendExtension.php | 4 ++ src/Mercure/Controller/JwtController.php | 26 +++------- src/Mercure/Service/HubService.php | 50 +++++++++++++++++++ src/Mercure/Service/HubServiceInterface.php | 27 ++++++++++ src/Mercure/Util/Constants/Mercure.php | 29 +++++++++++ 8 files changed, 132 insertions(+), 21 deletions(-) create mode 100644 src/Mercure/Service/HubService.php create mode 100644 src/Mercure/Service/HubServiceInterface.php create mode 100644 src/Mercure/Util/Constants/Mercure.php diff --git a/config/mercure.yaml b/config/mercure.yaml index 402a8147a..6497c93e2 100644 --- a/config/mercure.yaml +++ b/config/mercure.yaml @@ -11,7 +11,8 @@ services: public: true tags: [ 'controller.service_arguments' ] - Pimcore\Bundle\StudioBackendBundle\Mercure\Controller\JwtController: + Pimcore\Bundle\StudioBackendBundle\Mercure\Service\HubServiceInterface: + class: Pimcore\Bundle\StudioBackendBundle\Mercure\Service\HubService arguments: Symfony\Component\Mercure\HubInterface: '@mercure.hub.studio_client' diff --git a/doc/02_Mercure_Setup.md b/doc/02_Mercure_Setup.md index 276747b88..10ba5494c 100644 --- a/doc/02_Mercure_Setup.md +++ b/doc/02_Mercure_Setup.md @@ -29,6 +29,16 @@ pimcore_studio_backend: hub_url_server: 'http://mercure/.well-known/mercure' ``` You need to configure the full URL including protocol, port and path to Mercure here. +Additionally, you can configure the cookie lifetime for the JWT token in seconds. The default value is 3600 seconds. + +```yaml +pimcore_studio_backend: + mercure_settings: + cookie_lifetime: 3600 +``` + + +```yaml ## Example Configuration with docker compose Following there are configuration snippets for a setup with docker compose. diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 539e9eca9..5bb76d6da 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -160,6 +160,10 @@ private function addMercureConfiguration(ArrayNodeDefinition $node): void ->info('The key used to sign the JWT token') ->defaultNull() ->end() + ->integerNode('cookie_lifetime') + ->info('Lifetime of the mercure cookie in seconds. Default is one hour.') + ->defaultValue(3600) + ->end() ->end() ->end(); } diff --git a/src/DependencyInjection/PimcoreStudioBackendExtension.php b/src/DependencyInjection/PimcoreStudioBackendExtension.php index fb2ddab94..d1a3bb756 100644 --- a/src/DependencyInjection/PimcoreStudioBackendExtension.php +++ b/src/DependencyInjection/PimcoreStudioBackendExtension.php @@ -23,6 +23,7 @@ use Pimcore\Bundle\StudioBackendBundle\Element\Service\ElementDeleteServiceInterface; use Pimcore\Bundle\StudioBackendBundle\EventSubscriber\CorsSubscriber; use Pimcore\Bundle\StudioBackendBundle\Exception\InvalidPathException; +use Pimcore\Bundle\StudioBackendBundle\Mercure\Service\HubServiceInterface; use Pimcore\Bundle\StudioBackendBundle\OpenApi\Service\OpenApiServiceInterface; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -75,6 +76,9 @@ public function load(array $configs, ContainerBuilder $container): void $definition = $container->getDefinition(ElementDeleteServiceInterface::class); $definition->setArgument('$recycleBinThreshold', $config['element_recycle_bin_threshold']); + + $definition = $container->getDefinition(HubServiceInterface::class); + $definition->setArgument('$cookieLifetime', $config['mercure_settings']['cookie_lifetime']); } public function prepend(ContainerBuilder $container): void diff --git a/src/Mercure/Controller/JwtController.php b/src/Mercure/Controller/JwtController.php index 3a04a2e9c..79461b742 100644 --- a/src/Mercure/Controller/JwtController.php +++ b/src/Mercure/Controller/JwtController.php @@ -18,12 +18,11 @@ use OpenApi\Attributes\Post; use Pimcore\Bundle\StudioBackendBundle\Controller\AbstractApiController; +use Pimcore\Bundle\StudioBackendBundle\Mercure\Service\HubServiceInterface; use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\DefaultResponses; use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attributes\Response\SuccessResponse; use Pimcore\Bundle\StudioBackendBundle\OpenApi\Config\Tags; -use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Mercure\HubInterface; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Serializer\SerializerInterface; @@ -32,8 +31,10 @@ */ final class JwtController extends AbstractApiController { - public function __construct(private readonly HubInterface $clientHub, SerializerInterface $serializer) - { + public function __construct( + private readonly HubServiceInterface $hubService, + SerializerInterface $serializer + ) { parent::__construct($serializer); } @@ -52,24 +53,9 @@ public function auth(): Response { $res = new Response(); $res->headers->setCookie( - $this->createCookie(0) + $this->hubService->createCookie() ); return $res; } - - private function createCookie(int $lifetime): Cookie - { - $urlParts = parse_url($this->clientHub->getPublicUrl()); - - return Cookie::create( - 'mercureAuthorization', - $this->clientHub->getProvider()->getJwt(), - $lifetime, - $urlParts['path'] ?? '/', - $urlParts['host'] ?? '', - $urlParts['scheme'] === 'https', - true - ); - } } diff --git a/src/Mercure/Service/HubService.php b/src/Mercure/Service/HubService.php new file mode 100644 index 000000000..cbdc6dfb4 --- /dev/null +++ b/src/Mercure/Service/HubService.php @@ -0,0 +1,50 @@ +clientHub->getPublicUrl()); + + return new Cookie( + Mercure::AUTHORIZATION_COOKIE_NAME->value, + $this->clientHub->getProvider()->getJwt(), + time() + $this->cookieLifetime, + $urlParts[Mercure::URL_PATH->value] ?? '/', + $urlParts[Mercure::URL_HOST->value] ?? '', + $urlParts[Mercure::URL_SCHEME->value] === Mercure::URL_SCHEME_HTTPS->value, + true, + false, + Cookie::SAMESITE_STRICT + ); + } +} diff --git a/src/Mercure/Service/HubServiceInterface.php b/src/Mercure/Service/HubServiceInterface.php new file mode 100644 index 000000000..2df502aaa --- /dev/null +++ b/src/Mercure/Service/HubServiceInterface.php @@ -0,0 +1,27 @@ +