fix login sql : ajout d'un retry sur le login, suppression des options #45
|
@ -32,10 +32,6 @@ class SecurityController extends AbstractController
|
||||||
$loginForm->addError(new FormError($trans->trans('error.login', [], 'messages')));
|
$loginForm->addError(new FormError($trans->trans('error.login', [], 'messages')));
|
||||||
$request->getSession()->remove(SQLLoginUserAuthenticator::ERROR_LOGIN);
|
$request->getSession()->remove(SQLLoginUserAuthenticator::ERROR_LOGIN);
|
||||||
}
|
}
|
||||||
if ($request->getSession()->has(SQLLoginUserAuthenticator::ERROR_PDO)) {
|
|
||||||
$loginForm->addError(new FormError($trans->trans('error.pdo', [], 'messages')));
|
|
||||||
$request->getSession()->remove(SQLLoginUserAuthenticator::ERROR_PDO);
|
|
||||||
}
|
|
||||||
if ($request->getSession()->has(SQLLoginUserAuthenticator::ERROR_CONFIGURATION)) {
|
if ($request->getSession()->has(SQLLoginUserAuthenticator::ERROR_CONFIGURATION)) {
|
||||||
$loginForm->addError(new FormError($trans->trans('error.configuration', [], 'messages')));
|
$loginForm->addError(new FormError($trans->trans('error.configuration', [], 'messages')));
|
||||||
$request->getSession()->remove(SQLLoginUserAuthenticator::ERROR_CONFIGURATION);
|
$request->getSession()->remove(SQLLoginUserAuthenticator::ERROR_CONFIGURATION);
|
||||||
|
|
|
@ -3,14 +3,20 @@
|
||||||
namespace App\Hydra;
|
namespace App\Hydra;
|
||||||
|
|
||||||
use App\Hydra\Exception\InvalidChallengeException;
|
use App\Hydra\Exception\InvalidChallengeException;
|
||||||
|
use Exception;
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
use Symfony\Contracts\HttpClient\ResponseInterface;
|
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||||
|
|
||||||
class Client
|
class Client
|
||||||
{
|
{
|
||||||
protected $client;
|
private HttpClientInterface $client;
|
||||||
|
private const MAX_RETRY = 3;
|
||||||
protected $hydraAdminBaseUrl;
|
private const SLEEP_TIME = [
|
||||||
|
5,
|
||||||
|
500,
|
||||||
|
5000,
|
||||||
|
];
|
||||||
|
private string $hydraAdminBaseUrl;
|
||||||
|
|
||||||
public function __construct(HttpClientInterface $client, string $hydraAdminBaseUrl)
|
public function __construct(HttpClientInterface $client, string $hydraAdminBaseUrl)
|
||||||
{
|
{
|
||||||
|
@ -26,7 +32,7 @@ class Client
|
||||||
[
|
[
|
||||||
'query' => [
|
'query' => [
|
||||||
'login_challenge' => $loginChallenge,
|
'login_challenge' => $loginChallenge,
|
||||||
]
|
],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -35,7 +41,6 @@ class Client
|
||||||
throw new InvalidChallengeException();
|
throw new InvalidChallengeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +52,7 @@ class Client
|
||||||
[
|
[
|
||||||
'query' => [
|
'query' => [
|
||||||
'logout_challenge' => $logoutChallenge,
|
'logout_challenge' => $logoutChallenge,
|
||||||
]
|
],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -56,27 +61,38 @@ class Client
|
||||||
throw new InvalidChallengeException();
|
throw new InvalidChallengeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fetchConsentRequestInfo(string $consentChallenge): ResponseInterface
|
public function fetchConsentRequestInfo(string $consentChallenge): ResponseInterface
|
||||||
{
|
{
|
||||||
|
$attempt = 0;
|
||||||
|
while ($attempt < self::MAX_RETRY) {
|
||||||
$response = $this->client->request(
|
$response = $this->client->request(
|
||||||
'GET',
|
'GET',
|
||||||
$this->hydraAdminBaseUrl.'/oauth2/auth/requests/consent',
|
$this->hydraAdminBaseUrl.'/oauth2/auth/requests/consent',
|
||||||
[
|
[
|
||||||
'query' => [
|
'query' => [
|
||||||
'consent_challenge' => $consentChallenge,
|
'consent_challenge' => $consentChallenge,
|
||||||
]
|
],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
switch ($response->getStatusCode()) {
|
$status = $response->getStatusCode();
|
||||||
|
if (503 === $status) {
|
||||||
|
++$attempt;
|
||||||
|
usleep(1000 * self::SLEEP_TIME[$attempt] + rand(1, 5) * 1000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch ($status) {
|
||||||
case 404:
|
case 404:
|
||||||
throw new InvalidChallengeException();
|
throw new InvalidChallengeException();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (self::MAX_RETRY === $attempt) {
|
||||||
|
throw new Exception(sprintf('Fetch consent a rencontré une erreur %s après %s tentatives', $response->getStatusCode(), self::MAX_RETRY));
|
||||||
|
}
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
@ -91,7 +107,7 @@ class Client
|
||||||
'login_challenge' => $loginChallenge,
|
'login_challenge' => $loginChallenge,
|
||||||
],
|
],
|
||||||
'headers' => [
|
'headers' => [
|
||||||
'Content-Type' => 'application/json'
|
'Content-Type' => 'application/json',
|
||||||
],
|
],
|
||||||
'body' => json_encode($payload),
|
'body' => json_encode($payload),
|
||||||
]
|
]
|
||||||
|
@ -110,7 +126,7 @@ class Client
|
||||||
'consent_challenge' => $consentChallenge,
|
'consent_challenge' => $consentChallenge,
|
||||||
],
|
],
|
||||||
'headers' => [
|
'headers' => [
|
||||||
'Content-Type' => 'application/json'
|
'Content-Type' => 'application/json',
|
||||||
],
|
],
|
||||||
'body' => json_encode($payload),
|
'body' => json_encode($payload),
|
||||||
]
|
]
|
||||||
|
@ -129,7 +145,7 @@ class Client
|
||||||
'logout_challenge' => $logoutChallenge,
|
'logout_challenge' => $logoutChallenge,
|
||||||
],
|
],
|
||||||
'headers' => [
|
'headers' => [
|
||||||
'Content-Type' => 'application/json'
|
'Content-Type' => 'application/json',
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,11 +5,9 @@ namespace App\Security;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Security\Hasher\PasswordEncoder;
|
use App\Security\Hasher\PasswordEncoder;
|
||||||
use App\Service\SQLLoginService;
|
use App\Service\SQLLoginService;
|
||||||
use App\SQLLogin\Exception\DatabaseConnectionException;
|
|
||||||
use App\SQLLogin\Exception\DataToFetchConfigurationException;
|
use App\SQLLogin\Exception\DataToFetchConfigurationException;
|
||||||
use App\SQLLogin\Exception\EmptyResultException;
|
use App\SQLLogin\Exception\EmptyResultException;
|
||||||
use App\SQLLogin\Exception\InvalidSQLPasswordException;
|
use App\SQLLogin\Exception\InvalidSQLPasswordException;
|
||||||
use App\SQLLogin\Exception\LoginElementsConfigurationException;
|
|
||||||
use App\SQLLogin\Exception\SecurityPatternConfigurationException;
|
use App\SQLLogin\Exception\SecurityPatternConfigurationException;
|
||||||
use App\SQLLogin\SQLLoginRequest;
|
use App\SQLLogin\SQLLoginRequest;
|
||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
|
@ -87,12 +85,6 @@ class SQLLoginUserAuthenticator extends AbstractLoginFormAuthenticator
|
||||||
} catch (EmptyResultException $e) {
|
} catch (EmptyResultException $e) {
|
||||||
$session->set(self::ERROR_LOGIN, true);
|
$session->set(self::ERROR_LOGIN, true);
|
||||||
throw new AuthenticationException();
|
throw new AuthenticationException();
|
||||||
} catch (DatabaseConnectionException $e) {
|
|
||||||
$session->set(self::ERROR_PDO, true);
|
|
||||||
throw new AuthenticationException();
|
|
||||||
} catch (LoginElementsConfigurationException $e) {
|
|
||||||
$session->set(self::ERROR_CONFIGURATION, true);
|
|
||||||
throw new AuthenticationException();
|
|
||||||
} catch (DataToFetchConfigurationException $e) {
|
} catch (DataToFetchConfigurationException $e) {
|
||||||
$session->set(self::ERROR_DATA_TO_FETCH_CONFIGURATION, true);
|
$session->set(self::ERROR_DATA_TO_FETCH_CONFIGURATION, true);
|
||||||
throw new AuthenticationException();
|
throw new AuthenticationException();
|
||||||
|
|
|
@ -2,22 +2,18 @@
|
||||||
|
|
||||||
namespace App\Service;
|
namespace App\Service;
|
||||||
|
|
||||||
use App\SQLLogin\Exception\DatabaseConnectionException;
|
|
||||||
use App\SQLLogin\Exception\DataToFetchConfigurationException;
|
use App\SQLLogin\Exception\DataToFetchConfigurationException;
|
||||||
use App\SQLLogin\Exception\EmptyResultException;
|
use App\SQLLogin\Exception\EmptyResultException;
|
||||||
use App\SQLLogin\Exception\LoginElementsConfigurationException;
|
|
||||||
use App\SQLLogin\Exception\NullDataToFetchException;
|
use App\SQLLogin\Exception\NullDataToFetchException;
|
||||||
use App\SQLLogin\SQLLoginConnect;
|
use App\SQLLogin\SQLLoginConnect;
|
||||||
use App\SQLLogin\SQLLoginRequest;
|
use App\SQLLogin\SQLLoginRequest;
|
||||||
use PDO;
|
use PDO;
|
||||||
use PDOException;
|
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
|
||||||
class SQLLoginService extends AbstractController
|
class SQLLoginService extends AbstractController
|
||||||
{
|
{
|
||||||
public const MAX_RETRY = 3;
|
public const MAX_RETRY = 3;
|
||||||
private PDO $pdo;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private SQLLoginRequest $sqlLoginRequest,
|
private SQLLoginRequest $sqlLoginRequest,
|
||||||
|
@ -25,7 +21,6 @@ class SQLLoginService extends AbstractController
|
||||||
) {
|
) {
|
||||||
$this->sqlLoginRequest = $sqlLoginRequest;
|
$this->sqlLoginRequest = $sqlLoginRequest;
|
||||||
$this->loggerInterface = $loggerInterface;
|
$this->loggerInterface = $loggerInterface;
|
||||||
$this->pdo = $this->getConnection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fetchPasswordAndDatas(string $login): array
|
public function fetchPasswordAndDatas(string $login): array
|
||||||
|
@ -35,9 +30,6 @@ class SQLLoginService extends AbstractController
|
||||||
$datas = $this->executeRequestWithLogin($dataRequest, $login);
|
$datas = $this->executeRequestWithLogin($dataRequest, $login);
|
||||||
} catch (NullDataToFetchException $e) {
|
} catch (NullDataToFetchException $e) {
|
||||||
throw new DataToFetchConfigurationException($e->getMessage());
|
throw new DataToFetchConfigurationException($e->getMessage());
|
||||||
} catch (PDOException $e) {
|
|
||||||
$this->loggerInterface->critical($e->getMessage());
|
|
||||||
throw new LoginElementsConfigurationException($e->getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $datas;
|
return $datas;
|
||||||
|
@ -47,7 +39,8 @@ class SQLLoginService extends AbstractController
|
||||||
{
|
{
|
||||||
$attempt = 0;
|
$attempt = 0;
|
||||||
while ($attempt < self::MAX_RETRY) {
|
while ($attempt < self::MAX_RETRY) {
|
||||||
$query = $this->pdo->prepare($request);
|
$pdo = $this->getConnection();
|
||||||
|
$query = $pdo->prepare($request);
|
||||||
$query->execute([$this->sqlLoginRequest->getLoginColumnName() => $login]);
|
$query->execute([$this->sqlLoginRequest->getLoginColumnName() => $login]);
|
||||||
$datas = $query->fetch(PDO::FETCH_ASSOC);
|
$datas = $query->fetch(PDO::FETCH_ASSOC);
|
||||||
$query->closeCursor();
|
$query->closeCursor();
|
||||||
|
@ -68,13 +61,8 @@ class SQLLoginService extends AbstractController
|
||||||
private function getConnection(): PDO
|
private function getConnection(): PDO
|
||||||
{
|
{
|
||||||
// Appel du singleton
|
// Appel du singleton
|
||||||
try {
|
|
||||||
$sqlLogin = SQLLoginConnect::getInstance();
|
$sqlLogin = SQLLoginConnect::getInstance();
|
||||||
$pdo = $sqlLogin->connect($this->sqlLoginRequest->getDatabaseDsn(), $this->sqlLoginRequest->getDbUser(), $this->sqlLoginRequest->getDbPassword());
|
$pdo = $sqlLogin->connect($this->sqlLoginRequest->getDatabaseDsn(), $this->sqlLoginRequest->getDbUser(), $this->sqlLoginRequest->getDbPassword());
|
||||||
} catch (PDOException $e) {
|
|
||||||
$this->loggerInterface->critical($e->getMessage());
|
|
||||||
throw new DatabaseConnectionException($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return $pdo;
|
return $pdo;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue