<?php
namespace App\Controller\Web;
use App\Entity\User;
use App\Events;
use App\Form\Type\ResetPasswordType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
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\Event\InteractiveLoginEvent;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* Class SecurityController
* @package App\Controller\Web
*
* @Route("", name="security")
*/
class SecurityController extends AbstractController
{
/** @var EventDispatcherInterface */
private $eventDispatcher;
/** @var TranslatorInterface */
private $translator;
public function __construct(
EventDispatcherInterface $eventDispatcher,
TranslatorInterface $translator
)
{
$this->eventDispatcher = $eventDispatcher;
$this->translator = $translator;
}
/**
* @Route("/login", name="_login")
*
* @param AuthenticationUtils $authenticationUtils
* @return Response
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
return $this->render('public/login.html.twig', [
// last username entered by the user (if any)
'last_username' => $authenticationUtils->getLastUsername(),
// last authentication error (if any)
'error' => $authenticationUtils->getLastAuthenticationError(),
]);
}
/**
* @Route("/logout", name="_logout", methods={"GET"})
*/
public function logout()
{
// controller can be blank: it will never be executed!
throw new \Exception('Don\'t forget to activate logout in security.yaml');
}
/**
* @Route("/password-reset", name="_password_reset")
*/
public function passwordReset(Request $request): Response
{
if ($request->isMethod('POST')) {
$email = $request->request->get('_email');
/** @var User $user */
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy(['email' => $email]);
if (null === $user) {
$this->addFlash('danger', $this->translator->trans('The user with email %email% does not exist.', ['%email%' => $email]));
return $this->render('public/password-reset.html.twig');
}
$event = new GenericEvent($user);
$this->eventDispatcher->dispatch(Events::PASSWORD_RESET, $event);
$this->addFlash('success', 'User password reset email sent.');
return $this->redirectToRoute('homepage');
}
return $this->render('public/password-reset.html.twig');
}
/**
* @Route("/password-reset/confirm/{token}", methods={"GET", "POST"}, name="_password_reset_confirm")
*/
public function resetAction($token, Request $request, UserPasswordEncoderInterface $encoder)
{
/** @var User $user */
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy(['confirmationToken' => $token]);
if (null === $user) {
throw new NotFoundHttpException(sprintf('The user with confirmation token "%s" does not exist', $token));
}
$form = $this->createForm(ResetPasswordType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user->setPassword($encoder->encodePassword($user, $form->get('newPassword')->getData()));
$this->getDoctrine()->getManager()->flush();
$this->addFlash('success', 'Your password has been changed!');
return $this->redirectToRoute('homepage');
}
return $this->render('public/password-reset-confirm.html.twig', array(
'token' => $token,
'form' => $form->createView(),
));
}
/**
* @Route("/impersonate/{token}", methods={"GET", "POST"}, name="_impersonate_user")
* @param $token
* @param Request $request
* @param TokenStorageInterface $tokenInterface
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Exception
*/
public function impersonateUser($token, Request $request, TokenStorageInterface $tokenInterface)
{
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy(['impersonateToken' => $token]);
if($user)
{
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
$session = $this->get('session');
$session->set('_security_main', serialize($token));
$event = new InteractiveLoginEvent($request, $token);
$this->eventDispatcher->dispatch("security.interactive_login", $event);
/**
* @var $currentUser User
*/
$currentUser = $tokenInterface->getToken()->getUser();
$logFromWlpga = new GenericEvent($currentUser);
$this->eventDispatcher->dispatch(Events::USER_LOGGED_FROM_WLPGA, $logFromWlpga);
$user->setImpersonateToken(User::generateUniqueToken());
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('admin_index');
}
else
{
$this->addFlash('error', 'Token not found.');
return $this->redirect('/');
}
}
}