chore(symfony) #57 : bump symfony to version 6.4 and fix deprecations
Some checks failed
Cadoles/hydra-sql/pipeline/pr-develop There was a failure building this commit
Some checks failed
Cadoles/hydra-sql/pipeline/pr-develop There was a failure building this commit
This commit is contained in:
@ -11,21 +11,17 @@ use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
||||
use Symfony\Component\Finder\Exception\AccessDeniedException;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class MainController extends AbstractController
|
||||
{
|
||||
private HydraService $hydra;
|
||||
private Client $client;
|
||||
private SessionInterface $session;
|
||||
|
||||
public function __construct(SessionInterface $session, HydraService $hydra, Client $client)
|
||||
{
|
||||
$this->session = $session;
|
||||
$this->client = $client;
|
||||
$this->hydra = $hydra;
|
||||
public function __construct(
|
||||
private readonly RequestStack $requestStack,
|
||||
private readonly HydraService $hydra,
|
||||
private readonly Client $client
|
||||
){
|
||||
}
|
||||
|
||||
#[Route('/', name: 'app_home')]
|
||||
@ -38,9 +34,9 @@ class MainController extends AbstractController
|
||||
* Route de Healthcheck (notament pour kubernetes)
|
||||
*/
|
||||
#[Route('/health', name: 'health')]
|
||||
public function health(Request $request): Response
|
||||
public function health(): Response
|
||||
{
|
||||
return new Response('healthy', 200);
|
||||
return new Response('healthy', Response::HTTP_OK);
|
||||
}
|
||||
|
||||
#[Route('/connect/login-accept', name: 'app_login_accept', methods: ['GET'])]
|
||||
@ -51,7 +47,7 @@ class MainController extends AbstractController
|
||||
if (!$user instanceof User) {
|
||||
throw new AccessDeniedException();
|
||||
}
|
||||
$challenge = $this->session->get('challenge');
|
||||
$challenge = $this->requestStack->getSession()->get('challenge');
|
||||
if (!$challenge) {
|
||||
return new RedirectResponse($this->getParameter('issuer_url'));
|
||||
}
|
||||
|
@ -39,12 +39,12 @@ class SecurityController extends AbstractController
|
||||
}
|
||||
|
||||
return $this->render('login.html.twig', [
|
||||
'loginForm' => $loginForm->createView(),
|
||||
'loginForm' => $loginForm,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/logout', name: 'logout')]
|
||||
public function logout(Request $request): void
|
||||
public function logout(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
|
||||
class SQLLoginConfiguration implements ConfigurationInterface
|
||||
{
|
||||
public function getConfigTreeBuilder()
|
||||
public function getConfigTreeBuilder(): TreeBuilder
|
||||
{
|
||||
$treeBuilder = new TreeBuilder('sql_login');
|
||||
$treeBuilder->getRootNode()->children()
|
||||
|
@ -9,14 +9,12 @@ class User implements UserInterface
|
||||
private array $attributes = [];
|
||||
private string $login;
|
||||
private string $password;
|
||||
private bool $rememberMe;
|
||||
|
||||
public function __construct($login, $password, $attributes, $rememberMe = false)
|
||||
public function __construct($login, $password, $attributes)
|
||||
{
|
||||
$this->password = $password;
|
||||
$this->login = $login;
|
||||
$this->attributes = $attributes;
|
||||
$this->rememberMe = $rememberMe;
|
||||
}
|
||||
|
||||
public function getLogin(): ?string
|
||||
@ -34,11 +32,6 @@ class User implements UserInterface
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
public function getRememberMe(): bool
|
||||
{
|
||||
return $this->rememberMe;
|
||||
}
|
||||
|
||||
public function getRoles(): array
|
||||
{
|
||||
return ['ROLE_USER'];
|
||||
|
@ -8,23 +8,18 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||
|
||||
class HydraService extends AbstractController
|
||||
{
|
||||
private SessionInterface $session;
|
||||
private Client $client;
|
||||
private TokenStorageInterface $tokenStorage;
|
||||
private string $baseUrl;
|
||||
|
||||
public function __construct(Client $client, SessionInterface $session, TokenStorageInterface $tokenStorage, string $baseUrl)
|
||||
{
|
||||
$this->session = $session;
|
||||
$this->client = $client;
|
||||
$this->tokenStorage = $tokenStorage;
|
||||
$this->baseUrl = $baseUrl;
|
||||
public function __construct(
|
||||
private readonly Client $client,
|
||||
private readonly RequestStack $requestStack,
|
||||
private readonly TokenStorageInterface $tokenStorage,
|
||||
private readonly string $baseUrl
|
||||
){
|
||||
}
|
||||
|
||||
public function handleLoginRequest(Request $request): RedirectResponse
|
||||
@ -38,11 +33,11 @@ class HydraService extends AbstractController
|
||||
$res = $this->client->fetchLoginRequestInfo($challenge);
|
||||
$loginRequestInfo = $res->toArray();
|
||||
if (200 !== $res->getStatusCode()) {
|
||||
$this->session->clear();
|
||||
$this->requestStack->getSession()->clear();
|
||||
throw new BadRequestException();
|
||||
}
|
||||
// si le challenge est validé par hydra, on le stocke en session pour l'utiliser par la suite et on redirige vers une route interne protégée qui va déclencher l'identification FranceConnect
|
||||
$this->session->set('challenge', $loginRequestInfo['challenge']);
|
||||
$this->requestStack->getSession()->set('challenge', $loginRequestInfo['challenge']);
|
||||
|
||||
return new RedirectResponse($this->baseUrl.'/connect/login-accept');
|
||||
}
|
||||
@ -77,7 +72,7 @@ class HydraService extends AbstractController
|
||||
}
|
||||
$logoutRequestInfo = $this->client->fetchLogoutRequestInfo($logoutChallenge)->toArray();
|
||||
$logoutAcceptRes = $this->client->acceptLogoutRequest($logoutRequestInfo['challenge'])->toArray();
|
||||
$this->session->clear();
|
||||
$this->requestStack->getSession()->clear();
|
||||
$this->tokenStorage->setToken(null);
|
||||
|
||||
return new RedirectResponse($logoutAcceptRes['redirect_to']);
|
||||
|
@ -10,16 +10,16 @@ use App\SQLLogin\Exception\EmptyResultException;
|
||||
use App\SQLLogin\Exception\InvalidSQLPasswordException;
|
||||
use App\SQLLogin\Exception\SecurityPatternConfigurationException;
|
||||
use App\SQLLogin\SQLLoginRequest;
|
||||
use PDOException;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
|
||||
use Symfony\Component\Security\Http\SecurityRequestAttributes;
|
||||
|
||||
class SQLLoginUserAuthenticator extends AbstractLoginFormAuthenticator
|
||||
{
|
||||
@ -27,18 +27,12 @@ class SQLLoginUserAuthenticator extends AbstractLoginFormAuthenticator
|
||||
public const ERROR_LOGIN = 'error_login';
|
||||
public const TECHNICAL_ERROR = 'technical_error';
|
||||
|
||||
private string $baseUrl;
|
||||
|
||||
public function __construct(
|
||||
string $baseUrl,
|
||||
private SQLLoginService $sqlLoginService,
|
||||
private PasswordEncoder $passwordHasher,
|
||||
private SQLLoginRequest $sqlLoginRequest
|
||||
) {
|
||||
$this->baseUrl = $baseUrl;
|
||||
$this->sqlLoginService = $sqlLoginService;
|
||||
$this->passwordHasher = $passwordHasher;
|
||||
$this->sqlLoginRequest = $sqlLoginRequest;
|
||||
private readonly string $baseUrl,
|
||||
private readonly SQLLoginService $sqlLoginService,
|
||||
private readonly PasswordEncoder $passwordHasher,
|
||||
private readonly SQLLoginRequest $sqlLoginRequest
|
||||
){
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,24 +52,23 @@ class SQLLoginUserAuthenticator extends AbstractLoginFormAuthenticator
|
||||
|
||||
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): RedirectResponse
|
||||
{
|
||||
$request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
|
||||
$request->getSession()->set(SecurityRequestAttributes::AUTHENTICATION_ERROR, $exception);
|
||||
|
||||
return new RedirectResponse($this->baseUrl.'/login');
|
||||
}
|
||||
|
||||
public function authenticate(Request $request): SelfValidatingPassport
|
||||
{
|
||||
$form = $request->request->get('login');
|
||||
$form = $request->request->all(key: 'login');
|
||||
$login = $form['login'];
|
||||
$plaintextPassword = $form['password'];
|
||||
$rememberMe = isset($form['_remember_me']) ? true : false;
|
||||
$session = $request->getSession();
|
||||
try {
|
||||
$datas = $this->sqlLoginService->fetchPasswordAndDatas($login);
|
||||
} catch (EmptyResultException $e) {
|
||||
$session->set(self::ERROR_LOGIN, true);
|
||||
throw new AuthenticationException();
|
||||
} catch (DataToFetchConfigurationException|PDOException $e) {
|
||||
} catch (DataToFetchConfigurationException|\PDOException $e) {
|
||||
\Sentry\captureException($e);
|
||||
$session->set(self::TECHNICAL_ERROR, true);
|
||||
throw new AuthenticationException();
|
||||
@ -101,14 +94,18 @@ class SQLLoginUserAuthenticator extends AbstractLoginFormAuthenticator
|
||||
$session->set(self::TECHNICAL_ERROR, true);
|
||||
throw new AuthenticationException();
|
||||
}
|
||||
$user = new User($login, $remoteHashedPassword, $datas, $rememberMe);
|
||||
$loader = function (string $userIdentifier) use ($user) {
|
||||
return $user->getLogin() == $userIdentifier ? $user : null;
|
||||
|
||||
$user = new User($login, $remoteHashedPassword, $datas);
|
||||
|
||||
$loader = function (string $userIdentifier) use ($user): UserInterface {
|
||||
if ($user->getLogin() !== $userIdentifier) {
|
||||
throw new UserNotFoundException(sprintf('User "%s" not found.', $userIdentifier));
|
||||
}
|
||||
|
||||
return $user;
|
||||
};
|
||||
|
||||
$passport = new SelfValidatingPassport(new UserBadge($login, $loader));
|
||||
if ($rememberMe) {
|
||||
$passport->addBadge(new RememberMeBadge());
|
||||
}
|
||||
$passport->setAttribute('attributes', $user->getAttributes());
|
||||
|
||||
return $passport;
|
||||
|
@ -3,45 +3,48 @@
|
||||
namespace App\Security;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Service\SQLLoginService;
|
||||
use App\SQLLogin\SQLLoginRequest;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||
|
||||
class SQLLoginUserProvider implements UserProviderInterface
|
||||
{
|
||||
protected RequestStack $requestStack;
|
||||
|
||||
public function __construct(RequestStack $requestStack)
|
||||
{
|
||||
$this->requestStack = $requestStack;
|
||||
public function __construct(
|
||||
private readonly RequestStack $requestStack,
|
||||
private readonly SQLLoginService $sqlLoginService,
|
||||
private readonly SQLLoginRequest $sqlLoginRequest
|
||||
){
|
||||
}
|
||||
|
||||
public function loadUserByIdentifier(string $identifier, ?User $user): ?UserInterface
|
||||
public function loadUserByIdentifier(string $identifier): UserInterface
|
||||
{
|
||||
if ($user->getUserIdentifier() === $identifier) {
|
||||
return $user;
|
||||
$user = $this->sqlLoginService->fetchPasswordAndDatas($identifier);
|
||||
|
||||
$attributes = $user;
|
||||
unset($attributes[$this->sqlLoginRequest->getPasswordColumnName()]);
|
||||
|
||||
if (empty($user[$this->sqlLoginRequest->getLoginColumnName()]) || empty($user[$this->sqlLoginRequest->getPasswordColumnName()])) {
|
||||
throw new UserNotFoundException('email or password not found');
|
||||
}
|
||||
|
||||
return null;
|
||||
return new User($user[$this->sqlLoginRequest->getLoginColumnName()], $user[$this->sqlLoginRequest->getPasswordColumnName()], $attributes);
|
||||
}
|
||||
|
||||
public function loadUserByUsername(string $username): ?UserInterface
|
||||
{
|
||||
return $this->loadUserByIdentifier($username, null);
|
||||
}
|
||||
|
||||
public function refreshUser(UserInterface $user): UserInterface|null
|
||||
public function refreshUser(UserInterface $user): UserInterface
|
||||
{
|
||||
if (!$user instanceof User) {
|
||||
throw new UnsupportedUserException(sprintf('Invalid user class "%s".', get_class($user)));
|
||||
}
|
||||
|
||||
return $this->loadUserByIdentifier($user->getUserIdentifier(), $user);
|
||||
return $this->loadUserByIdentifier($user->getUserIdentifier());
|
||||
}
|
||||
|
||||
public function supportsClass(string $class): bool
|
||||
{
|
||||
return User::class === $class || is_subclass_of($class, User::class);
|
||||
return User::class === $class || \is_subclass_of($class, User::class);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use App\SQLLogin\SQLLoginRequest;
|
||||
use PDO;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
class SQLLoginService extends AbstractController
|
||||
{
|
||||
@ -21,6 +22,9 @@ class SQLLoginService extends AbstractController
|
||||
$this->loggerInterface = $loggerInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,string>
|
||||
*/
|
||||
public function fetchPasswordAndDatas(string $login): array
|
||||
{
|
||||
$dataRequest = $this->sqlLoginRequest->getDatasRequest();
|
||||
@ -30,6 +34,9 @@ class SQLLoginService extends AbstractController
|
||||
return $datas;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,string>
|
||||
*/
|
||||
private function executeRequestWithLogin(string $request, string $login): array
|
||||
{
|
||||
$attempt = 0;
|
||||
|
Reference in New Issue
Block a user