src/Controller/SecurityController.php line 43

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\User;
  4. use App\Form\Security\ForgotPasswordForm;
  5. use App\Form\Security\ResetPasswordForm;
  6. use App\Form\Security\SignInForm;
  7. use App\Service\TokenGenerator;
  8. use Carbon\Carbon;
  9. use Doctrine\ORM\EntityManagerInterface;
  10. use Doctrine\ORM\NonUniqueResultException;
  11. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpFoundation\Response;
  14. use Symfony\Component\Routing\Annotation\Route;
  15. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  16. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  17. use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
  18. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  19. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  20. /**
  21.  * Class SecurityController.
  22.  *
  23.  * @Route("", name="security")
  24.  */
  25. class SecurityController extends AbstractController
  26. {
  27.     /**
  28.      * @var int
  29.      */
  30.     private $lockoutPolicy;
  31.     public function __construct(int $lockoutPolicy)
  32.     {
  33.         $this->lockoutPolicy $lockoutPolicy;
  34.     }
  35.     /**
  36.      * @Route("/sign-in", name=".sign-in")
  37.      */
  38.     public function index(AuthenticationUtils $authenticationUtils): Response
  39.     {
  40.         $utils $authenticationUtils;
  41.         $error $utils->getLastAuthenticationError();
  42.         $last $utils->getLastUsername();
  43.         $attempts 0;
  44.         $user $this->getDoctrine()->getRepository(User::class)->findUser($last);
  45.         if ($user instanceof User) {
  46.             $attempts $this->lockoutPolicy $user->getFailures();
  47.             if (=== $attempts) {
  48.                 $attempts null;
  49.             }
  50.             if (=== $attempts) {
  51.                 $error = new CustomUserMessageAuthenticationException(
  52.                     'account.locked'
  53.                 );
  54.             }
  55.         }
  56.         $form $this->createForm(SignInForm::class, [
  57.             '_username' => $last,
  58.         ]);
  59.         return $this->render('security/sign-in.html.twig', [
  60.             'form' => $form->createView(),
  61.             'error' => $error,
  62.             'attempts' => $attempts,
  63.         ]);
  64.     }
  65.     /**
  66.      * @Route("/forgot-password", name=".forgot-password")
  67.      */
  68.     public function forgotPasswordAction(Request $requestEntityManagerInterface $emTokenGenerator $generator)
  69.     {
  70.         $form $this->createForm(ForgotPasswordForm::class);
  71.         $form->handleRequest($request);
  72.         if ($form->isSubmitted()) {
  73.             $email $form->get('email')->getData();
  74.             $this->addFlash('success''Please check your mailbox to continue.');
  75.             $user $em->getRepository(User::class)->findUser($email);
  76.             if ($user instanceof User && !$user->isRemoved() && $user->getFailures() < $this->lockoutPolicy) {
  77.                 $generator->generate($user);
  78.             }
  79.             return $this->redirectToRoute('security.sign-in');
  80.         }
  81.         return $this->render('security/forgot-password.html.twig', [
  82.             'form' => $form->createView(),
  83.         ]);
  84.     }
  85.     /**
  86.      * @Route("/{token}/{email}/reset-password", name=".reset-password")
  87.      *
  88.      * @return Response
  89.      *
  90.      * @throws NonUniqueResultException
  91.      */
  92.     public function resetPasswordAction(Request $requestEntityManagerInterface $emTokenStorageInterface $tokenStorageEventDispatcherInterface $eventDispatcherstring $emailstring $token)
  93.     {
  94.         $now Carbon::now();
  95.         /** @var User $user */
  96.         $user $em->createQueryBuilder()
  97.             ->from(User::class, 'user')
  98.             ->select('user')
  99.             ->where('user.email = :email')
  100.             ->andWhere('user.token.string = :token')
  101.             ->andWhere('user.token.expires >= :now')
  102.             ->andWhere('user.removed = FALSE')
  103.             ->andWhere('user.failures < :lockout')
  104.             ->setParameters(['email' => $email'token' => $token'now' => $now'lockout' => $this->lockoutPolicy])
  105.             ->setMaxResults(1)
  106.             ->getQuery()->getOneOrNullResult();
  107.         if (!$user instanceof User) {
  108.             throw $this->createNotFoundException();
  109.         }
  110.         $form $this->createForm(ResetPasswordForm::class);
  111.         $form->handleRequest($request);
  112.         if ($form->isSubmitted() && $form->isValid()) {
  113.             $password $form->get('password')->getData();
  114.             $user->setPlainPassword($password);
  115.             $user->getToken()->reset();
  116.             $em->flush();
  117.             $token = new UsernamePasswordToken($user$password'main'$user->getRoles());
  118.             $tokenStorage->setToken($token);
  119.             $event = new InteractiveLoginEvent($request$token);
  120.             $eventDispatcher->dispatch($event);
  121.             $this->addFlash('success''Your password was successfully updated.');
  122.             return $this->redirectToRoute('dashboard');
  123.         }
  124.         return $this->render('security/reset-password.html.twig', [
  125.             'form' => $form->createView(),
  126.             'email' => $email,
  127.             'token' => $token,
  128.         ]);
  129.     }
  130.     /**
  131.      * @Route("/sign-out", name=".sign-out")
  132.      */
  133.     public function signOutAction()
  134.     {
  135.         throw new \Exception('');
  136.     }
  137. }