<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use App\Entity\User;
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use App\Form\ResettingType;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class AuthenticationController extends AbstractController
{
/**
* @Route(
* "{_locale}/requete",
* name="request_resetting",
* requirements={
* "_locale": "%app_locales%",
* }
* )
*/
public function request(Request $request, TokenGeneratorInterface $tokenGenerator, \Swift_Mailer $mailer)
{
// création d'un formulaire "à la volée", afin que l'internaute puisse renseigner son mail
$form = $this->createFormBuilder()
->add('email', EmailType::class, [
'constraints' => [
new Email(),
new NotBlank()
]
])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
// voir l'épisode 2 de cette série pour retrouver la méthode loadUserByUsername:
$user = $em->getRepository(User::class)->loadUserByUsername($form->getData()['email']);
// aucun email associé à ce compte.
if (!$user) {
$request->getSession()->getFlashBag()->add('warning', "Cet email n'existe pas.");
return $this->redirectToRoute("request_resetting");
}
// création du token
$user->setToken($tokenGenerator->generateToken());
// enregistrement de la date de création du token
$user->setPasswordRequestedAt(new \Datetime());
$em->flush();
// on utilise le service Mailer créé précédemment
$message = (new \Swift_Message('Renouvellement du mot de passe'))
->setFrom('info@aperosparfumes.com')
->setTo($user->getEmail())
->setBody(
$this->renderView(
// templates/emails/registration.html.twig
'resetting/mail.html.twig',
['user' => $user]
),
'text/html'
);
$mailer->send($message);
$request->getSession()->getFlashBag()->add('success', "Un mail va vous être envoyé afin que vous puissiez renouveller votre mot de passe. Le lien que vous recevrez sera valide 24h.");
return $this->redirectToRoute("home");
}
return $this->render('resetting/request.html.twig', [
'form' => $form->createView()
]);
}
// si supérieur à 1 jour, retourne false
// sinon retourne false
private function isRequestInTime(\Datetime $passwordRequestedAt = null)
{
if ($passwordRequestedAt === null)
{
return false;
}
$now = new \DateTime();
$interval = $now->getTimestamp() - $passwordRequestedAt->getTimestamp();
$daySeconds = 60 * 60 * 24;
$response = $interval > $daySeconds ? false : $reponse = true;
return $response;
}
/**
* @Route(
* "{_locale}/reset/{token}",
* name="resetting",
* requirements={
* "_locale": "%app_locales%",
* }
* )
*/
public function resetting($token, Request $request, UserPasswordEncoderInterface $encoder)
{
$id = $request->get('id');
$user = $this->getDoctrine()->getManager()->getRepository(User::class)->find($id);
// interdit l'accès à la page si:
// le token associé au membre est null
// le token enregistré en base et le token présent dans l'url ne sont pas égaux
// le token date de plus de 10 minutes
if ($user->getToken() === null || $token !== $user->getToken() || !$this->isRequestInTime($user->getPasswordRequestedAt()))
{
throw new AccessDeniedHttpException();
}
$form = $this->createForm(ResettingType::class, $user);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid())
{
$password = $encoder->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
// réinitialisation du token à null pour qu'il ne soit plus réutilisable
$user->setToken(null);
$user->setPasswordRequestedAt(null);
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
$this->addFlash('success', "Votre mot de passe a été renouvelé.");
return $this->redirectToRoute('home');
}
return $this->render('resetting/index.html.twig', [
'form' => $form->createView()
]);
}
}