traductions, sentry, form, mariadb, assets
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:
20
src/Controller/LocaleController.php
Normal file
20
src/Controller/LocaleController.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class LocaleController extends AbstractController
|
||||
{
|
||||
#[Route(path: 'locale/{locale}', name: 'locale_change')]
|
||||
public function changeLocal(string $locale, Request $request)
|
||||
{
|
||||
// On stocke la langue dans la session
|
||||
$request->getSession()->set('_locale', $locale);
|
||||
|
||||
// redirection
|
||||
return $this->redirect($request->headers->get('referer'));
|
||||
}
|
||||
}
|
@ -24,17 +24,13 @@ class MainController extends AbstractController
|
||||
$this->hydra = $hydra;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/", name="app_home")
|
||||
*/
|
||||
#[Route('/', name: 'app_home')]
|
||||
public function home(Request $request)
|
||||
{
|
||||
return $this->hydra->handleLoginRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/connect/login-accept", name="app_login_accept")
|
||||
*/
|
||||
#[Route('/connect/login-accept', name: 'app_login_accept')]
|
||||
public function loginAccept(Request $request)
|
||||
{
|
||||
/** @var User */
|
||||
@ -47,9 +43,7 @@ class MainController extends AbstractController
|
||||
return new RedirectResponse($loginAcceptRes['redirect_to']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/connect/consent", name="app_consent")
|
||||
*/
|
||||
#[Route('/connect/consent', name: 'app_consent')]
|
||||
public function consent(Request $request)
|
||||
{
|
||||
return $this->hydra->handleConsentRequest($request);
|
||||
|
@ -2,32 +2,52 @@
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Form\LoginType;
|
||||
use App\Security\PdoUserAuthenticator;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class SecurityController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @Route("/login", name="app_login")
|
||||
*/
|
||||
public function login(AuthenticationUtils $authenticationUtils): Response
|
||||
#[Route('/login', name: 'app_login')]
|
||||
public function login(ParameterBagInterface $params, AuthenticationUtils $authenticationUtils, Request $request, TranslatorInterface $trans): Response
|
||||
{
|
||||
// get the login error if there is one
|
||||
// Si l'utilisateur est déjà connecté on le renvoie sur la page du site demandeur
|
||||
if ($this->getUser()) {
|
||||
return new RedirectResponse($params->get('issuer_url'));
|
||||
}
|
||||
|
||||
// On fournit le form, mais il est traité par un authenticator
|
||||
$loginForm = $this->createForm(LoginType::class, null);
|
||||
$error = $authenticationUtils->getLastAuthenticationError();
|
||||
if ($error) {
|
||||
if ($request->getSession()->has(PdoUserAuthenticator::ERROR_LOGIN)) {
|
||||
$loginForm->get('login')->addError(new FormError($trans->trans('error.login', [], 'messages')));
|
||||
$request->getSession()->remove(PdoUserAuthenticator::ERROR_LOGIN);
|
||||
}
|
||||
if ($request->getSession()->has(PdoUserAuthenticator::ERROR_PASSWORD)) {
|
||||
$loginForm->get('password')->addError(new FormError($trans->trans('error.password', [], 'messages')));
|
||||
$request->getSession()->remove(PdoUserAuthenticator::ERROR_PASSWORD);
|
||||
}
|
||||
if ($request->getSession()->has(PdoUserAuthenticator::ERROR_PDO)) {
|
||||
$loginForm->addError(new FormError($trans->trans('error.pdo', [], 'messages')));
|
||||
$request->getSession()->remove(PdoUserAuthenticator::ERROR_PDO);
|
||||
}
|
||||
}
|
||||
// last username entered by the user
|
||||
$lastUsername = $authenticationUtils->getLastUsername();
|
||||
|
||||
return $this->render('login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
|
||||
return $this->render('login.html.twig', [
|
||||
'loginForm' => $loginForm->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/logout", name="app_logout")
|
||||
*/
|
||||
#[Route('/logout', name: 'logout')]
|
||||
public function logout(Request $request)
|
||||
{
|
||||
}
|
||||
|
41
src/EventListener/LocaleSubscriber.php
Normal file
41
src/EventListener/LocaleSubscriber.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\EventListener;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
class LocaleSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
// Langue par défaut
|
||||
private string $defaultLocale;
|
||||
|
||||
public function __construct(string $defaultLocale)
|
||||
{
|
||||
$this->defaultLocale = $defaultLocale;
|
||||
}
|
||||
|
||||
public function onKernelRequest(RequestEvent $event)
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
if (!$request->hasPreviousSession()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// On vérifie si la langue est passée en paramètre de l'URL
|
||||
if ($locale = $request->query->get('_locale')) {
|
||||
$request->setLocale($locale);
|
||||
} else {
|
||||
// Sinon on utilise celle de la session
|
||||
$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
|
||||
}
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
KernelEvents::REQUEST => [['onKernelRequest', 20]],
|
||||
];
|
||||
}
|
||||
}
|
@ -27,10 +27,11 @@ class LogoutSubscriber implements EventSubscriberInterface
|
||||
$request = $event->getRequest();
|
||||
|
||||
// get the current response, if it is already set by another listener
|
||||
$response = $event->getResponse();
|
||||
|
||||
$request->getSession()->clear();
|
||||
$request->getSession()->invalidate();
|
||||
// configure a custom logout response to the homepage
|
||||
$response = $this->hydra->handleLogoutRequest($request);
|
||||
|
||||
$event->setResponse($response);
|
||||
}
|
||||
}
|
||||
|
39
src/Form/LoginType.php
Normal file
39
src/Form/LoginType.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class LoginType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('login', TextType::class, [
|
||||
'translation_domain' => 'form',
|
||||
'label' => 'form.label.login',
|
||||
])
|
||||
->add('password', PasswordType::class, [
|
||||
'translation_domain' => 'form',
|
||||
'label' => 'form.label.password',
|
||||
])
|
||||
->add('_remember_me', CheckboxType::class, [
|
||||
'required' => false,
|
||||
'translation_domain' => 'form',
|
||||
'label' => 'form.label.remember_me',
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => null,
|
||||
]);
|
||||
}
|
||||
}
|
@ -78,7 +78,7 @@ class HydraService extends AbstractController
|
||||
$logoutRequestInfo = $this->client->fetchLogoutRequestInfo($logoutChallenge)->toArray();
|
||||
$logoutAcceptRes = $this->client->acceptLogoutRequest($logoutRequestInfo['challenge'])->toArray();
|
||||
$this->session->clear();
|
||||
$this->tokenStorage->setToken();
|
||||
$this->tokenStorage->setToken(null);
|
||||
|
||||
return new RedirectResponse($logoutAcceptRes['redirect_to']);
|
||||
}
|
||||
|
@ -4,10 +4,8 @@ namespace App;
|
||||
|
||||
use App\DependencyInjection\PdoExtension;
|
||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
|
||||
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
|
||||
|
||||
class Kernel extends BaseKernel
|
||||
@ -25,6 +23,7 @@ class Kernel extends BaseKernel
|
||||
|
||||
$loader->load(function (ContainerBuilder $container) use ($loader) {
|
||||
$envLanguage = \getenv('APP_LOCALES');
|
||||
$container->setParameter('app.supported_locales', explode(',', $envLanguage));
|
||||
$container->registerExtension(new PdoExtension());
|
||||
$loader->load($this->getConfigDir().'/pdo_configuration/*.{yml,yaml}', 'glob');
|
||||
});
|
||||
|
9
src/Pdo/Exception/InvalidLoginException.php
Normal file
9
src/Pdo/Exception/InvalidLoginException.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Pdo\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
class InvalidLoginException extends Exception
|
||||
{
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Pdo\Exception;
|
||||
|
||||
class InvalidPasswordException
|
||||
use Exception;
|
||||
|
||||
class InvalidPasswordException extends Exception
|
||||
{
|
||||
}
|
||||
|
@ -3,16 +3,16 @@
|
||||
namespace App\Security;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Hydra\Client;
|
||||
use App\Pdo\Exception\InvalidPasswordException;
|
||||
use App\Services\PdoService;
|
||||
use PDOException;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
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\Http\Authenticator\AbstractAuthenticator;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
||||
@ -22,18 +22,19 @@ use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPasspor
|
||||
class PdoUserAuthenticator extends AbstractAuthenticator
|
||||
{
|
||||
public const LOGIN_ROUTE = 'app_login';
|
||||
public const ERROR_LOGIN = 'error_login';
|
||||
public const ERROR_PASSWORD = 'error_password';
|
||||
public const ERROR_PDO = 'error_pdo';
|
||||
|
||||
private PdoService $pdoService;
|
||||
protected string $baseUrl;
|
||||
private Client $client;
|
||||
private SessionInterface $session;
|
||||
private PdoService $pdoService;
|
||||
private UrlGeneratorInterface $router;
|
||||
|
||||
public function __construct(string $baseUrl, PdoService $pdoService, Client $client, SessionInterface $session)
|
||||
public function __construct(string $baseUrl, PdoService $pdoService, UrlGeneratorInterface $router)
|
||||
{
|
||||
$this->baseUrl = $baseUrl;
|
||||
$this->pdoService = $pdoService;
|
||||
$this->client = $client;
|
||||
$this->session = $session;
|
||||
$this->router = $router;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,38 +54,50 @@ class PdoUserAuthenticator extends AbstractAuthenticator
|
||||
|
||||
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
|
||||
{
|
||||
$message = strtr($exception->getMessageKey(), $exception->getMessageData());
|
||||
$request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
|
||||
|
||||
return new Response($message, Response::HTTP_FORBIDDEN);
|
||||
return new RedirectResponse(
|
||||
$this->router->generate('app_login')
|
||||
);
|
||||
}
|
||||
|
||||
public function authenticate(Request $request): Passport
|
||||
{
|
||||
$login = $request->request->get('login');
|
||||
$password = $request->request->get('password');
|
||||
$rememberMe = $request->request->get('_remember_me') ? true : false;
|
||||
$form = $request->request->get('login');
|
||||
$login = $form['login'];
|
||||
$password = $form['password'];
|
||||
$rememberMe = isset($form['_remember_me']) ? true : false;
|
||||
try {
|
||||
// requête préparée
|
||||
$remoteHashedPassword = $this->pdoService->fetchPassword($login);
|
||||
} catch (PDOException $e) {
|
||||
dd($e);
|
||||
}
|
||||
try {
|
||||
$this->pdoService->verifyPassword($password, $remoteHashedPassword);
|
||||
$attributes = $this->pdoService->fetchDatas($login);
|
||||
$user = new User($login, $password, $attributes, $rememberMe);
|
||||
$loader = function (string $userIdentifier) use ($user) {
|
||||
return $user->getLogin() == $userIdentifier ? $user : null;
|
||||
};
|
||||
$passport = new SelfValidatingPassport(new UserBadge($login, $loader));
|
||||
// if ($rememberMe) {
|
||||
// $passport->addBadge(new RememberMeBadge());
|
||||
// }
|
||||
$passport->setAttribute('attributes', $user->getAttributes());
|
||||
|
||||
return $passport;
|
||||
} catch (InvalidPasswordException $e) {
|
||||
$request->getSession()->set(self::ERROR_PDO, true);
|
||||
throw new AuthenticationException();
|
||||
}
|
||||
if ($remoteHashedPassword) {
|
||||
try {
|
||||
$this->pdoService->verifyPassword($password, $remoteHashedPassword);
|
||||
$attributes = $this->pdoService->fetchDatas($login);
|
||||
$user = new User($login, $password, $attributes, $rememberMe);
|
||||
$loader = function (string $userIdentifier) use ($user) {
|
||||
return $user->getLogin() == $userIdentifier ? $user : null;
|
||||
};
|
||||
$passport = new SelfValidatingPassport(new UserBadge($login, $loader));
|
||||
if ($rememberMe) {
|
||||
$passport->addBadge(new RememberMeBadge());
|
||||
}
|
||||
$passport->setAttribute('attributes', $user->getAttributes());
|
||||
|
||||
return $passport;
|
||||
} catch (InvalidPasswordException $e) {
|
||||
$request->getSession()->set(self::ERROR_PASSWORD, true);
|
||||
throw new AuthenticationException();
|
||||
} catch (PDOException $e) {
|
||||
$request->getSession()->set(self::ERROR_PDO, true);
|
||||
throw new AuthenticationException();
|
||||
}
|
||||
}
|
||||
$request->getSession()->set(self::ERROR_LOGIN, true);
|
||||
throw new AuthenticationException();
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,12 @@
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Pdo\Exception\InvalidPasswordException;
|
||||
use App\Pdo\PdoConnect;
|
||||
use App\Pdo\PdoRequest;
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use App\Pdo\PdoConnect;
|
||||
use App\Pdo\PdoRequest;
|
||||
use Sentry\captureException;
|
||||
use App\Pdo\Exception\InvalidPasswordException;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
|
||||
@ -34,8 +35,9 @@ class PdoService extends AbstractController
|
||||
$query->execute([$this->pdoRequest->getNameLogin() => $login]);
|
||||
$datas = $query->fetch(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $e) {
|
||||
echo 'Erreur fetch Datas !: '.$e->getMessage().'<br/>';
|
||||
exit();
|
||||
\Sentry\captureException($e);
|
||||
|
||||
throw new PDOException();
|
||||
}
|
||||
|
||||
return $datas;
|
||||
@ -55,11 +57,15 @@ class PdoService extends AbstractController
|
||||
$query->execute([$this->pdoRequest->getNameLogin() => $login]);
|
||||
$password = $query->fetch(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $e) {
|
||||
echo 'Erreur fetch Password!: '.$e->getMessage().'<br/>';
|
||||
exit();
|
||||
\Sentry\captureException($e);
|
||||
dd($e);
|
||||
throw new PDOException();
|
||||
}
|
||||
if ($password) {
|
||||
return $password[$this->pdoRequest->getNamePassword()];
|
||||
}
|
||||
|
||||
return $password[$this->pdoRequest->getNamePassword()];
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getConnection()
|
||||
|
Reference in New Issue
Block a user