Skip to content

Commit

Permalink
[Task] Introduce lifetime and hubservice (#236)
Browse files Browse the repository at this point in the history
* Introduce lifetime and hubservice

* Apply php-cs-fixer changes

* Add doc

---------

Co-authored-by: mattamon <[email protected]>
  • Loading branch information
mattamon and mattamon authored Jul 9, 2024
1 parent 93c739a commit cf9a1be
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 21 deletions.
3 changes: 2 additions & 1 deletion config/mercure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down
10 changes: 10 additions & 0 deletions doc/02_Mercure_Setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
4 changes: 4 additions & 0 deletions src/DependencyInjection/PimcoreStudioBackendExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
26 changes: 6 additions & 20 deletions src/Mercure/Controller/JwtController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
}

Expand All @@ -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
);
}
}
50 changes: 50 additions & 0 deletions src/Mercure/Service/HubService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\StudioBackendBundle\Mercure\Service;

use Pimcore\Bundle\StudioBackendBundle\Mercure\Util\Constants\Mercure;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\Mercure\HubInterface;

/**
* @internal
*/
final readonly class HubService implements HubServiceInterface
{
public function __construct(
private HubInterface $clientHub,
private int $cookieLifetime = 3600
) {
}

public function createCookie(): Cookie
{
$urlParts = parse_url($this->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
);
}
}
27 changes: 27 additions & 0 deletions src/Mercure/Service/HubServiceInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\StudioBackendBundle\Mercure\Service;

use Symfony\Component\HttpFoundation\Cookie;

/**
* @internal
*/
interface HubServiceInterface
{
public function createCookie(): Cookie;
}
29 changes: 29 additions & 0 deletions src/Mercure/Util/Constants/Mercure.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\StudioBackendBundle\Mercure\Util\Constants;

/**
* @internal
*/
enum Mercure: string
{
case AUTHORIZATION_COOKIE_NAME = 'mercureAuthorization';
case URL_PATH = 'path';
case URL_HOST = 'host';
case URL_SCHEME = 'scheme';
case URL_SCHEME_HTTPS = 'https';
}

0 comments on commit cf9a1be

Please sign in to comment.