diff --git a/src/Controller/SecurityController.php b/src/Controller/SecurityController.php index 08a0c76..cb525c5 100644 --- a/src/Controller/SecurityController.php +++ b/src/Controller/SecurityController.php @@ -36,9 +36,21 @@ class SecurityController extends AbstractController $loginForm->get('password')->addError(new FormError($trans->trans('error.password', [], 'messages'))); $request->getSession()->remove(SQLLoginUserAuthenticator::ERROR_PASSWORD); } - if ($request->getSession()->has(SQLLoginUserAuthenticator::ERROR_SQL_LOGIN)) { - $loginForm->addError(new FormError($trans->trans('error.sql_login', [], 'messages'))); - $request->getSession()->remove(SQLLoginUserAuthenticator::ERROR_SQL_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)) { + $loginForm->addError(new FormError($trans->trans('error.configuration', [], 'messages'))); + $request->getSession()->remove(SQLLoginUserAuthenticator::ERROR_CONFIGURATION); + } + if ($request->getSession()->has(SQLLoginUserAuthenticator::ERROR_DATA_TO_FETCH_CONFIGURATION)) { + $loginForm->addError(new FormError($trans->trans('error.data_to_fetch_configuration', [], 'messages'))); + $request->getSession()->remove(SQLLoginUserAuthenticator::ERROR_DATA_TO_FETCH_CONFIGURATION); + } + if ($request->getSession()->has(SQLLoginUserAuthenticator::ERROR_SECURITY_PATTERN_CONFIGURATION)) { + $loginForm->addError(new FormError($trans->trans('error.security_pattern_configuration', [], 'messages'))); + $request->getSession()->remove(SQLLoginUserAuthenticator::ERROR_SECURITY_PATTERN_CONFIGURATION); } } diff --git a/src/SQLLogin/Exception/InvalidSQLLoginConfigurationException.php b/src/SQLLogin/Exception/DataToFetchConfigurationException.php similarity index 50% rename from src/SQLLogin/Exception/InvalidSQLLoginConfigurationException.php rename to src/SQLLogin/Exception/DataToFetchConfigurationException.php index 156abf7..7b09626 100644 --- a/src/SQLLogin/Exception/InvalidSQLLoginConfigurationException.php +++ b/src/SQLLogin/Exception/DataToFetchConfigurationException.php @@ -4,6 +4,6 @@ namespace App\SQLLogin\Exception; use Exception; -class InvalidSQLLoginConfigurationException extends Exception +class DataToFetchConfigurationException extends Exception { } diff --git a/src/SQLLogin/Exception/DatabaseConnectionException.php b/src/SQLLogin/Exception/DatabaseConnectionException.php new file mode 100644 index 0000000..770ea6b --- /dev/null +++ b/src/SQLLogin/Exception/DatabaseConnectionException.php @@ -0,0 +1,9 @@ +config[self::DATA_TO_FETCH] as $data) { - $scope .= $data.','; - } - $scope = substr($scope, 0, -1); + if ($this->config[self::DATA_TO_FETCH]) { + foreach ($this->config[self::DATA_TO_FETCH] as $data) { + $scope .= $data.','; + } + // On enlève la dernière virgule + $scope = substr($scope, 0, -1); - return 'SELECT '.$scope.' FROM '.$this->getTableName().' WHERE '.$this->getLoginColumnName().' = :'.$this->getLoginColumnName().';'; + return 'SELECT '.$scope.' FROM '.$this->getTableName().' WHERE '.$this->getLoginColumnName().' = :'.$this->getLoginColumnName().';'; + } + throw new NullDataToFetchException(); } /** * Construction de la string pour la requête préparée selon la configuration yaml * intègre la récupération du mot de passe hashé, du salt et de besoin d'upgrade de la méthode de hashage */ - public function getRequestPassword() + public function getRequestPassword(): string { $fields = $this->getPasswordColumnName(); if (!empty($this->getSaltColumnName())) { diff --git a/src/Security/Hasher/PasswordEncoder.php b/src/Security/Hasher/PasswordEncoder.php index c2d725a..91ffa7b 100644 --- a/src/Security/Hasher/PasswordEncoder.php +++ b/src/Security/Hasher/PasswordEncoder.php @@ -2,8 +2,9 @@ namespace App\Security\Hasher; -use App\SQLLogin\Exception\InvalidSQLLoginConfigurationException; use App\SQLLogin\Exception\InvalidSQLPasswordException; +use App\SQLLogin\Exception\SecurityPatternConfigurationException; +use Psr\Log\LoggerInterface; use Symfony\Component\PasswordHasher\Exception\InvalidPasswordException; use Symfony\Component\PasswordHasher\Hasher\CheckPasswordLengthTrait; use Symfony\Component\PasswordHasher\LegacyPasswordHasherInterface; @@ -19,7 +20,7 @@ class PasswordEncoder implements LegacyPasswordHasherInterface protected array $hashAlgoLegacy; protected array $securityPattern; - public function __construct(?string $pepper, string $hashAlgoLegacy, string $securityPattern) + public function __construct(?string $pepper, string $hashAlgoLegacy, string $securityPattern, private LoggerInterface $loggerInterface) { $this->pepper = $pepper; $this->hashAlgoLegacy = explode(',', $hashAlgoLegacy); @@ -88,7 +89,8 @@ class PasswordEncoder implements LegacyPasswordHasherInterface foreach ($this->securityPattern as $term) { if (self::PEPPER_PATTERN !== $term && self::PASSWORD_PATTERN !== $term && self::SALT_PATTERN !== $term) { - throw new InvalidSQLLoginConfigurationException(); + $this->loggerInterface->critical('La configuration du security pattern est invalide, les termes autorisés sont : '.self::PASSWORD_PATTERN.', '.self::SALT_PATTERN.' et '.self::PEPPER_PATTERN); + throw new SecurityPatternConfigurationException(); } } $completedPlainPassword = ''; diff --git a/src/Security/SQLLoginUserAuthenticator.php b/src/Security/SQLLoginUserAuthenticator.php index 1d3394e..842ad16 100644 --- a/src/Security/SQLLoginUserAuthenticator.php +++ b/src/Security/SQLLoginUserAuthenticator.php @@ -5,8 +5,11 @@ namespace App\Security; use App\Entity\User; use App\Security\Hasher\PasswordEncoder; use App\Service\SQLLoginService; +use App\SQLLogin\Exception\DatabaseConnectionException; +use App\SQLLogin\Exception\DataToFetchConfigurationException; use App\SQLLogin\Exception\InvalidSQLPasswordException; -use PDOException; +use App\SQLLogin\Exception\LoginElementsConfigurationException; +use App\SQLLogin\Exception\SecurityPatternConfigurationException; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -24,7 +27,11 @@ class SQLLoginUserAuthenticator extends AbstractLoginFormAuthenticator public const LOGIN_ROUTE = 'app_login'; public const ERROR_LOGIN = 'error_login'; public const ERROR_PASSWORD = 'error_password'; + public const ERROR_PDO = 'error_pdo'; public const ERROR_SQL_LOGIN = 'error_sql_login'; + public const ERROR_CONFIGURATION = 'error_configuration'; + public const ERROR_DATA_TO_FETCH_CONFIGURATION = 'error_data_to_fetch_configuration'; + public const ERROR_SECURITY_PATTERN_CONFIGURATION = 'error_security_pattern_configuration'; protected string $baseUrl; private SQLLoginService $sqlLoginService; @@ -65,11 +72,15 @@ class SQLLoginUserAuthenticator extends AbstractLoginFormAuthenticator $login = $form['login']; $plaintextPassword = $form['password']; $rememberMe = isset($form['_remember_me']) ? true : false; + $session = $request->getSession(); try { // requête préparée list($remoteHashedPassword, $remoteSalt) = $this->sqlLoginService->fetchPassword($login); - } catch (PDOException $e) { - $request->getSession()->set(self::ERROR_SQL_LOGIN, true); + } catch (DatabaseConnectionException $e) { + $session->set(self::ERROR_PDO, true); + throw new AuthenticationException(); + } catch (LoginElementsConfigurationException $e) { + $session->set(self::ERROR_CONFIGURATION, true); throw new AuthenticationException(); } if ($remoteHashedPassword) { @@ -90,10 +101,16 @@ class SQLLoginUserAuthenticator extends AbstractLoginFormAuthenticator return $passport; } catch (InvalidSQLPasswordException $e) { - $request->getSession()->set(self::ERROR_PASSWORD, true); + $session->set(self::ERROR_PASSWORD, true); throw new AuthenticationException(); - } catch (PDOException $e) { - $request->getSession()->set(self::ERROR_SQL_LOGIN, true); + } catch (DataToFetchConfigurationException $e) { + $session->set(self::ERROR_DATA_TO_FETCH_CONFIGURATION, true); + throw new AuthenticationException(); + } catch (DatabaseConnectionException $e) { + $session->set(self::ERROR_PDO, true); + throw new AuthenticationException(); + } catch (SecurityPatternConfigurationException $e) { + $session->set(self::ERROR_SECURITY_PATTERN_CONFIGURATION, true); throw new AuthenticationException(); } } diff --git a/src/Service/SQLLoginService.php b/src/Service/SQLLoginService.php index 2e1d549..6b90546 100644 --- a/src/Service/SQLLoginService.php +++ b/src/Service/SQLLoginService.php @@ -2,6 +2,10 @@ namespace App\Service; +use App\SQLLogin\Exception\DatabaseConnectionException; +use App\SQLLogin\Exception\DataToFetchConfigurationException; +use App\SQLLogin\Exception\LoginElementsConfigurationException; +use App\SQLLogin\Exception\NullDataToFetchException; use App\SQLLogin\SQLLoginConnect; use App\SQLLogin\SQLLoginRequest; use PDO; @@ -23,16 +27,25 @@ class SQLLoginService extends AbstractController { try { $dbh = $this->getConnection(); + } catch (PDOException $e) { + $this->loggerInterface->critical($e->getMessage()); + throw new DatabaseConnectionException($e->getMessage()); + } + try { // forge de la requête $request = $this->sqlLoginRequest->getRequestScope(); + } catch (NullDataToFetchException $e) { + throw new DataToFetchConfigurationException($e->getMessage()); + } + + try { // Préparation de la requête $query = $dbh->prepare($request); $query->execute([$this->sqlLoginRequest->getLoginColumnName() => $login]); $datas = $query->fetch(PDO::FETCH_ASSOC); } catch (PDOException $e) { - \Sentry\captureException($e); $this->loggerInterface->critical($e->getMessage()); - throw new PDOException(); + throw new DataToFetchConfigurationException($e->getMessage()); } return $datas; @@ -42,13 +55,21 @@ class SQLLoginService extends AbstractController { try { $dbh = $this->getConnection(); - $request = $this->sqlLoginRequest->getRequestPassword(); + } catch (PDOException $e) { + $this->loggerInterface->critical($e->getMessage()); + throw new DatabaseConnectionException($e->getMessage()); + } + + // forge de la requête + $request = $this->sqlLoginRequest->getRequestPassword(); + + try { $query = $dbh->prepare($request); $query->execute([$this->sqlLoginRequest->getLoginColumnName() => $login]); $password = $query->fetch(PDO::FETCH_ASSOC); } catch (PDOException $e) { $this->loggerInterface->critical($e->getMessage()); - throw new PDOException(); + throw new LoginElementsConfigurationException($e->getMessage()); } if ($password) { return [ diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index f04251d..6df1993 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -21,6 +21,18 @@ error.pdo Connection to database encountered a problem + + error.configuration + Identification data references do not exist in the database + + + error.data_to_fetch_configuration + Data references to be transmitted do not exist + + + error.security_pattern_configuration + The security pattern is not allowed + diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf index b3caf24..662608c 100644 --- a/translations/messages.fr.xlf +++ b/translations/messages.fr.xlf @@ -19,7 +19,19 @@ error.pdo - La connexion à la base de déonnées à rencontré un problème + La connexion à la base de données a rencontré un problème + + + error.configuration + Les références de données d'identification n'existent pas dans la base de données + + + error.data_to_fetch_configuration + Les références de données à transmettre n'existent pas + + + error.security_pattern_configuration + Le patron de sécurité n'est pas autorisé