<?php
namespace App\Controller;
use App\Entity\User;
use App\Form\Type\PasswordResetType;
use App\Time\TimeService;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Encoder\EncoderFactory;
use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class SecurityController extends Controller
{
public function index(): Response
{
return $this->render('Default/index.html.twig');
}
public function login(AuthenticationUtils $authenticationUtils): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('index');
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
if ($error) {
$this->setFlash('error', $error->getMessage());
}
return $this->render(
'Default/login.html.twig',
['error' => $error, 'last_username' => $lastUsername, 'showNavigation' => false, 'showFooter' => false],
);
}
public function passwordSet(Request $request, TimeService $timeService, $token = null): Response
{
$user = $this->getRepo(User::class)->findOneBy(['passwordResetToken' => $token]);
if (!$user) {
$this->setFlash('error', 'The password reset token has expired please contact Dawson Forklift Services to request a new link.');
throw $this->createNotFoundException('Invlaid token "' . $token . '".');
}
$now = $timeService->getNewDateTime();
$invalidToken = $now > $user->getPasswordResetTokenExpiry();
if ($invalidToken) {
$user->setPasswordResetToken(null);
$user->setPasswordResetTokenExpiry(null);
$this->setFlash('error', 'The password reset token has expired please contact Dawson Forklift Services to request a new link.');
return $this->redirect($this->generateUrl('login'));
}
$form = $this->createForm(PasswordResetType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$defaultEncoder = new MessageDigestPasswordEncoder('sha512', true, 5000);
$encoders = [
User::class => $defaultEncoder,
];
$encoderFactory = new EncoderFactory($encoders);
$encoder = $encoderFactory->getEncoder($user);
$bcrypted_password = $encoder->encodePassword($form->get('plainPassword')->getData(), $user->getSalt());
$user->setPassword($bcrypted_password);
$user->setPasswordResetToken(null);
$user->setPasswordResetTokenExpiry(null);
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
$token = new UsernamePasswordToken($user, null, 'secured_area', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
$event = new InteractiveLoginEvent($request, $token);
$this->get('event_dispatcher')->dispatch('security.interactive_login', $event);
$this->setFlash('success', 'The password for "' . $user->getUsername() . '" was successfully set');
return $this->redirect($this->generateUrl('index'));
}
return $this->render('User/_passwordSetForm.html.twig', ['token' => $token, 'form' => $form->createView(), 'formRoute' => $this->generateUrl('set_password', ['token' => $token])]);
}
public function passwordReset(Request $request, TimeService $timeService, $token = null): Response
{
$user = $this->getRepo(User::class)->findOneBy(['passwordResetToken' => $token]);
if (!$user) {
$this->setFlash('error', 'The password reset token has expired please contact Dawson Forklift Services to request a new link.');
throw $this->createNotFoundException('Invlaid token "' . $token . '".');
}
$now = $timeService->getNewDateTime();
$invalidToken = $now > $user->getPasswordResetTokenExpiry();
if ($invalidToken) {
$user->setPasswordResetToken(null);
$user->setPasswordResetTokenExpiry(null);
$this->setFlash('error', 'The password reset token has expired please contact Dawson Forklift Services to request a new link.');
return $this->redirect($this->generateUrl('login'));
}
$form = $this->createForm(PasswordResetType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$defaultEncoder = new MessageDigestPasswordEncoder('sha512', true, 5000);
$encoders = [
User::class => $defaultEncoder,
];
$encoderFactory = new EncoderFactory($encoders);
$encoder = $encoderFactory->getEncoder($user);
$bcrypted_password = $encoder->encodePassword($form->get('plainPassword')->getData(), $user->getSalt());
$user->setPassword($bcrypted_password);
$user->setPasswordResetToken(null);
$user->setPasswordResetTokenExpiry(null);
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
$token = new UsernamePasswordToken($user, null, 'secured_area', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
$event = new InteractiveLoginEvent($request, $token);
$this->get('event_dispatcher')->dispatch('security.interactive_login', $event);
$this->setFlash('success', 'The password for "' . $user->getUsername() . '" was successfully reset');
return $this->redirect($this->generateUrl('index'));
}
return $this->render('User/_passwordResetForm.html.twig', ['token' => $token, 'form' => $form->createView(), 'formRoute' => $this->generateUrl('reset_password', ['token' => $token])]);
}
}