<?php
namespace App\Controller;
use App\Form\ChangePasswordType;
use App\Service\Mail\MailHandler;
use App\Share\Entity\PasswordLink;
use App\Share\Entity\UserPasswordLink;
use App\Share\Repository\UserPasswordLinkRepository;
use App\Share\Repository\UserRepository;
use App\Traits\UtilsTrait;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends AbstractController
{
use UtilsTrait;
/**
* @var MailHandler
*/
private $mailHandler;
/**
* @var LoggerInterface
*/
private $logger;
/**
* @var UserPasswordHasherInterface
*/
private $encoder;
public function __construct(
MailHandler $mailHandler,
LoggerInterface $logger,
UserPasswordHasherInterface $encoder
)
{
$this->mailHandler = $mailHandler;
$this->logger = $logger;
$this->encoder = $encoder;
}
/**
* @Route("/connexion", name="app_login")
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
if($this->isGranted("IS_AUTHENTICATED_REMEMBERED"))
{
return $this->redirectToRoute("admin_dashboard");
}
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/mot-de-passe-oublie", name="forgot_password")
*/
public function forgotPassword(
Request $request,
UserRepository $userRepository,
UserPasswordLinkRepository $passwordLinkRepository
): Response
{
$error = null;
if($request->isMethod('POST'))
{
$email = $request->request->get('email',null);
if(!$email)
{
$error = "Veuillez rensigner votre email !";
}
try {
$user = $userRepository->findOneBy([
'email'=>$email,
'enabled'=>true,
]);
$error = "Impossible de trouver le profil demandé !";
if ($user) {
$token = $this->generateToken();
$resetPasswordLink = $this->generateResetPassworkLinkTokenUrl($request, $token);
$passwordLinkRepository->deleteOldLinks($user);
$passwordLink = new UserPasswordLink();
$passwordLink->setAppUser($user);
$passwordLink->setToken($token);
$passwordLink->setEndAt($this->createExpireTokenDate());
$error = null;
$em = $this->getDoctrine()->getManager();
$em->persist($passwordLink);
$em->flush();
$mailSuccess = $this->mailHandler->sendResetPasswordLink([
'user' => $user,
'url' => $resetPasswordLink,
'to' => $user->getEmail(),
'fullname' => $user->getFullName(),
]);
if (1 !== $mailSuccess) {
$this->addFlash('warning', "Une erreur s'est produite lors de l'envoi du mail");
} elseif (1 === $mailSuccess) {
$this->addFlash('success','Vous allez recevoir un mail pour modifier votre mot de passe');
}
return $this->redirectToRoute('app_login');
}
}
catch (\Exception $e){
$error = "Erreur lors de la recherche de votre profil !";
$this->logger->critical(sprintf("security_controller_forgot_password.CRITICAL: %s",$e->getMessage()));
}
}
return $this->render('security/forgot_password.html.twig',
[
'error'=>$error,
]
);
}
/**
* @Route("/reset-mot-de-passe/{token}", name="admin_reset_password")
*/
public function AdminResetPassword(Request $request, $token,UserPasswordLinkRepository $userPasswordLinkRepository)
{
if(!$token){
$this->addFlash("error","Votre token est invalide !");
return $this->redirectToRoute('forgot_password');
}
$userPasswordLink = $userPasswordLinkRepository->findOneBy(['token'=>$token]);
if(!$userPasswordLink){
$this->addFlash("error","Votre token est invalide !");
return $this->redirectToRoute('forgot_password');
}
if($this->isTokenExpired($userPasswordLink->getEndAt()))
{
$this->addFlash('error',"Votre token est expiré !");
return $this->redirectToRoute('forgot_password');
}
$user = $userPasswordLink->getAppUser();
if(!$user)
{
$this->addFlash('error',"Une erreur est survenue lors de la récuparation de votre profil !");
return $this->redirectToRoute('forgot_password');
}
$form = $this->createForm(ChangePasswordType::class,$user);
$form->handleRequest($request);
if($request->isMethod('POST') && $form->isValid()){
if($user->getPlainPassword()){
$passwordEncoded = $this->encoder->hashPassword($user,$user->getPlainPassword());
$user->setPassword($passwordEncoded);
}
$userPasswordLinkRepository->deleteOldLinks($user);
$em = $this->getDoctrine()->getManager();
$em->flush($user);
$this->addFlash('success',"Votre profil a été mis à jour !");
return $this->redirectToRoute('app_login');
}
if($form->getErrors(true) && count($form->getErrors(true)) > 0)
{
$errorMessage = $form->getErrors(true)->getChildren('password')->getMessage();
$this->addFlash('error',$errorMessage);
}
return $this->render('security/reset_password.html.twig',[
'form'=>$form->createView(),
'token'=>$token,
]);
}
/**
* @Route("/deconnexion", name="app_logout")
*/
public function logout()
{
return $this->redirectToRoute('app_login');
}
}