<?php
/**
* @author Thomas HERISSON (contact@scaledev.fr)
* @copyright 2021 - ScaleDEV SAS, 12 RUE CHARLES MORET, 10120 ST ANDRE LES VERGERS
* @license commercial
*/
declare(strict_types=1);
namespace App\Controller;
use DateTime;
use App\Repository\UserRepository;
use App\Message\PasswordLostMessage;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Security\Core\Security;
class SecurityController extends AbstractController
{
private EntityManagerInterface $em;
private UserRepository $userRepo;
private TranslatorInterface $tr;
public function __construct(EntityManagerInterface $em, UserRepository $userRepo, TranslatorInterface $tr)
{
$this->em = $em;
$this->userRepo = $userRepo;
$this->tr = $tr;
}
/**
* @param AuthenticationUtils $authenticationUtils
* @return Response
* @Route("/login", name="app_login", host="%app.default_host%")
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('app_dashboard');
}
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render(
'security/login.html.twig',
[
'last_username' => $lastUsername,
'error' => $error
]
);
}
/**
* @Route("/logout", name="app_logout")
*/
public function logout()
{
// nothing to do here :)
}
/**
* @param AuthenticationUtils $authenticationUtils
* @param Request $request
* @param MessageBusInterface $messageBus
* @return Response
* @Route("/password-lost", name="app_password_lost", host="%app.default_host%")
*/
public function passwordLost(
AuthenticationUtils $authenticationUtils,
Request $request,
MessageBusInterface $messageBus
): Response {
$lastUsername = $authenticationUtils->getLastUsername();
if ($request->isMethod('post')) {
$user = $this->userRepo->findOneBy(['email' => $request->get('email')]);
if ($user && $user->getPassword()) {
$messageBus->dispatch(new PasswordLostMessage($user));
$this->addFlash(
'success',
$this->tr->trans('You will receive an email within a few minutes to reset your password.')
);
} else {
$this->addFlash('danger', $this->tr->trans('You cannot reset your password.'));
}
return $this->redirectToRoute('app_login');
}
return $this->render(
'security/password_lost.html.twig',
[
'last_username' => $lastUsername
]
);
}
/**
* @param Request $request
* @param UserPasswordHasherInterface $passwordHasher
* @param string $email
* @param string $token
* @return Response
* @Route("/password-renew/{email}/{token}", name="app_password_renew", host="%app.default_host%")
*/
public function passwordRenew(
Request $request,
UserPasswordHasherInterface $passwordHasher,
string $email,
string $token
): Response {
if (!$email || !$token) {
$this->addFlash('danger', $this->tr->trans('You can\'t access to this page'));
return $this->redirectToRoute('app_login');
}
$user = $this->userRepo->findOneBy(['email' => urldecode($email)]);
if (
!$user
|| $token != $user->getToken()
|| $user->getTokenValidity() < new DateTime()
) {
$this->addFlash('danger', $this->tr->trans('Unknown or expired password renewal request'));
return $this->redirectToRoute('app_login');
}
if ($request->isMethod('post')) {
if ($request->get('password') != $request->get('password_confirm')) {
$this->addFlash('danger', $this->tr->trans('Passwords don\'t match'));
} else {
$user->setPassword(
$passwordHasher->hashPassword(
$user,
$request->get('password')
)
);
$user->setToken(null);
$user->setTokenValidity(null);
$this->em->persist($user);
$this->em->flush();
$this->addFlash('success', $this->tr->trans('Your password has been changed. Please log in.'));
return $this->redirectToRoute('app_login');
}
}
return $this->render('security/password_renew.html.twig');
}
/**
* @param Security $security
* @param Request $request
* @return Response
* @Route("/logged_in_check", name="logged_in_check", methods={"GET","POST"})
*/
public function loggedInCheck(Security $security, Request $request): Response
{
if ($request->isMethod('get')) {
return $this->redirectToRoute('app_dashboard');
}
return new JsonResponse(['result' => $security->isGranted('IS_AUTHENTICATED_REMEMBERED')]);
}
}