src/Controller/SecurityController.php line 87
<?phpnamespace App\Controller;use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\Routing\Annotation\Route;use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;use App\Entity\User;use App\Entity\Settings;use App\Entity\ActiveSession;use App\Form\RegisterType;use Doctrine\Persistence\ManagerRegistry as PersistenceManagerRegistry;use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;use Symfony\Component\HttpFoundation\Request;use App\Logger\DatabaseLogger;use App\Repository\UserRepository;use Symfony\Component\Mailer\MailerInterface;use Symfony\Component\Mime\Email;use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;use Symfony\Bundle\SecurityBundle\Security;use \Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;use App\Service\SessionControlService;use Symfony\Component\HttpFoundation\RequestStack;class SecurityController extends AbstractController {public function __construct(private UserPasswordHasherInterface $passwordEncoder,private MailerInterface $mailer,private ParameterBagInterface $params,private Security $security,private DatabaseLogger $logger,private SessionControlService $sessionControlService,private RequestStack $requestStack) {}#[Route(path: '/security', name: 'security', methods: ['GET'])]public function index(): Response {return $this->render('security/index.html.twig', [// 'controller_name' => 'SecurityController',]);}#[Route(path: '/login', name: 'app_login')]public function login(AuthenticationUtils $authenticationUtils): Response {# https://auth0.com/blog/creating-your-first-symfony-app-and-adding-authentication/// if ($this->getUser()) {// return $this->redirectToRoute('target_path');// }// get the login error if there is one$error = $authenticationUtils->getLastAuthenticationError();// last username entered by the user$lastUsername = $authenticationUtils->getLastUsername();return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);}#[Route(path: '/logout', name: 'app_pre_logout')]public function pre_logout(Request $request): Response {$user = $this->security->getUser();if (!$user) {return $this->redirectToRoute('home');}$session = ($request->hasSession()) ? $request->getSession()->getId() : '';$this->sessionControlService->registerActiveSessions($user->getEmail(), ActiveSession::STATUS_LOGGED_OUT_USER);$this->logger->notice('USER LOGOUT');return $this->security->logout(false);}#[Route(path: '/real_logout', name: 'app_logout')]public function logout(): void {throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');}#[Route(path: '/register', name: 'register', methods: ['GET', 'POST'])]public function register(Request $request, PersistenceManagerRegistry $doctrine, DatabaseLogger $logger, TokenGeneratorInterface $tokenGenerator, UserRepository $userRepository) {$em = $doctrine->getManager();$connection = $doctrine->getConnection();$settingsRepository = $em->getRepository(Settings::class);$regexObj = $settingsRepository->findOneBy(['name' => 'regexpPass']);$allowregister = $settingsRepository->findOneByName('allowregister');if (is_null($allowregister) || $allowregister->getValue() == 0) {return $this->redirectToRoute('home');}$user = new User();//TODO: para que haga algo parecido al "fill" de laravel tenemos que pasarle el entity// $user en la function createForm.$form = $this->createForm(RegisterType::class, ['regexp' => $regexObj]);$form->handleRequest($request);if ($form->isSubmitted() && $form->isValid()) {//comprobar que exista el correo sin validar y que tenga más de 15 min// --> si existe el registro lo actualizamos$user_check = $em->getRepository(User::class)->createQueryBuilder('u')->where('u.email = :email')->setParameters(['email' => $request->get('register')['email'],])->getQuery()->getOneOrNullResult();if ($user_check) {if ($user_check->getConfirmed() === 1) {$this->addFlash('danger', 'Usuario ya registrado');return $this->redirectToRoute('register');}if ($user_check->getTimeCreated() >= new \DateTime('-15 minutes')) {$this->addFlash('danger', 'Revise su correo para completar el registro.');return $this->redirectToRoute('register');}$user = $user_check;}// Encode the new users password$token = $tokenGenerator->generateToken();$user->setConfirmationToken($token);$user->setConfirmed(0);$user->setStatus(User::STATUS_SUSPENDED);$user->setPolicyAgreed($request->get('register')['policyagreed']);$user->setEmail($request->get('register')['email']);$user->setPassword($this->passwordEncoder->hashPassword($user, $request->get('register')['password']['first']));$user->setTimecreated(new \DateTime());// Set their role$user->setRoles(['ROLE_USER']);// Save$em = $doctrine->getManager();$em->persist($user);$em->flush();$logger->notice('Se ha creado un nuevo usuario.', ['data' => $user->serialize(),'userid' => $user->getId()]);$this->sendConfirmationEmail($user);$this->addFlash('success', 'Revise su correo para completar el registro.');return $this->redirectToRoute('app_login');}return $this->render('security/register.html.twig', ['form' => $form->createView(),]);}#[Route(path: '/confirm-registration/{token}', name: 'confirm_registration', methods: ['GET'])]public function confirmRegistration($token, PersistenceManagerRegistry $doctrine, DatabaseLogger $logger) {$em = $doctrine->getManager();$user = $em->getRepository(User::class)->findOneBy(['confirmationtoken' => $token, 'confirmed' => 0]);$error = 'Ocurrió un error al procesar la solicitud.';if ($user) {$error = '';$user->setConfirmed(1);$user->setStatus(User::STATUS_ENABLED);$em->persist($user);$em->flush();$logger->notice('Se ha confirmado el registro de un usuario.', ['data' => $user->serialize(),'userid' => $user->getId()]);}return $this->render('security/confirmation_result.html.twig', ['error' => $error,]);}private function sendConfirmationEmail(User $user) {try {$email = new Email();$email->from($_ENV['MAIL_SMTP_DO_NOT_REPLY_USERNAME'])->to($user->getEmail())->subject('Confirmación de registro')->html($this->renderView('security/confirmation_email.html.twig',['token' => $user->getConfirmationToken(),'user' => $user]),'text/html');$this->mailer->send($email);} catch (\Exception $e) {$this->logger->error('Error avisando por correo a ' . $user->getEmail(),['userid' => $user->getId(),'data' => $e->getMessage(),],);}}#[Route(path: '/forgot-password', name: 'app_forgot_password_request')]public function forgotPasswordRequest(Request $request, PersistenceManagerRegistry $doctrine, DatabaseLogger $logger, TokenGeneratorInterface $tokenGenerator): Response {$em = $doctrine->getManager();$regexp = $em->getRepository(Settings::class)->findOneBy(['name' => 'regexpPass']);if ($request->isMethod('POST')) {$resetemail = $request->get('resetemail');$user = $em->getRepository(User::class)->findOneBy(['email' => $resetemail, 'confirmed' => 1]);if ($user) {$token = $tokenGenerator->generateToken();$user->setConfirmationToken($token);$em->persist($user);$em->flush();try {$email = new Email();$email->from($_ENV['MAIL_SMTP_DO_NOT_REPLY_USERNAME'])->to($user->getEmail())->subject('Solicitud de reinicio de contraseña')->html($this->renderView('security/passwordreset_email.html.twig',['token' => $user->getConfirmationToken()]),'text/html');$this->mailer->send($email);$this->addFlash('success', 'Se ha enviado la solicitud de contraseña al correo indicado.');$logger->notice('Se ha solicitado un reinicio de contraseña para el usuario.', ['data' => $user->serialize(),'userid' => $user->getId()]);} catch (\Exception $e) {$this->logger->error('Error avisando por correo a ' . $user->getEmail(),['userid' => $user->getId(),'data' => $e->getMessage(),],);}}}return $this->render('security/passwordreset.html.twig', ['confirmreset' => false,'regexpPass' => $regexp,]);}#[Route(path: '/reset-password/{token}', name: 'reset_password', methods: ['GET', 'POST'])]public function resetPassword(Request $request, $token, PersistenceManagerRegistry $doctrine, DatabaseLogger $logger, TokenGeneratorInterface $tokenGenerator) {$em = $doctrine->getManager();$user = $em->getRepository(User::class)->findOneBy(['confirmationtoken' => $token, 'confirmed' => 1]);$regexp = $em->getRepository(Settings::class)->findOneBy(['name' => 'regexpPass']);if (!$user) {$this->addFlash('danger', 'Esta página no está disponible.<br>Es posible que el enlace que seleccionaste no funcione o que se haya eliminado la página.');return $this->redirectToRoute('home');}if ($request->isMethod('POST')) {$password = $request->get('password');$user->setPassword($this->passwordEncoder->hashPassword($user, $password));$user->setConfirmationToken("");$em->persist($user);$em->flush();$logger->notice('Se ha completado un reinicio de contraseña para el usuario.', ['data' => $user->serialize(),'userid' => $user->getId()]);$this->addFlash('success', 'El password ha sido reseteado correctamente.');return $this->redirectToRoute('home');}return $this->render('security/passwordreset.html.twig', ['confirmreset' => true,'regexpPass' => $regexp,]);}}