<?php
namespace App\Controller\Front;
use App\Entity\User;
use App\Service\Tools;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mime\Address;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Http\SecurityEvents;
/**
* Class SecurityController
* @package App\Controller
*/
class SecurityController extends AbstractController
{
private EntityManagerInterface $em;
public function __construct(
EntityManagerInterface $em
) {
$this->em = $em;
}
/**
* @param AuthenticationUtils $authenticationUtils
* @param Request $request
* @param Tools $tools
* @param EventDispatcherInterface $eventDispatcher
* @return Response
* @Route("/login", name="login", options={"expose"=true})
*/
public function login(
AuthenticationUtils $authenticationUtils,
Request $request,
Tools $tools,
EventDispatcherInterface $eventDispatcher
): Response {
if ($autoLogin = $request->get('al')) {
$user = $this->em->getRepository(User::class)->find($tools->decrypt($autoLogin));
if ($user) {
//On se connecte à l'user
$token = new UsernamePasswordToken($user, null, 'user_provider', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
$event = new SecurityEvents($request);
$eventDispatcher->dispatch($event, SecurityEvents::INTERACTIVE_LOGIN);
return $this->redirectToRoute('app_index');
}
}
if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
return $this->redirectToRoute('app_index');
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('front/security/login.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
]);
}
/**
* @throws Exception
* @Route("/logout", name="logout")
*/
public function logout(): void
{
throw new Exception('This should never be reached!');
}
/**
* @param Request $request
* @param MailerInterface $mailer
* @return RedirectResponse|Response
* @Route("/password-forget", name="password_forget")
* @throws TransportExceptionInterface
*/
public function passwordForget(Request $request, MailerInterface $mailer): RedirectResponse|Response
{
if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
return $this->redirectToRoute('app_index');
}
$email = $request->get('email');
$error = "";
if ($request->get('submit_password_forget')) {
/** @var User $user */
$user = $this->em->getRepository(User::class)->findOneBy([
'email' => $email
]);
if ($user) {
$hash = md5(uniqid('pf'));
$user->setHash($hash);
$message = (new TemplatedEmail())
->from(new Address($this->getParameter('MAILER_FROM'), $this->getParameter('MAILER_FROM_NAME')))
->to($user->getEmail())
->subject("Mot de passe oublié")
->htmlTemplate('email/user/password_forget.html.twig')
->context([
'user' => $user,
'hash' => $hash,
]);
$mailer->send($message);
$this->em->persist($user);
$this->em->flush();
}
$this->addFlash('success', "Un mail vient d'être envoyé à " . $email);
return $this->redirectToRoute('login');
}
return $this->render('front/security/password_forget.html.twig', [
'email' => $email,
'error' => $error,
'body_class' => 'login-container',
]);
}
/**
* @param string $hash
* @param Request $request
* @param UserPasswordEncoderInterface $passwordEncoder
* @return RedirectResponse|Response
* @Route("/password-reset/{hash}", name="password_reset")
*/
public function passwordReset(string $hash, Request $request, UserPasswordEncoderInterface $passwordEncoder): RedirectResponse|Response
{
if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
return $this->redirectToRoute('app_index');
}
$error = "";
/** @var User $user */
$user = $this->em->getRepository(User::class)->findOneBy([
'hash' => $hash
]);
if ($user && $request->get('submit_password_reset') && ($password = $request->get('password'))) {
if (strlen($password) > 5) {
$password = $passwordEncoder->encodePassword($user, $password);
$user->setPassword($password);
$user->setHash(null);
$this->em->persist($user);
$this->em->flush();
return $this->redirectToRoute('login');
} else {
$error = "Veuillez saisir un mot de passe d'au moins 6 caractères";
}
}
return $this->render('front/security/password_reset.html.twig', [
'error' => $error,
'body_class' => 'login-container',
]);
}
}