src/Security/AppCustomAuthenticator.php line 33

Open in your IDE?
  1. <?php
  2. namespace App\Security;
  3. use App\Entity\IpOk;
  4. use App\Entity\Param;
  5. use App\Entity\User;
  6. use App\Entity\UserLogin;
  7. use App\Helper\Tools;
  8. use Doctrine\ORM\EntityManagerInterface;
  9. use Symfony\Component\HttpFoundation\RedirectResponse;
  10. use Symfony\Component\HttpFoundation\Request;
  11. use Symfony\Component\HttpFoundation\Response;
  12. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  13. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  14. use Symfony\Component\Security\Core\Security;
  15. use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
  16. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
  17. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge;
  18. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
  19. use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
  20. use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
  21. use Symfony\Component\Security\Http\Util\TargetPathTrait;
  22. use Symfony\Component\DependencyInjection\ContainerInterface;
  23. use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
  24. use Twig\Environment;
  25. use Symfony\Component\Mailer\MailerInterface;
  26. use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
  27. use Symfony\Component\Mime\Email;
  28. use Symfony\Component\Mime\Address;
  29. use Symfony\Component\Notifier\ChatterInterface;
  30. use Symfony\Component\Notifier\Message\ChatMessage;
  31. class AppCustomAuthenticator extends AbstractLoginFormAuthenticator
  32. {
  33.     use TargetPathTrait;
  34.     public const LOGIN_ROUTE 'app_login';
  35.     private $entityManager;
  36.     private $container;
  37.     private $flashBag;
  38.     private $twig;
  39.     private $mailer;
  40.     private $chatter;
  41.     private UrlGeneratorInterface $urlGenerator;
  42.     public function __construct(UrlGeneratorInterface $urlGeneratorFlashBagInterface $flashBagContainerInterface $containerEntityManagerInterface $entityManagerEnvironment $twigMailerInterface $mailerChatterInterface $chatter)
  43.     {
  44.         $this->urlGenerator $urlGenerator;
  45.         $this->entityManager $entityManager;
  46.         $this->container $container;
  47.         $this->flashBag $flashBag;
  48.         $this->twig $twig;
  49.         $this->mailer $mailer;
  50.         $this->chatter $chatter;
  51.     }
  52.     public function authenticate(Request $request): Passport
  53.     {
  54.         $email $request->request->get('_username''');
  55.         $em $this->entityManager;
  56.         $smiley '';
  57.         $secureByIp $em->getRepository(Param::class)->findOneBy(['slug' => Param::SECURE_IP_LOGIN]);
  58.         if($secureByIp) {
  59.             $secureByIp $secureByIp->getValue();
  60.             // check bypass
  61.             $secureByIpBypass $em->getRepository(Param::class)->findOneBy(['slug' => Param::SECURE_IP_LOGIN_BYPASS]);
  62.             if($secureByIpBypass) {
  63.                 // if bypass is at least 2 characters long
  64.                 if(strlen($secureByIpBypass->getValue()) > 2) {
  65.                     $smiley ' ;)';
  66.                     if(isset($_GET['bypass']) && $secureByIpBypass->getValue() == $_GET['bypass']) {
  67.                         $secureByIp false;
  68.                     }
  69.                 }
  70.             }
  71.         } else {
  72.             $secureByIp true;
  73.         }
  74.         // check if IP ok
  75.         if($secureByIp && $request->request->get('_username')) {
  76.             $ipInList $em->getRepository(IpOk::class)->findOneBy(['ip' => $_SERVER['REMOTE_ADDR'], 'valid' => 1]);
  77.             if(!$ipInList) {
  78.                 $this->sendIpMail($_SERVER['REMOTE_ADDR'], $request->request->get('_username'), $smiley);
  79.             }
  80.             $ipInList->setUpdateDate(new \DateTime());
  81.             $em->persist($ipInList);
  82.             $em->flush();
  83.         }
  84.         $ip Tools::getUserIpAddr();
  85.         $query json_decode(file_get_contents('https://stats.kelkii.com/kelapi/v1/get-ip-infos/'.$ip.'/42ESDHSzea742QGHSqDQsfQSDFQZEfqSGQgghQTQRGgQRGQRFDQHSRG'), true);
  86.         $trackIp 'No traking data';
  87.         if(isset($query['city'])) {
  88.             $trackIp $query['city'].' - '$query['regionName'].' - '$query['country'].' - '$query['isp'];
  89.         }
  90.         // add user login
  91.         $userLog = new UserLogin();
  92.         $userLog->setLoginDate(new \DateTime());
  93.         $userLog->setDetail('Connexion le '.date('d/m/Y à H:i:s').' - '.$trackIp.' - '.$ip);
  94.         $userLog->setUserEmail($email);
  95.         $em->persist($userLog);
  96.         $connectedUser $em->getRepository(User::class)->findOneBy(['email' => $email ]);
  97.         if(!$connectedUser) {
  98.             $this->flashBag->add('error''Utilisateur inconnu !');
  99.             header('Location: /');
  100.             exit;
  101.         }
  102.         $request->getSession()->getFlashBag()->add('info'$connectedUser->getLastconnexiondata());
  103.         $connectedUser->setLastconnexiondata('Dernière connexion le '.date('d/m/Y à H:i:s').' - '.$trackIp.' - '.$ip);
  104.         $em->persist($connectedUser);
  105.         $em->flush();
  106.         $request->getSession()->set(Security::LAST_USERNAME$email);
  107.         return new Passport(
  108.             new UserBadge($email),
  109.             new PasswordCredentials($request->request->get('_password''')),
  110.             [
  111.                 new RememberMeBadge(),
  112.                 new CsrfTokenBadge('authenticate'$request->request->get('_csrf_token')),
  113.             ]
  114.         );
  115.     }
  116.     public function onAuthenticationSuccess(Request $requestTokenInterface $tokenstring $firewallName): ?Response
  117.     {
  118.         if ($targetPath $this->getTargetPath($request->getSession(), $firewallName)) {
  119.             return new RedirectResponse($targetPath);
  120.         }
  121.         return new RedirectResponse($this->urlGenerator->generate('homepage'));
  122.     }
  123.     protected function getLoginUrl(Request $request): string
  124.     {
  125.         return $this->urlGenerator->generate(self::LOGIN_ROUTE);
  126.     }
  127.     protected function sendIpMail($ip$username$smiley) {
  128.         $query json_decode(file_get_contents('https://stats.kelkii.com/kelapi/v1/get-ip-infos/'.$ip.'/42ESDHSzea742QGHSqDQsfQSDFQZEfqSGQgghQTQRGgQRGQRFDQHSRG'), true);
  129.         $trackIp 'No traking data';
  130.         if(isset($query['city'])) {
  131.             $trackIp $query['city'].' - '$query['regionName'].' - '$query['country'].' - '$query['isp'];
  132.         }
  133.         $postdata http_build_query(
  134.             [
  135.                 'useragent' => $_SERVER['HTTP_USER_AGENT']
  136.             ]
  137.         );
  138.         $opts = ['http' =>
  139.             [
  140.                 'method'  => 'POST',
  141.                 'header'  => 'Content-Type: application/x-www-form-urlencoded',
  142.                 'content' => $postdata
  143.             ]
  144.         ];
  145.         $context  stream_context_create($opts);
  146.         $systemInfo json_decode(file_get_contents('https://stats.kelkii.com/kelapi/v1/device-infos/42ESDHSzea742QGHSqDQsfQSDFQZEfqSGQgghQTQRGgQRGQRFDQHSRG'false$context), true);
  147.         if(isset($systemInfo['os'])) {
  148.             $trackIp .= ' - '.$systemInfo['os'].' - '.$systemInfo['browser'];
  149.         }
  150.         // create new IP
  151.         $em $this->entityManager;
  152.         $now = new \DateTime('now');
  153.         $ipok $em->getRepository(IpOk::class)->findOneBy(['ip' => $_SERVER['REMOTE_ADDR'], 'valid' => 0]);
  154.         if(!$ipok) {
  155.             $ipok = new IpOk();
  156.             $ipok->setIp($ip);
  157.             $ipok->setSlug(Tools::generateStrongPassword(30false'ld'));
  158.         } elseif ($ipok->getUpdateDate()->diff($now)->== 0) {
  159.             $this->flashBag->add('error''Check mail de sécurité !'.$smiley);
  160.             header('Location: /');
  161.             exit;
  162.         }
  163.         $ipok->setUpdateDate(new \DateTime());
  164.         $ipok->setValid(0);
  165.         $ipok->setTrack($trackIp);
  166.         $em->persist($ipok);
  167.         $em->flush();
  168.         $title "Accept IP $ip to connect to Kelkii ?";
  169.         $html $this->twig->render(
  170.             'emails/newip.html.twig',
  171.             ['ip' => $ipok'trackIp' => $trackIp'username' => $username]
  172.         );
  173.         // slack message
  174.         $urlvalidation 'https://app.kelkii.com/login/'.$ipok->getSlug();
  175.         $message = (new ChatMessage('<@Kelkii> nouvelle connexion depuis '.$ipok->getIp().' - '.$ipok->getTrack(). ' ('.$username.') : <'.$urlvalidation.'|valider>'))
  176.             ->transport('slack');
  177.         $this->chatter->send($message);
  178.         // email message
  179.         $email = (new Email())
  180.             ->from(new Address('r2d2@kelkii.com''Kelkii Connect'))
  181.             ->to(new Address('fblary@gmail.com''Florian'))
  182.             ->subject($title)
  183.             ->html($html);
  184.         try {
  185.             $this->mailer->send($email);
  186.             $this->flashBag->add('error''Mail de sécurité envoyé !'.$smiley);
  187.             header('Location: /');
  188.             exit;
  189.         } catch (TransportExceptionInterface $e) {
  190.             Tools::sendErrorToKelkii('Custom Auth - ' $titleurlencode(json_encode($e->getMessage())));
  191.             echo $e->getMessage();exit;
  192.         }
  193.     }
  194. }