<?php
namespace App\Controller;
use App\Entity\User;
use App\Form\NewPasswordFormType;
use App\Form\RegistrationFormType;
use App\Form\ResetPassType;
use App\Repository\UserRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\Translation\TranslatorInterface;
class SecurityController extends AbstractController
{
/**
* @param AuthenticationUtils $authenticationUtils
* @Route("/login", name="app_login")
* @return Response
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('app_home');
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
$registrationForm = $this->createForm(
RegistrationFormType::class,
new User(),
['action' => $this->generateUrl('app_register')] );
$forgottenPasswordForm = $this->createForm(
ResetPassType::class,
null,
['action' => $this->generateUrl('app_forgotten_password')]
);
return $this->render('security/login.html.twig', [
'registrationForm' => $registrationForm->createView(),
'forgottenPasswordForm' => $forgottenPasswordForm->createView(),
'last_username' => $lastUsername,
'error' => $error
]);
}
/**
* @Route("/logout", name="app_logout")
* @Security("is_granted('ROLE_USER')")
*/
public function logout()
{
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
/**
* @param Request $request
* @param UserRepository $userRepository
* @param \Swift_Mailer $mailer
* @param TokenGeneratorInterface $tokenGenerator
* @param TranslatorInterface $translator
* @Route("/forgotPass", name="app_forgotten_password", methods={"POST"})
* @return Response
*/
public function forgotPass(Request $request, UserRepository $userRepository, \Swift_Mailer $mailer,
TokenGeneratorInterface $tokenGenerator,TranslatorInterface $translator): Response
{
$form = $this->createForm(ResetPassType::class);
$form->handleRequest($request);
$locale = $request->getLocale();
if ($form->isSubmitted() && $form->isValid()) {
try {
$data = $form->getData();
// Get User
$user = $userRepository->findOneBy(['email' => $data['email']]);
if ($user === null) {
$this->addFlash('danger', $translator->trans('error.accountNotExist',[],null,$request->getLocale()));
return $this->redirectToRoute('app_login',['_locale'=>$locale]);
}
// Generate Token
$token = $tokenGenerator->generateToken();
$user->setResetToken($token);
$userRepository->save($user);
} catch (\Throwable $throwable) {
$this->addFlash('warning', $translator->trans('error.error500',[],null,$request->getLocale()));
return $this->redirectToRoute('app_login');
}
$locale = $user->getLocale();
$url = $this->generateUrl('app_reset_password', ['_locale' => $locale,'token' => $token],
UrlGeneratorInterface::ABSOLUTE_URL);
$message = (new \Swift_Message($translator->trans('email.suject',[],null,$locale)))
->setFrom(['no-reply@ed-pepper.eu' => 'Pepper'])
->setTo($user->getEmail())
->setBody(
$this->renderView(
'emails/reset-password.html.twig',
[
'suject'=>$translator->trans('email.suject',[],null,$locale),
'hello'=> $translator->trans('email.hello',[],null,$locale),
'user' => sprintf('%s.%s',$user->getCivility(),$user->getFirstName()),
'message'=>$translator->trans('email.message', [], null, $locale),
'url'=>$url,
'footer1' => $translator->trans('email.footer1',[],null,$locale),
'footer2' => $translator->trans('email.footer2',[],null,$locale)
]
),
'text/html'
)
;
// Send email
$mailer->send($message);
$this->addFlash('success', $translator->trans('login.forgot.success',["%email%" => $user->getEmail() ],null,$locale));
}
return $this->redirectToRoute('app_login',[ '_locale' => $locale]);
}
/**
* @param Request $request
* @param string $token
* @param UserPasswordEncoderInterface $passwordEncoder
* @param UserRepository $userRepository
* @param TranslatorInterface $translator
* @Route("/reset_pass/{token}", name="app_reset_password", methods={"POST","GET"})
* @return Response
*/
public function resetPassword(Request $request, string $token, UserPasswordEncoderInterface $passwordEncoder,
UserRepository $userRepository,TranslatorInterface $translator) : Response
{
$user = $userRepository->findOneBy(['reset_token' => $token]);
if ($user === null) {
$this->addFlash('danger', $translator->trans('login.resetpass.errorToken',[],null,$request->getLocale()));
return $this->redirectToRoute('app_login');
}
$form = $this->createForm(NewPasswordFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try{
$user = $userRepository->findOneBy(['reset_token' => $token]);
$user->setResetToken(null);
$user->setPassword($passwordEncoder->encodePassword($user, $form->get('newPassword')->getData()));
$userRepository->save($user);
$this->addFlash('message', $translator->trans('login.resetpass.success',[],null,$request->getLocale()));
return $this->redirectToRoute('app_login');
}catch (\Throwable $throwable){
$this->addFlash('danger', $translator->trans('error.error500',[],null,$request->getLocale()));
return $this->redirectToRoute('app_login');
}
}
return $this->render('security/reset_password.html.twig', [
'newPasswordForm' => $form->createView(),
]);
}
}