src/Controller/SecurityController.php line 46

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\User;
  4. use App\Repository\UserRepository;
  5. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  6. use Symfony\Component\HttpFoundation\JsonResponse;
  7. use Symfony\Component\HttpFoundation\Request;
  8. use Symfony\Component\HttpFoundation\Response;
  9. use Symfony\Component\Ldap\Ldap;
  10. use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  11. use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
  12. use Symfony\Component\Security\Csrf\CsrfToken;
  13. use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
  14. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  15. use Symfony\Contracts\Translation\TranslatorInterface;
  16. class SecurityController extends AbstractController
  17. {
  18.     public $ldap;
  19.     private $csrfTokenManager;
  20.     private $userPasswordEncoder;
  21.     private $userRepository;
  22.     public function __construct(
  23.         Ldap $ldap,
  24.         CsrfTokenManagerInterface $csrfTokenManager,
  25.         UserPasswordEncoderInterface $userPasswordEncoder,
  26.         UserRepository $userRepository
  27.     )
  28.     {
  29.         $this->ldap=$ldap;
  30.         $this->csrfTokenManager $csrfTokenManager;
  31.         $this->userPasswordEncoder $userPasswordEncoder;
  32.         $this->userRepository $userRepository;
  33.     }
  34.     public function login(AuthenticationUtils $authenticationUtilsTranslatorInterface $translator): Response
  35.     {
  36.         if ('azure' === $this->getParameter('login_method')){
  37.             return $this->redirectToRoute('connect_azure_start');
  38.         }
  39.         // get the login error if there is one
  40.         $error $authenticationUtils->getLastAuthenticationError();
  41.         // last username entered by the user
  42.         $lastUsername $authenticationUtils->getLastUsername();
  43.         return $this->render('security/login.html.twig', [
  44.             'error' => $error,
  45.             'last_username' => $lastUsername,
  46.             'translation_domain' => 'admin',
  47.             'page_title' => $translator->trans('pages.login.page_title'),
  48.             'csrf_token_intention' => 'authenticate',
  49.             'target_path' => $this->generateUrl('dashboard'),
  50.             'username_label' => $translator->trans('pages.login.username_label'),
  51.             'password_label' => $translator->trans('pages.login.password_label'),
  52.             'sign_in_label' => $translator->trans('pages.login.sign_in_label'),
  53.             'username_parameter' => '_username',
  54.             'password_parameter' => '_password',
  55.         ]);
  56.     }
  57.     public function logout()
  58.     {
  59.         if ('azure' === $this->getParameter('login_method')){
  60.             return $this->redirectToRoute('app_logout_azure');
  61.         }
  62.         throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
  63.     }
  64.     public function checkUserExistsAPI(Request $request){
  65.         $user_exists false;
  66.         $user_registrable false;
  67.         $user_data = [];
  68.         // Get Credentials
  69.         $credentials = [
  70.             'username' => $request->request->get('_username'),
  71.             'csrf_token' => $request->request->get('_csrf_token'),
  72.         ];
  73.         // Check if token is correct
  74.         $token = new CsrfToken('authenticate'$credentials['csrf_token']);
  75.         if (!$this->csrfTokenManager->isTokenValid($token)) {
  76.             throw new InvalidCsrfTokenException();
  77.         }
  78.         // Check if user exists id db
  79.         $user_db $this->getDoctrine()->getManager()->getRepository(User::class)->findOneBy(['email' => $credentials['username']]);
  80.         if ($user_db) {
  81.             $user_exists true;
  82.             $user_data=[
  83.                 'name' => $user_db->getName(),
  84.                 'email'=> $user_db->getEmail(),
  85.                 'md5' => md5(strtolower($user_db->getEmail())),
  86.             ];
  87.         }
  88.         // Check if user is registrable
  89.         if(!$user_exists){
  90.             $user $this->clientHelper->getUsernameData($credentials);
  91.             if($user){
  92.                 $user_registrable true;
  93.             }
  94.         }
  95.         // If user doesn't exist we check if LDAP
  96.         if(!$user_exists){
  97.             $user $this->_checkInLDAP($credentials);
  98.             if($user){
  99.                 $user_attr $user->getAttributes();
  100.                 $user_exists true;
  101.                 $user_data=[
  102.                     'name' => $user_attr['displayName'],
  103.                     'email' => $user_attr['userPrincipalName'][0],
  104.                     'md5' => md5(strtolower($user_attr['userPrincipalName'][0])),
  105.                 ];
  106.             }
  107.         }
  108.         $response = [
  109.             'user_exists'=>$user_exists,
  110.             'user_registrable'=>$user_registrable,
  111.             'user_data'=>$user_data
  112.         ];
  113.         return new JsonResponse ($responseResponse::HTTP_OK);
  114.     }
  115.     public function _checkInLDAP($credentials){
  116.         $username$credentials['username'];
  117.         $this->ldap->bind($_ENV['SEARCH_DN'], $_ENV['SEARCH_PASSWORD']);
  118.         $query $this->ldap->query($_ENV['DN_STRING'], '(&(sAMAccountName='.$username.'))');
  119.         $results $query->execute();
  120.         return $results[0] ? $results[0] : false;
  121.     }
  122.     public function registerUser($tokenRequest $request){
  123.         $user $this->userRepository->findOneBy(['token'=>$token]);
  124.         if(!$user){
  125.             return false;
  126.         }
  127.         $userData $this->clientHelper->getUsernameSingleData($user->getEmail());
  128.         $form=$this->createForm(UserRegistrationType::class, $user);
  129.         $form->handleRequest($request);
  130.         if ($form->isSubmitted() && $form->isValid()) {
  131.             // Retrieve Data
  132.             $entityManager $this->getDoctrine()->getManager();
  133.             $user $form->getData();
  134.             $user->setPassword($this->userPasswordEncoder->encodePassword(
  135.                 $user,
  136.                 $user->getPassword()
  137.             ));
  138.             $user->setToken(null);
  139.             $entityManager->persist($user);
  140.             $entityManager->flush();
  141.             return $this->redirectToRoute('dashboard');
  142.         }
  143.         return $this->render('security/register.html.twig', [
  144.             'form' => $form->createView(),
  145.             'user_data' => $userData,
  146.             'user' => $user
  147.         ]);
  148.     }
  149.     public function sendVerificationEmail(Request $request){
  150.         // Get Credentials
  151.         $credentials = [
  152.             'email' => $request->request->get('_username'),
  153.             'username' => $request->request->get('_username'),
  154.             'csrf_token' => $request->request->get('_csrf_token'),
  155.         ];
  156.         // Check if token is correct
  157.         $token = new CsrfToken('authenticate'$credentials['csrf_token']);
  158.         if (!$this->csrfTokenManager->isTokenValid($token)) {
  159.             throw new InvalidCsrfTokenException();
  160.         }
  161.         // Check if username is in database
  162.         $user $this->clientHelper->getUsernameData($credentials);
  163.         if(!$user){
  164.             return false;
  165.         }
  166.         $user $this->createUser($credentials);
  167.         $email_to=$credentials['email'];
  168.         //$email_to= 'desarrollo@vlc.auren.es';
  169.         $mailer_from $_ENV['MAILER_FROM'];
  170.         $subject 'Auren Sistemas Extranet- Verificación de email';
  171.         // Configure email and send it
  172.         $transport = (new \Swift_SmtpTransport($_ENV['MAIL_HOST'], $_ENV['MAIL_PORT'], 'tls' ))
  173.             ->setUsername($_ENV['MAIL_USER'])
  174.             ->setPassword($_ENV['MAIL_PASSWORD'])
  175.             ->setStreamOptions([
  176.                 'ssl' => [
  177.                     'allow_self_signed' => true,
  178.                     'verify_peer' => false
  179.                 ]
  180.             ]);
  181.         $mailer = new \Swift_Mailer($transport);
  182.         $message = (new \Swift_Message($subject))
  183.             ->setFrom($mailer_from)
  184.             ->setTo($email_to)
  185.             ->setBody(
  186.                 $this->renderView(
  187.                     'emails/user/validation.html.twig',
  188.                     [
  189.                         'user'=>$user,
  190.                     ]
  191.                 ),
  192.                 'text/html'
  193.             )
  194.         ;
  195.         $success $mailer->send($message);
  196.         $response = [
  197.             'sended'=>$success,
  198.             'email'=>$email_to,
  199.         ];
  200.         return new JsonResponse ($responseResponse::HTTP_OK);
  201.     }
  202.     public function sendRecoverPasswordEmail(Request $request){
  203.         // Get Credentials
  204.         $credentials = [
  205.             'email' => $request->request->get('_username'),
  206.             'username' => $request->request->get('_username'),
  207.             'csrf_token' => $request->request->get('_csrf_token'),
  208.         ];
  209.         // Check if token is correct
  210.         $token = new CsrfToken('authenticate'$credentials['csrf_token']);
  211.         if (!$this->csrfTokenManager->isTokenValid($token)) {
  212.             throw new InvalidCsrfTokenException();
  213.         }
  214.         // Check if username is in database
  215.         $user $this->clientHelper->getUsernameData($credentials);
  216.         if(!$user){
  217.             $response = [
  218.                 'sended'=>false,
  219.                 'text'=>'No se puede recuperar la contraseña para su tipo de usuario',
  220.             ];
  221.             return new JsonResponse ($responseResponse::HTTP_OK);
  222.         }
  223.         $user $this->setNewUserToken($credentials);
  224.         $email_to=$credentials['email'];
  225.         //$email_to= 'svalero@vlc.auren.es';
  226.         $mailer_from $_ENV['MAILER_FROM'];
  227.         $subject 'Auren Sistemas Extranet- Recuperación de contraseña';
  228.         // Configure email and send it
  229.         $transport = (new \Swift_SmtpTransport($_ENV['MAIL_HOST'], $_ENV['MAIL_PORT'], 'tls' ))
  230.             ->setUsername($_ENV['MAIL_USER'])
  231.             ->setPassword($_ENV['MAIL_PASSWORD'])
  232.             ->setStreamOptions([
  233.                 'ssl' => [
  234.                     'allow_self_signed' => true,
  235.                     'verify_peer' => false
  236.                 ]
  237.             ]);
  238.         $mailer = new \Swift_Mailer($transport);
  239.         $message = (new \Swift_Message($subject))
  240.             ->setFrom($mailer_from)
  241.             ->setTo($email_to)
  242.             ->setBody(
  243.                 $this->renderView(
  244.                     'emails/user/recover_password.html.twig',
  245.                     [
  246.                         'user'=>$user,
  247.                     ]
  248.                 ),
  249.                 'text/html'
  250.             )
  251.         ;
  252.         $success $mailer->send($message);
  253.         $response = [
  254.             'sended'=>$success,
  255.             'email'=>$email_to,
  256.         ];
  257.         return new JsonResponse ($responseResponse::HTTP_OK);
  258.     }
  259.     public function loginRecoverPassword($tokenRequest $request){
  260.         $user $this->userRepository->findOneBy(['token'=>$token]);
  261.         if(!$user){
  262.             return false;
  263.         }
  264.         $userData $this->clientHelper->getUsernameSingleData($user->getEmail());
  265.         $form=$this->createForm(RecoverPasswordType::class, $user);
  266.         $form->handleRequest($request);
  267.         if ($form->isSubmitted() && $form->isValid()) {
  268.             $entityManager $this->getDoctrine()->getManager();
  269.             $user $form->getData();
  270.             $user->setPassword($this->userPasswordEncoder->encodePassword(
  271.                 $user,
  272.                 $user->getPassword()
  273.             ));
  274.             $user->setToken(null);
  275.             $entityManager->persist($user);
  276.             $entityManager->flush();
  277.             return $this->redirectToRoute('dashboard');
  278.         }
  279.         return $this->render('security/recover_password.html.twig', [
  280.             'form' => $form->createView(),
  281.             'user_data' => $userData,
  282.             'user' => $user
  283.         ]);
  284.     }
  285.     public function createUser($credentials){
  286.         $entityManager $this->getDoctrine()->getManager();
  287.         $token $this->generateToken();
  288.         $userData $this->clientHelper->getUsernameSingleData($credentials['email']);
  289.         $user = new User();
  290.         $user->setEmail($credentials['email']);
  291.         $user->setName($userData['PContacto']);
  292.         $user->setRoles(array('ROLE_USER'));
  293.         $user->setToken($token);
  294.         $user->setActive(false);
  295.         $entityManager->persist($user);
  296.         $entityManager->flush();
  297.         return $user;
  298.     }
  299.     public function setNewUserToken($credentials){
  300.         $entityManager $this->getDoctrine()->getManager();
  301.         $token $this->generateToken();
  302.         $user $this->userRepository->findOneBy(['email'=>$credentials['email']]);
  303.         $user->setToken($token);
  304.         $entityManager->persist($user);
  305.         $entityManager->flush();
  306.         return $user;
  307.     }
  308.     public function generateToken()
  309.     {
  310.         return rtrim(strtr(base64_encode(random_bytes(32)), '+/''-_'), '=');
  311.     }
  312. }