<?php
namespace Witalink\StarterBundle\Controller;
use App\Entity\User;
use Exception;
use LogicException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\Translation\TranslatorInterface;
use Witalink\StarterBundle\EventSubscriber\CustomEvents;
use Witalink\StarterBundle\EventSubscriber\Event\UserEvent;
use Witalink\StarterBundle\Form\PasswordType;
use Witalink\StarterBundle\Form\RegisterType;
class SecurityController extends AbstractController
{
private $authenticationUtils;
private $request;
private $translator;
private $generator;
private $withAutoRegistration;
private $withRememberMe;
private $withTerms;
private $eventDispatcher;
public function __construct(
bool $withAutoRegistration,
bool $withRememberMe,
bool $withTerms,
AuthenticationUtils $authenticationUtils,
RequestStack $request_stack,
TranslatorInterface $translator,
TokenGeneratorInterface $generator,
EventDispatcherInterface $eventDispatcher
) {
$this->withAutoRegistration = $withAutoRegistration;
$this->withRememberMe = $withRememberMe;
$this->withTerms = $withTerms;
$this->authenticationUtils = $authenticationUtils;
$this->request = $request_stack->getCurrentRequest();
$this->translator = $translator;
$this->generator = $generator;
$this->eventDispatcher = $eventDispatcher;
}
/**
* @Route("/login", name="app_login")
*/
public function login(): Response
{
// get the login error if there is one
$error = $this->authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $this->authenticationUtils->getLastUsername();
return $this->render(
'@WitalinkStarter/security/login.html.twig',
[
'last_username' => $lastUsername,
'error' => $error,
'withAutoRegistration' => $this->withAutoRegistration,
'withRememberMe' => $this->withRememberMe,
]
);
}
/**
* @Route("/logout", name="app_logout")
*/
public function logout()
{
throw new LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
/**
* @Route("/forgot", name="app_forgot_password")
*/
public function forgotPassword()
{
if ($this->request->isMethod('POST')) {
$forgetPasswordEmail = $this->request->request->get('forgetPasswordEmail');
$em = $this->getDoctrine()->getManager();
/** @var User $user */
$user = $em->getRepository(User::class)->findOneBy(['email' => $forgetPasswordEmail]);
if (null === $user) {
$this->addFlash('danger', $this->translator->trans('user.email.absent', [], 'validators'));
return $this->redirectToRoute('app_forgot_password');
}
$token = $this->generator->generateToken();
try {
$user->setToken($token);
$em->flush();
// we dispatch event to send the reset password email
$this->eventDispatcher->dispatch(new UserEvent($user), CustomEvents::USER_FORGET_PASSWORD);
$this->addFlash('success', $this->translator->trans('user.email.sent', [], 'validators'));
} catch (Exception $e) {
$this->addFlash('danger', $e);
}
return $this->redirectToRoute('app_forgot_password');
}
return $this->render(
'@WitalinkStarter/security/forget_password_email.html.twig',
[
'withAutoRegistration' => $this->withAutoRegistration,
]
);
}
/**
* @Route("/register", name="app_register")
*/
public function register(TokenGeneratorInterface $generator)
{
if (!$this->withAutoRegistration) {
return $this->redirectToRoute('app_login');
}
$user = new User();
$form = $this->createForm(RegisterType::class, $user);
$form->handleRequest($this->request);
if ($form->isSubmitted() && $form->isValid() && $this->request->isMethod('POST')) {
$email = $user->getEmail();
$em = $this->getDoctrine()->getManager();
$result = $em->getRepository(User::class)->findOneBy(['email' => $email]);
if ($result) {
$this->addFlash('danger', "$email est déjà utilisé");
} else {
try {
$token = $generator->generateToken();
$user->setToken($token);
$em->persist($user);
$em->flush();
// The user has been created, at this point, we dispatch events
$this->eventDispatcher->dispatch(new UserEvent($form->getData()), CustomEvents::USER_REGISTRED);
$this->addFlash('success', "Un email d'activation vous a été envoyé.");
} catch (Exception $e) {
$this->addFlash('danger', $e);
}
}
return $this->redirectToRoute('app_register');
}
return $this->render(
'@WitalinkStarter/security/register.html.twig',
[
'error' => $form->getErrors(),
'form' => $form->createView(),
'withTerms' => $this->withTerms,
]
);
}
/**
* @Route("/reset", name="app_reset_password")
* @Route("/activate", name="app_activate")
*/
public function resetPassword()
{
$isActivate = ($this->request->attributes->get('_route') == "app_activate") ? true : false;
$token = $this->request->query->get('token');
if (empty($token)) {
$this->addFlash('danger', "Le token ne doit pas être vide");
return $this->redirectToRoute('app_reset_password');
}
$em = $this->getDoctrine()->getManager();
/** @var User $user */
$user = $em->getRepository(User::class)->findOneBy(['token' => $token]);
if (null === $user) {
$this->addFlash('danger', $this->translator->trans('expired_activation_link'));
return $this->redirectToRoute('app_forgot_password');
}
$form = $this->createForm(PasswordType::class, $user);
$form->handleRequest($this->request);
if ($form->isSubmitted() && $form->isValid()) {
$formData = $this->request->request->get('password');
//dd($formData);
$passwd = $formData['password']['first'];
$repPasswd = $formData['password']['second'];
if ($passwd == $repPasswd) {
$user->setPlainPassword($passwd);
$user->setToken(null);
$em->flush();
$this->addFlash('success', $this->translator->trans('user.password.passed', [], 'validators'));
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
}
}
return $this->render(
'@WitalinkStarter/security/reset_password.html.twig',
[
'isActivate' => $isActivate,
'form' => $form->createView(),
]
);
}
}