optimisation appel pdo, retry consent
Cadoles/hydra-sql/pipeline/pr-develop There was a failure building this commit Details

This commit is contained in:
Rudy Masson 2024-10-11 13:25:21 +02:00
parent e3f406a8bb
commit cb8361e7d1
4 changed files with 48 additions and 56 deletions

View File

@ -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);

View File

@ -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)
{ {
@ -22,11 +28,11 @@ class Client
{ {
$response = $this->client->request( $response = $this->client->request(
'GET', 'GET',
$this->hydraAdminBaseUrl . '/oauth2/auth/requests/login', $this->hydraAdminBaseUrl.'/oauth2/auth/requests/login',
[ [
'query' => [ 'query' => [
'login_challenge' => $loginChallenge, 'login_challenge' => $loginChallenge,
] ],
] ]
); );
@ -35,7 +41,6 @@ class Client
throw new InvalidChallengeException(); throw new InvalidChallengeException();
} }
return $response; return $response;
} }
@ -43,11 +48,11 @@ class Client
{ {
$response = $this->client->request( $response = $this->client->request(
'GET', 'GET',
$this->hydraAdminBaseUrl . '/oauth2/auth/requests/logout', $this->hydraAdminBaseUrl.'/oauth2/auth/requests/logout',
[ [
'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
{ {
$response = $this->client->request( $attempt = 0;
'GET', while ($attempt < self::MAX_RETRY) {
$this->hydraAdminBaseUrl . '/oauth2/auth/requests/consent', $response = $this->client->request(
[ 'GET',
'query' => [ $this->hydraAdminBaseUrl.'/oauth2/auth/requests/consent',
'consent_challenge' => $consentChallenge, [
'query' => [
'consent_challenge' => $consentChallenge,
],
] ]
] );
);
switch ($response->getStatusCode()) { $status = $response->getStatusCode();
case 404: if (503 === $status) {
throw new InvalidChallengeException(); ++$attempt;
usleep(1000 * self::SLEEP_TIME[$attempt] + rand(1, 5) * 1000);
continue;
}
switch ($status) {
case 404:
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;
} }
@ -85,18 +101,18 @@ class Client
{ {
$response = $this->client->request( $response = $this->client->request(
'PUT', 'PUT',
$this->hydraAdminBaseUrl . '/oauth2/auth/requests/login/accept', $this->hydraAdminBaseUrl.'/oauth2/auth/requests/login/accept',
[ [
'query' => [ 'query' => [
'login_challenge' => $loginChallenge, 'login_challenge' => $loginChallenge,
], ],
'headers' => [ 'headers' => [
'Content-Type' => 'application/json' 'Content-Type' => 'application/json',
], ],
'body' => json_encode($payload), 'body' => json_encode($payload),
] ]
); );
return $response; return $response;
} }
@ -104,13 +120,13 @@ class Client
{ {
$response = $this->client->request( $response = $this->client->request(
'PUT', 'PUT',
$this->hydraAdminBaseUrl . '/oauth2/auth/requests/consent/accept', $this->hydraAdminBaseUrl.'/oauth2/auth/requests/consent/accept',
[ [
'query' => [ 'query' => [
'consent_challenge' => $consentChallenge, 'consent_challenge' => $consentChallenge,
], ],
'headers' => [ 'headers' => [
'Content-Type' => 'application/json' 'Content-Type' => 'application/json',
], ],
'body' => json_encode($payload), 'body' => json_encode($payload),
] ]
@ -123,13 +139,13 @@ class Client
{ {
$response = $this->client->request( $response = $this->client->request(
'PUT', 'PUT',
$this->hydraAdminBaseUrl . '/oauth2/auth/requests/logout/accept', $this->hydraAdminBaseUrl.'/oauth2/auth/requests/logout/accept',
[ [
'query' => [ 'query' => [
'logout_challenge' => $logoutChallenge, 'logout_challenge' => $logoutChallenge,
], ],
'headers' => [ 'headers' => [
'Content-Type' => 'application/json' 'Content-Type' => 'application/json',
], ],
] ]
); );

View File

@ -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();

View File

@ -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;
} }