src/Controller/SecurityController.php line 350

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  6. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  7. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  8. use Symfony\Component\EventDispatcher\EventDispatcher;
  9. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  10. use Symfony\Component\HttpFoundation\Response;
  11. use Symfony\Component\HttpFoundation\JsonResponse;
  12. use Symfony\Component\HttpKernel\KernelInterface;
  13. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  14. use Doctrine\Persistence\ManagerRegistry;
  15. use Ramsey\Uuid\Uuid;
  16. use App\Service\LdapService;
  17. use App\Entity\User;
  18. use App\Entity\Group;
  19. use App\Form\LoginType;
  20. class SecurityController extends AbstractController
  21. {
  22.     private $appKernel;
  23.     private $tokenstorage;
  24.     private $ldapservice;
  25.     public function __construct(KernelInterface $appKernelTokenStorageInterface $tokenstorageLdapService $ldapservice)
  26.     {
  27.         $this->appKernel $appKernel;
  28.         $this->tokenstorage $tokenstorage;
  29.         $this->ldapservice $ldapservice;
  30.     }
  31.     public function login(Request $requestAuthenticationUtils $authenticationUtilsManagerRegistry $em)
  32.     {
  33.         switch ($this->getParameter('mode_auth')) {
  34.             case 'SQL':
  35.                 return $this->loginSQL($request$authenticationUtils$em);
  36.                 break;
  37.             case 'CAS':
  38.                 return $this->loginCAS($request$authenticationUtils$em);
  39.                 break;
  40.             case 'LDAP':
  41.                 return $this->loginLDAP($request$authenticationUtils$em);
  42.                 break;
  43.         }
  44.     }
  45.     public function loginSQL(Request $requestAuthenticationUtils $authenticationUtilsManagerRegistry $em)
  46.     {
  47.         return $this->render('Security\loginSQL.html.twig', [
  48.             'last_username' => $authenticationUtils->getLastUsername(),
  49.             'error' => $authenticationUtils->getLastAuthenticationError(),
  50.             'useheader' => false,
  51.             'usemenu' => false,
  52.             'usesidebar' => false
  53.         ]);
  54.     }
  55.     public function loginLDAP(Request $requestAuthenticationUtils $authenticationUtilsManagerRegistry $em)
  56.     {
  57.         // Création du formulaire
  58.         $form $this->createForm(LoginType::class);
  59.         // Récupération des data du formulaire
  60.         $form->handleRequest($request);
  61.         // Affichage du formulaire
  62.         return $this->render('Security/loginLDAP.html.twig', [
  63.             'useheader' => false,
  64.             'usemenu' => false,
  65.             'usesidebar' => false,
  66.             'form' => $form->createView(),
  67.             'error' => "",
  68.         ]);
  69.     }
  70.     public function ldapcheckuser(Request $requestAuthenticationUtils $authenticationUtilsManagerRegistry $em)
  71.     {         
  72.         $username $request->get('login')['username'];
  73.         $password $request->get('login')['password'];
  74.         // Récupération de la cible de navigation
  75.         $redirect $request->getSession()->get('_security.main.target_path');
  76.         // L'utilisateur se co à l'annuaire
  77.         $userldap $this->ldapservice->userconnect($username$password);
  78.         if ($userldap) {
  79.             $user=$em->getRepository("App\Entity\User")->findOneBy(["username"=>$username]);
  80.             // Il n'y a pas d'autosubmit / autoupdate : il doit se faire par synchronisation
  81.             if($user) {
  82.                 // Autoconnexion
  83.                 return $this->autoconnexion($user$redirect$request);                     
  84.             }            
  85.         }
  86.       
  87.         return $this->redirect($this->generateUrl('app_core_login'));               
  88.     }
  89.     public function loginCAS(Request $requestAuthenticationUtils $authenticationUtilsManagerRegistry $em)
  90.     {
  91.         // Récupération de la cible de navigation
  92.         $redirect $request->getSession()->get('_security.main.target_path');
  93.         // Masteridentity
  94.         $masteridentity=$this->getParameter("masteridentity");
  95.         // Init Client CAS
  96.         // \phpCAS::setDebug("/var/log/phpcas/phpCAS-ninegate.log");
  97.         $url=$this->getHost($request);
  98.         $url=str_replace("http://",$this->getParameter("protocole")."://",$url);
  99.         $url=str_replace("https://",$this->getParameter("protocole")."://",$url);
  100.         if($this->getParameter("cas_type")=="client")
  101.             @\phpCAS::client(CAS_VERSION_2_0$this->getParameter('cas_host'), intval($this->getParameter('cas_port')), is_null($this->getParameter('cas_path')) ? '' $this->getParameter('cas_path'), $urlfalse);
  102.         else
  103.             @\phpCAS::proxy(CAS_VERSION_2_0$this->getParameter('cas_host'), intval($this->getParameter('cas_port')), is_null($this->getParameter('cas_path')) ? '' $this->getParameter('cas_path'), $urlfalse);
  104.         
  105.         \phpCAS::setNoCasServerValidation();
  106.         
  107.         // Authentification
  108.         \phpCAS::forceAuthentication();
  109.         // Récupération UID
  110.         $username = \phpCAS::getUser();
  111.         // Récupération Attribut
  112.         $attributes = \phpCAS::getAttributes();
  113.         // Init
  114.         $email "";
  115.         $lastname "";
  116.         $firstname "";
  117.         // Rechercher l'utilisateur
  118.         if(isset($attributes[$this->getParameter('user_attr_cas_username')]))
  119.             $username $attributes[$this->getParameter('user_attr_cas_username')];
  120.         if(isset($attributes[$this->getParameter('user_attr_cas_mail')]))
  121.             $email $attributes[$this->getParameter('user_attr_cas_mail')];
  122.         if(isset($attributes[$this->getParameter('user_attr_cas_lastname')]))
  123.             $lastname $attributes[$this->getParameter('user_attr_cas_lastname')];
  124.         if(isset($attributes[$this->getParameter('user_attr_cas_firstname')]))
  125.             $firstname $attributes[$this->getParameter('user_attr_cas_firstname')];
  126.         $user $em->getRepository('App\Entity\User')->findOneBy(array("username"=>$username));
  127.         $exists $user true false;
  128.         if (!$exists) {
  129.             if($masteridentity=="SQL") {
  130.                 // C'est pas normal que l'on puisse se connecter alors que l'utilisateur n'est pas connu en base
  131.                 // La base étant le maitre de l'identité
  132.                 throw $this->createNotFoundException('Permission denied');
  133.             }
  134.             if($masteridentity=="LDAP") {
  135.                 // Normalement la synchronisation des comptes aurait du générer le compte en base c'est donc pas normal
  136.                 // Peut-être juste relancer une synchronisation
  137.                 // On tente une synchronisation via methode SSO
  138.                 $masteridentity="SSO";
  139.                 // throw $this->createNotFoundException('Permission denied. Need to synchronize LDAP ? Contact your administrator');
  140.             }
  141.             if($masteridentity=="SSO") {
  142.                 if(empty($email)) $email $username."@nomail.com";
  143.                 // On s'assure qu'il n'y a pas déjà un utilisateur avec le même mail
  144.                 $usermail $em->getRepository('App\Entity\User')->findOneBy(array("email"=>$email));
  145.                 if($usermail) {
  146.                     return $this->render('App\Entity\Registration:info.html.twig', [
  147.                         'useheader'         => true,
  148.                         'usemenu'           => false,
  149.                         'usesidebar'        => false,                   
  150.                         'infotitle'         => "Première connexion",
  151.                         'info'              => "Votre compte ne peut être activé car votre adresse mel est déjà utilisée par un autre compte utilisateur.<br>Nous sommes désolés du désagrément et vous invitons à contacter un administrateur.",
  152.                         'mode'              => "error",
  153.                         'redirectto'         => "",
  154.                     ]);
  155.                 }
  156.                 // Là c'est normal que potentiellement il n'existe pas il faut donc l'autogénérer
  157.                 $user = new User();
  158.                 // On calcule le niveau01 de l'utilisateur
  159.                 $niveau01=$em->getRepository('App\Entity\Niveau01')->calculateNiveau01($attributes);
  160.                 if(!$niveau01) {
  161.                     $niveau01=$em->getRepository('App\Entity\Niveau01')->findAll()[0];
  162.                     //throw $this->createNotFoundException('Permission denied. No Organisation Niveau 01 match');
  163.                 }
  164.                 $user->setUsername($username);
  165.                 $user->setEmail($email);
  166.                 $user->setLastname($lastname);
  167.                 $user->setFirstname($firstname);
  168.                 $user->setPassword("CASPWD-".$username);
  169.                 $user->setSalt("CASPWD-".$username);
  170.                 $user->setApikey(Uuid::uuid4());
  171.                 $user->setNiveau01($niveau01);
  172.                 $user->setSiren($niveau01->getSiren());
  173.                 $user->setSiret("");
  174.                 $user->setAvatar("noavatar.png");
  175.                 $user->setVisible(true);
  176.                 $user->setAuthlevel("simple");
  177.                 $user->setBelongingpopulation("agent");
  178.                 $user->setRole("ROLE_USER");
  179.                 if(in_array($username,$this->getParameter("ldap_usersadmin")))
  180.                     $user->setRole("ROLE_ADMIN");
  181.                 $em->getManager()->persist($user);
  182.                 $em->getManager()->flush();
  183.                 // Génération auto des groupes
  184.                 $this->submitGroup($em,$attributes);
  185.                 // On calcule les groupes de l'utilisateur
  186.                 $user=$em->getRepository('App\Entity\Group')->calculateGroup($user,$attributes);
  187.             }
  188.         }
  189.         else {
  190.             // Mise à jour des valeurs uniquement si le maitre de l'identité est le SSO
  191.             if($masteridentity=="SSO") {
  192.                 // On calcule le niveau01 de l'utilisateur
  193.                 $niveau01=$em->getRepository('App\Entity\Niveau01')->calculateNiveau01($attributes);
  194.                 if(!$niveau01)
  195.                     throw $this->createNotFoundException('Permission denied. No Organisation Niveau 01 match');
  196.                 // On s'assure que le niveau 02 appartient bien au niveau 01 calculé
  197.                 $sameniveau01=(!is_null($user->getNiveau02())&&$niveau01==$user->getNiveau02()->getNiveau01());
  198.                 $user->setLastname($lastname);
  199.                 $user->setFirstname($firstname);
  200.                 $user->setEmail($email);
  201.                 if(!$sameniveau01) {
  202.                     $user->setNiveau01($niveau01);
  203.                     $user->setNiveau02(null);
  204.                 }
  205.                 if(in_array($username,$this->getParameter("ldap_usersadmin")))
  206.                     $user->setRole("ROLE_ADMIN");
  207.                 // Génération auto des groupes
  208.                 $this->submitGroup($em,$attributes);
  209.                 // On calcule les groupes de l'utilisateur
  210.                 $user=$em->getRepository('App\Entity\Group')->calculateGroup($user,$attributes);
  211.                 $em->getManager()->flush();
  212.             }
  213.         }
  214.         // Sauvegarde des attributes en session
  215.         $request->getSession()->set('attributes'$attributes);
  216.         // Sauvegarde des ssoitems en session
  217.         $ssoitems=[];
  218.         if($this->getParameter('ssosynchroitem')) {
  219.             $user_attr_cas_item=$this->getParameter('user_attr_cas_item');
  220.             if(array_key_exists($user_attr_cas_item,$attributes)) {
  221.                 if(!is_array($attributes[$user_attr_cas_item])) {
  222.                     $attributes[$user_attr_cas_item]=[$attributes[$user_attr_cas_item]];
  223.                 }
  224.                 $ssoitems=$attributes[$user_attr_cas_item];
  225.             }
  226.         }
  227.         $request->getSession()->set('ssoitems'$ssoitems);
  228.         // Autoconnexion
  229.         return $this->autoconnexion($user$redirect$request); 
  230.     }
  231.     public function logout(Request $request)
  232.     {
  233.         $auth_mode $this->getParameter('mode_auth');
  234.         switch ($auth_mode) {
  235.             case 'SQL':
  236.                 return $this->logoutSQL($request);
  237.                 break;
  238.             case 'CAS':
  239.                 return $this->logoutCAS($request);
  240.                 break;
  241.             case 'LDAP':
  242.                 return $this->logoutLDAP($request);
  243.                 break;
  244.             case 'OPENID':
  245.                 return $this->logoutOPENID($request);
  246.                 break;
  247.         }
  248.     }
  249.     public function logoutSQL(Request $request)
  250.     {
  251.         $this->tokenstorage->setToken(null);
  252.         $request->getSession()->invalidate();
  253.         return $this->redirectToRoute('app_core_home');
  254.     }
  255.     public function logoutCAS(Request $request)
  256.     {
  257.         // Init Client CAS
  258.         // \phpCAS::setDebug("/var/log/phpcas/phpCAS-ninegate.log");
  259.         $url=$this->getHost($request);
  260.         $url=str_replace("http://",$this->getParameter("protocole")."://",$url);
  261.         $url=str_replace("https://",$this->getParameter("protocole")."://",$url);
  262.         \phpCAS::client(CAS_VERSION_2_0$this->getParameter('cas_host'), intval($this->getParameter('cas_port')), is_null($this->getParameter('cas_path')) ? '' $this->getParameter('cas_path'), $urlfalse);
  263.         \phpCAS::setNoCasServerValidation();
  264.         // Logout
  265.         $url $this->generateUrl('app_core_home', [], UrlGeneratorInterface::ABSOLUTE_URL);
  266.         $url=str_replace("http://",$this->getParameter("protocole")."://",$url);
  267.         $url=str_replace("https://",$this->getParameter("protocole")."://",$url);        
  268.         \phpCAS::logout(['service' => $url]);
  269.         $this->tokenstorage->setToken(null);
  270.         $request->getSession()->invalidate();
  271.         return true;
  272.     }
  273.     public function logoutLDAP(Request $request)
  274.     {
  275.         $this->tokenstorage->setToken(null);
  276.         $request->getSession()->invalidate();
  277.         return $this->redirectToRoute('app_core_home');
  278.     }
  279.     public function checkuser(Request $request
  280.     {
  281.         $userapp $this->getUser();
  282.         $fgforceconnect $request->getSession()->get('fgforceconnect');
  283.         $modeauth=$this->getParameter('mode_auth');
  284.         if(is_null($userapp) && $fgforceconnect) {
  285.             return new Response("<script>window.location.href='".$this->generateUrl("app_core_login")."';</script>");
  286.         }
  287.         else 
  288.         {
  289.             // Mode d'authentification
  290.             switch($modeauth) {
  291.                 case "CAS":
  292.                     // Init Client CAS
  293.                     $url=$this->getHost($request);
  294.                     $url=str_replace("http://",$this->getParameter("protocole")."://",$url);
  295.                     $url=str_replace("https://",$this->getParameter("protocole")."://",$url);
  296.             
  297.                     \phpCAS::client(CAS_VERSION_2_0$this->getParameter('cas_host'), intval($this->getParameter('cas_port')), is_null($this->getParameter('cas_path')) ? '' $this->getParameter('cas_path'), $urlfalse);
  298.                     \phpCAS::setNoCasServerValidation();
  299.                     if(\phpCAS::checkAuthentication()) {
  300.                         $usercas = \phpCAS::getUser();
  301.                         // si on a un usercas mais pas de userapp c'est qu'il faut s'autoconnect
  302.                         if(!$userapp) {
  303.                             $url=$this->generateUrl('app_core_login');
  304.                             return new Response(
  305.                                 '<script>document.location.replace("'.$url.'");</script>'
  306.                             );
  307.                         }
  308.                     } 
  309.                 break;
  310.             }
  311.         }
  312.         return new Response();
  313.     }
  314.     private function autoconnexion($user$redirectRequest $request)
  315.     {
  316.         // Récupérer le token de l'utilisateur
  317.         $token = new UsernamePasswordToken($user'main'$user->getRoles());
  318.         $this->tokenstorage->setToken($token);
  319.         $request->getSession()->set('_security_main'serialize($token));
  320.         // Simuler l'evenement de connexion
  321.         $event = new InteractiveLoginEvent($request$token);
  322.         $dispatcher = new EventDispatcher();
  323.         $dispatcher->dispatch($event);
  324.         // Redirection
  325.         if ($redirect) {
  326.             return $this->redirect($redirect);
  327.         } else {
  328.             return $this->redirect($this->generateUrl('app_core_home'));
  329.         }
  330.     }
  331.     private function submitGroup($em,$attributes) {
  332.         if(!$this->getParameter('ssosynchrogroup'))
  333.             return null;
  334.         $user_attr_cas_group=$this->getParameter('user_attr_cas_group');
  335.         // Si l'utilisateur possège l'attribut groupe dans ses attributs
  336.         if(array_key_exists($user_attr_cas_group,$attributes)) {
  337.             if(!is_array($attributes[$user_attr_cas_group])) {
  338.                 $attributes[$user_attr_cas_group]=[$attributes[$user_attr_cas_group]];
  339.             }
  340.             foreach($attributes[$user_attr_cas_group] as $ssogroup) {
  341.                 $basedn=$this->getParameter('ldap_basedn');
  342.                 $name=$ssogroup;
  343.                 if($basedn!="") {
  344.                     // Si présence du basedn dans le nom du groupe = nous sommes en présence d'un DN = on récupere donc comme nom que son cn
  345.                     if(stripos($name,$basedn)!==false) {
  346.                         $tbname=explode(",",$name);
  347.                         $tbname=explode("=",$tbname[0]);
  348.                         $name=$tbname[1];
  349.                     }
  350.                 }
  351.                 
  352.                 // Recherche du groupe
  353.                 $group=$em->getRepository("App\Entity\Group")->findOneBy(["label"=>$name]);
  354.                 if(!$group) {
  355.                     $group=new Group();
  356.                     $group->setLabel($name);
  357.                     $group->setFgcancreatepage(false);
  358.                     $group->setFgcancreateblog(false);
  359.                     $group->setFgcancreatecalendar(false);
  360.                     $group->setFgcancreateproject(false);
  361.                     $group->setFgcanshare(false);
  362.                     $group->setFgopen(false);
  363.                     $group->setFgall(false);
  364.                 }
  365.                 $group->setAttributes('{"'.$user_attr_cas_group.'":"'.$ssogroup.'"}');
  366.                 $group->setFgtemplate(false);
  367.                 $em->getManager()->persist($group);
  368.                 $em->getManager()-> flush();
  369.             }
  370.         }
  371.     }
  372.     public function imapunread(Request $request) {
  373.         if($this->getParameter("active_imapunread")&&$this->getParameter("cas_type")=="proxy") {
  374.             $ip=$this->getParameter("imapundread_ip");
  375.             // Init Client CAS
  376.             // \phpCAS::setDebug("/var/log/phpcas/phpCAS-ninegate.log");
  377.             @\phpCAS::proxy(CAS_VERSION_2_0$this->getParameter('cas_host'), intval($this->getParameter('cas_port')), is_null($this->getParameter('cas_path')) ? '' $this->getParameter('cas_path'), $this->getHost($request), false);
  378.             \phpCAS::setNoCasServerValidation();
  379.             \phpCAS::forceAuthentication();
  380.         
  381.             
  382.             $pt= \phpCAS::retrievePT('imap://'.$ip,$t,$f);
  383.             $a = \phpCAS::serviceMail("{".$ip.":993/imap/ssl/novalidate-cert}","imap://".$ip,0$errc,$err,$pt);
  384.             $unseen imap_status($a"{".$ip.":993/imap/ssl/novalidate-cert}INBOX"SA_UNSEEN);
  385.             $count=$unseen->unseen;
  386.             $response = new JsonResponse($count);    
  387.         }
  388.         else 
  389.             $response = new JsonResponse("");    
  390.         return $response;
  391.     }    
  392.     public function redirectroute(Request $request$route$id) {
  393.         if($route=="app_core_home")
  394.             return $this->redirectToRoute($route,["id"=>$id]);
  395.         else 
  396.             return $this->redirectToRoute("app_core_home",["gotoroute"=>$route,"gotoid"=>$id]);
  397.     }
  398.     private function getHost($request) {
  399.         $host $request->getHost();
  400.         $protocol $request->getScheme();
  401.         $port $request->getPort();
  402.         return $protocol."://".$host.($port!=80&&$port!=443?":".$port:"");
  403.     }
  404. }