Update configuration to comply with symfony 7.2

This commit is contained in:
2025-05-22 17:45:52 +02:00
parent eab5a8be7b
commit 053b92b77c
30 changed files with 408 additions and 83 deletions

View File

@@ -19,6 +19,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
#[\Symfony\Component\Console\Attribute\AsCommand(name: 'chill:doc-store:configure-openstack')]
class ConfigureOpenstackObjectStorageCommand extends Command
{
protected static $defaultDescription = 'Configure openstack container to store documents';
@@ -39,7 +40,6 @@ class ConfigureOpenstackObjectStorageCommand extends Command
protected function configure()
{
$this
->setName('chill:doc-store:configure-openstack')
->addOption('os_token', 'o', InputOption::VALUE_REQUIRED, 'Openstack token')
->addOption('domain', 'd', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Domain name')
;

View File

@@ -22,7 +22,7 @@ use Symfony\Component\Config\Definition\ConfigurationInterface;
*/
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
public function getConfigTreeBuilder(): \Symfony\Component\Config\Definition\Builder\TreeBuilder
{
$treeBuilder = new TreeBuilder('chill_doc_store');
/** @var ArrayNodeDefinition $rootNode */

View File

@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\DocStoreBundle\Security\Authenticator;
use Lexik\Bundle\JWTAuthenticationBundle\TokenExtractor\TokenExtractorInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Extract the JWT Token from the segment of the dav endpoints.
*
* A segment is a separation inside the string, using the character "/".
*
* For recognizing the JWT, the first segment must be "dav", and the second one must be
* the JWT endpoint.
*/
final readonly class DavOnUrlTokenExtractor implements TokenExtractorInterface
{
public function __construct(
private LoggerInterface $logger,
) {}
public function extract(Request $request): false|string
{
$uri = $request->getRequestUri();
$segments = array_values(
array_filter(
explode('/', $uri),
fn ($item) => '' !== trim($item)
)
);
if (2 > count($segments)) {
$this->logger->info('not enough segment for parsing URL');
return false;
}
if ('dav' !== $segments[0]) {
$this->logger->info('the first segment of the url must be DAV');
return false;
}
return $segments[1];
}
}

View File

@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\DocStoreBundle\Security\Authenticator;
use Chill\DocStoreBundle\Security\Authenticator\DavOnUrlTokenExtractor;
use Lexik\Bundle\JWTAuthenticationBundle\Exception\InvalidTokenException;
use Lexik\Bundle\JWTAuthenticationBundle\Exception\JWTDecodeFailureException;
use Lexik\Bundle\JWTAuthenticationBundle\Exception\MissingTokenException;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
/**
* JWT authenticator for DAV URL endpoints.
*/
class JWTOnDavUrlAuthenticator extends AbstractAuthenticator
{
public function __construct(
private readonly JWTTokenManagerInterface $jwtManager,
private readonly DavOnUrlTokenExtractor $davOnUrlTokenExtractor,
) {
}
public function supports(Request $request): ?bool
{
return false !== $this->davOnUrlTokenExtractor->extract($request);
}
public function authenticate(Request $request): Passport
{
$token = $this->davOnUrlTokenExtractor->extract($request);
if (false === $token) {
throw new MissingTokenException('JWT Token not found');
}
try {
$payload = $this->jwtManager->parse($token);
} catch (JWTDecodeFailureException $e) {
throw new InvalidTokenException('Invalid JWT Token', 0, $e);
}
$username = $payload['username'] ?? $payload['email'] ?? $payload['user_id'] ?? null;
if (null === $username) {
throw new InvalidTokenException('Invalid JWT Token: Username not found');
}
return new SelfValidatingPassport(new UserBadge($username));
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
// On success, let the request continue
return null;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
throw $exception;
}
}