container = $container; $this->em = $em; } protected function configure() { $this ->setName('app:synchroUsers') ->setDescription('Synchronisation des Utilisateurs') ->setHelp('Synchronisation des Utilisateurs') ->addArgument('simulate', InputArgument::OPTIONAL, 'true to simulate / false to run') ->addArgument('cronid', InputArgument::OPTIONAL, 'ID Cron Job') ->addArgument('lastchance', InputArgument::OPTIONAL, 'Lastchance to run the cron') ; } protected function execute(InputInterface $input, OutputInterface $output) { $this->output = $output; $this->filesystem = new Filesystem(); $this->rootlog = $this->container->get('kernel')->getLogDir()."/"; $this->writelnred(''); $this->writelnred('== app:synchroUsers'); $this->writelnred('=========================================================================================================='); $simulate = $input->getArgument('simulate'); if($simulate=="") $simulate="true"; if($simulate!="true"&&$simulate!="false") { $this->writeln('Paramétre incorrect'); return; } $simulate=($simulate=="true"); $this->writeln(''); if($simulate) $this->writeln('** SIMULATION'); else $this->writeln('** REEL'); // Synchro if($this->container->getParameter('appMasteridentity')=="LDAP") $this->synchroLdap($simulate); else $this->synchroNinegate($simulate); return 1; } protected function synchroLdap($simulate) { $this->writeln(''); $this->writeln('====================================================='); $this->writeln('== SYNCHONISATION ANNUAIRE =========================='); $this->writeln('====================================================='); $this->ldap = $this->container->get('app.ldap.service'); $this->writeln(''); $this->writeln('====================================================='); $this->writeln('== SYNCHONISATION LDAP TO BUNDLE ===================='); $this->writeln('====================================================='); $this->ldap_basedn = $this->container->getParameter('ldapBasedn'); $ldap_username = $this->container->getParameter('ldapUsername'); $ldap_firstname = $this->container->getParameter('ldapFirstname'); $ldap_lastname = $this->container->getParameter('ldapLastname'); $ldap_email = $this->container->getParameter('ldapEmail'); $ldap_admins = $this->container->getParameter('ldapAdmins'); $ldap_model = $this->container->getParameter('ldapModel'); $fieldstoread = array($ldap_username,$ldap_firstname,$ldap_lastname,$ldap_email); $ldapusers = array(); $ldapmails = array(); // Suppression des groupe ninegate $groups=$this->em->getRepository("App:Group")->findAll(); foreach($groups as $group) { if($group->getIdexternal()) { $this->writeln(" - Suppression dans Bundle >> ".$group->getName()); if(!$simulate) { $this->em->remove($group); $this->em->flush(); } } } if($ldap_model=="scribe") { $this->writeln(''); $this->writeln('== SCRIBE ==========================================='); $this->writeln(''); $this->writeln('== PROFILS =========================================='); // Eleves $ldapfilter="(&(uid=*)(ENTPersonProfils=eleve))"; $label="PROFIL - Elèves"; $this->writeln(" - $label"); if(!$simulate) $this->addmodGroup($label,$ldapfilter,false); // Enseignants $ldapfilter="(|(&(uid=*)(ENTPersonProfils=enseignant))(&(uid=*)(typeadmin=0))(&(uid=*)(typeadmin=2)))"; $label="PROFIL - Enseignants"; $this->writeln(" - $label"); if(!$simulate) $this->addmodGroup($label,$ldapfilter,true); // Responsables $ldapfilter="(&(uid=*)(ENTPersonProfils=responsable))"; $label="PROFIL - Responsables"; $this->writeln(" - $label"); if(!$simulate) $this->addmodGroup($label,$ldapfilter,false); // Administratifs $ldapfilter="(&(uid=*)(ENTPersonProfils=administratif))"; $label="PROFIL - Administratifs"; $this->writeln(" - $label"); if(!$simulate) $this->addmodGroup($label,$ldapfilter,true); // Classes $this->writeln(''); $this->writeln('== CLASSES =========================================='); $results = $this->ldap->search("type=Classe", ['cn','description','gidNumber'], $this->ldap_basedn); foreach($results as $result) { $cn=$result["cn"]; $ldapfilter="(|(&(type=Classe)(cn=$cn))(&(type=Equipe)(cn=profs-$cn))(&(ENTPersonProfils=Administratif)(divcod=$cn)))"; $label="CLASSE - ".$result["cn"]; $this->writeln(" - $label"); if(!$simulate) $this->addmodGroup($label,$ldapfilter,true); } // Elèves des Classes $this->writeln(''); $this->writeln('== ELEVES DES CLASSES =========================================='); $results = $this->ldap->search("type=Classe", ['cn','description','gidNumber'], $this->ldap_basedn); foreach($results as $result) { $cn=$result["cn"]; $ldapfilter="(&(type=Classe)(cn=$cn))"; $label="ELEVES DE LA CLASSE - ".$result["cn"]; $this->writeln(" - $label"); if(!$simulate) $this->addmodGroup($label,$ldapfilter,false); } // Professeurs des Classes $this->writeln(''); $this->writeln('== PROFESSEURS DES CLASSES =========================================='); $results = $this->ldap->search("type=Classe", ['cn','description','gidNumber'], $this->ldap_basedn); foreach($results as $result) { $cn=$result["cn"]; $ldapfilter="(|(&(type=Equipe)(cn=profs-$cn))(&(ENTPersonProfils=Administratif)(divcod=$cn)))"; $label="PROFESSEURS DE LA CLASSE - ".$result["cn"]; $this->writeln(" - $label"); if(!$simulate) $this->addmodGroup($label,$ldapfilter,false); } // Options $this->writeln(''); $this->writeln('== OPTIONS =========================================='); $cn=$result["cn"]; $results = $this->ldap->search("type=Option", ['cn','description','gidNumber'], $this->ldap_basedn); foreach($results as $result) { $ldapfilter="(|(&(type=Option)(cn=$cn))(&(type=Equipe)(cn=profs-$cn))(&(ENTPersonProfils=Administratif)(divcod=$cn)))"; $label="OPTION - ".$result["cn"]; $this->writeln(" - $label"); if(!$simulate) $this->addmodGroup($label,$ldapfilter,true); } $ldap_filtergroup="(type=Groupe)"; $ldap_filteruser="(&(uid=*)(objectclass=inetOrgPerson)(!(description=Computer)))"; } else { $ldap_filtergroup=$this->container->getParameter('ldapFiltergroup'); $ldap_filteruser=$this->container->getParameter('ldapFilteruser'); } // Groupes $this->writeln(''); $this->writeln('== GROUPES =========================================='); $results = $this->ldap->search($ldap_filtergroup, ['cn','description','gidNumber'], $this->ldap_basedn); foreach($results as $result) { $cn=$result["cn"]; $ldapfilter="(&(&".$ldap_filtergroup.")(cn=$cn))"; $label="GROUPE - ".$result["cn"]; $this->writeln(" - $label"); if(!$simulate) $this->addmodGroup($label,$ldapfilter,true); } $this->writeln(''); $this->writeln('== USERS ============================================'); // On stocke tout les email déjà existant $this->writeln('== Stocker les emails utilisateurs existants'); $users=$this->em->createQueryBuilder()->select('table.email')->from('App:User','table')->getQuery()->getArrayResult(); foreach($users as $user) { array_push($ldapmails,$user["email"]); } // Sur l'ensemble des utilisateurs de l'anuaire $this->writeln("== Récupération des utilisateurs de l'annuaire"); $results = $this->ldap->search($ldap_filteruser, $fieldstoread, $this->ldap_basedn); $nbuserstotal=count($results); $nbusers=0; $tberrors=[]; // Pour chaque utilisateur ldap $this->writeln('== Traitement des utilisateurs'); foreach($results as $result) { // Compteur de users $nbusers++; // Formatage du résultat if(is_array($result[$ldap_username])) { $result[$ldap_username]=$result[$ldap_username][0]; } $result[$ldap_username]=utf8_encode($result[$ldap_username]); if(!isset($result[$ldap_lastname])) $result[$ldap_lastname] = ""; if(!isset($result[$ldap_firstname])) $result[$ldap_firstname] = ""; if(!array_key_exists($ldap_email,$result)||empty($result[$ldap_email])) $result[$ldap_email]=$result[$ldap_username]."@nomail.fr"; $result[$ldap_email]=strtolower($result[$ldap_email]); $result[$ldap_email]=utf8_encode($result[$ldap_email]); // On sauvegarde ce user if(in_array($result[$ldap_username],$ldapusers)) { $this->writelnred(" - Création dans Bundle impossible >> ".$result[$ldap_username]." deux users avec le meme uid"); continue; } array_push($ldapusers,$result[$ldap_username]); // Création ou Modification du user $user=$this->em->getRepository('App:User')->findOneBy(array('username' => $result[$ldap_username])); if(!$user) { if(empty($result[$ldap_email])) array_push($tberrors," - Création dans Bundle impossible >> ".$result[$ldap_username]." sans email"); else { if(in_array($result[$ldap_email],$ldapmails)) array_push($tberrors," - Création dans Bundle impossible >> ".$result[$ldap_username]." un autre utilisateur a déjà ce mail = ".$result[$ldap_email]); else { array_push($ldapmails,$result[$ldap_email]); $this->writeln(" - Création dans Bundle >> ".$result[$ldap_username]); if(!$simulate) $this->addUser($result[$ldap_username],$result[$ldap_firstname],$result[$ldap_lastname],$result[$ldap_email],$ldap_admins); } } } else { $toadmin=false; if(in_array($result[$ldap_username],$ldap_admins)&&!in_array("ROLE_ADMIN",$user->getRoles())) $toadmin=true; if($user->getLastname()!=$result[$ldap_lastname]||$user->getFirstname()!=$result[$ldap_firstname]||$user->getEmail()!=$result[$ldap_email]||$toadmin) { $usermail=$this->em->getRepository('App:User')->findOneBy(array('email' => $result[$ldap_email])); if($usermail&&$usermail!=$user) { array_push($tberrors," - Modification dans Bundle impossible >> ".$result[$ldap_username]." un autre utilisateur a déjà ce mail = ".$result[$ldap_email]); } else { $this->writeln(" - Modification dans Bundle >> ".$result[$ldap_username]); if(!$simulate) $this->modUser($user,$result[$ldap_username],$result[$ldap_firstname],$result[$ldap_lastname],$result[$ldap_email],$ldap_admins); } } } if($nbusers%1000==0) $this->writeln(" == Nombre d'utilisateurs traités = $nbusers sur $nbuserstotal =="); } if(!$simulate) { $this->writeln(" == Nombre d'utilisateurs traités = $nbusers sur $nbuserstotal =="); $this->em->flush(); } foreach($tberrors as $error) { $this->writelnred(" == ERROR == $error"); } $this->writeln(''); $this->writeln('== USERS GROUP ======================================'); $groups=$this->em->getRepository('App:Group')->findAll(); foreach($groups as $group) { if(!$group->getldapfilter()) continue; $ldapusersgroup=array(); $ldapfilter=$group->getLdapfilter(); $this->writeln(''); $this->writeln('== '.$group->getName()); if(!is_null($ldapfilter)) { $results = $this->ldap->search($ldapfilter,[$ldap_username,"memberuid"] , $this->ldap_basedn); foreach($results as $result) { if(isset($result["memberuid"])) { // Si memberid est un tableau il y a plusieur user dedans if(is_array($result["memberuid"])) { foreach($result["memberuid"] as $key => $value) { if(is_int($key)) { $user=$this->em->getRepository('App:User')->findOneBy(array('username' => $value)); if($user) { array_push($ldapusersgroup,$value); $this->writeln(" - Rattacher >> ".$value); if(!$simulate) $this->addtoGroup($user,$group); } } } } // sinon m'a qu'un seul uid else { $user=$this->em->getRepository('App:User')->findOneBy(array('username' => $result["memberuid"])); if($user) { array_push($ldapusersgroup,$result["memberuid"]); $this->writeln(" - Rattacher >> ".$result["memberuid"]); if(!$simulate) $this->addtoGroup($user,$group); } } } if(isset($result[$ldap_username])) { $user=$this->em->getRepository('App:User')->findOneBy(array('username' => $result[$ldap_username])); if($user) { array_push($ldapusersgroup,$result[$ldap_username]); $this->writeln(" - Rattacher >> ".$result[$ldap_username]); if(!$simulate) $this->addtoGroup($user,$group); } } } foreach($group->getUsers() as $member) { if(!in_array($member->getUsername(),$ldapusersgroup)) { $this->writeln(" - Détattacher >> ".$member->getUsername()); if(!$simulate) { $this->em->remove($member); $this->em->flush(); } } } } } $this->writeln(''); $this->writeln('====================================================='); $this->writeln('== SYNCHONISATION BUNDLE TO LDAP ===================='); $this->writeln('====================================================='); $this->writeln(''); $this->writeln('== USERS ============================================'); // Pour chaque utilisateur de la base //$users=$this->em->getRepository('App:User')->findAll(); $datas=$this->em->createQueryBuilder()->select('table.id,table.username')->from('App:User','table')->getQuery()->getArrayResult(); $nbusers=0; // tentative d'optimisation $flipped = array_flip($ldapusers); foreach($datas as $data) { $nbusers++; // Si l'utilisateur n'est pas dans la liste des users ldap : on le supprime if(!isset($flipped[$data["username"]])) { $user=$this->em->getRepository('App:User')->find($data["id"]); if($user->getUsername()=="admin") $this->writeln(" - Ne jamais supprimer >> ".$user->getUsername()); else { $this->writeln(" - Suppression dans Bundle >> ".$user->getUsername()); if(!$simulate) { $this->em->remove($user); $this->em->flush(); } } } else { //on peut unset les recherches suivantes seront plus rapide unset($flipped[$data["username"]]); } if($nbusers%1000==0) $this->writelnred(" == Nombre d'utilisateurs traités = $nbusers=="); } $this->writeln(''); $this->writeln('== GROUPS ============================================'); $groups=$this->em->getRepository("App:Group")->findAll(); foreach($groups as $group) { if(!$group->getLdapfilter()) continue; if(!in_array($group->getId(),$this->ldapgroups)) { $this->writeln(" - Suppression dans Bundle >> ".$group->getName()); if(!$simulate) { $this->em->remove($group); $this->em->flush(); } } } $this->writeln(''); } protected function synchroNinegate($simulate) { $this->writeln(''); $this->writeln('====================================================='); $this->writeln('== SYNCHONISATION NINEGATE =========================='); $this->writeln('====================================================='); $this->writeln(''); $this->writeln('====================================================='); $this->writeln('== SYNCHONISATION NINEGATE TO BUNDLE ================'); $this->writeln('====================================================='); // Suppression des groupe annuaire $groups=$this->em->getRepository("App:Group")->findAll(); foreach($groups as $group) { if($group->getLdapfilter()) { $this->writeln(" - Suppression dans Bundle >> ".$group->getName()); if(!$simulate) { $this->em->remove($group); $this->em->flush(); } } } $appmasterurl = $this->container->getParameter("appMasterurl"); $appmasterkey = $this->container->getParameter("appMasterkey"); // Généraltion de l'urol de communication if(stripos($appmasterurl,"/")===0) { $url="http://".$this->container->getParameter("appWeburl").$appmasterurl; } else $url=$appmasterurl; // Entete $headers = ['Accept' => 'application/json']; $query = []; // Paramétrage unirest \Unirest\Request::verifyPeer(false); \Unirest\Request::verifyHost(false); \Unirest\Request::timeout(5); // Login sans proxy try{ $response = \Unirest\Request::post($url.'/rest/login',$headers,["key"=>$appmasterkey]); } catch (\Exception $e) { // On tente avec le proxy s'il y en a un $proxyUse = $this->container->getParameter("proxyUse"); if($proxyUse) { $proxyHost = $this->container->getParameter("proxyHost"); $proxyPort = $this->container->getParameter("proxyPort"); \Unirest\Request::proxy($proxyHost, $proxyPort, CURLPROXY_HTTP, true); try{ $response = \Unirest\Request::post($url.'/rest/login/'.$appmasterkey,$headers,$query); } catch (\Exception $e) { die("Erreur de communication API = ".$e->getMessage()."\n"); } } else { die("Erreur de communication API = ".$e->getMessage()."\n"); } } if($response->code!="200") die("Erreur sur clé API\n"); $this->writeln(''); $this->writeln('== GROUPS ============================================'); // Récupération des informations groups issus du masteridentity try{ $response = \Unirest\Request::post($url.'/rest/groups',$headers,["key"=>$appmasterkey]); } catch (\Exception $e) { die("Erreur de communication API = ".$e->getMessage()."\n"); } $lstgroups=[]; if($response->code=="200" && is_object($response->body)) { $apigroups=$response->body; foreach($apigroups as $apigroup) { array_push($lstgroups,$apigroup->id); $group=$this->em->getRepository("App:Group")->findOneBy(["idexternal"=>$apigroup->id]); $this->writeln(" - ".$apigroup->name); if(!$simulate) { if(!$group) { $group = new Group(); $group->setIdexternal($apigroup->id); } $group->setName($apigroup->name); $this->em->persist($group); $this->em->flush(); } } } else die("Erreur de communication = ".print_r($response,true)); $this->writeln(''); $this->writeln('== USERS ============================================'); // Récupération des informations utilisateurs issus du masteridentity try{ $response = \Unirest\Request::post($url.'/rest/users',$headers,["key"=>$appmasterkey]); } catch (\Exception $e) { die("Erreur de communication API = ".$e->getMessage()."\n"); } $lstusers=[]; if($response->code=="200"&&is_object($response->body)) { $apiusers=$response->body; foreach($apiusers as $apiuser) { array_push($lstusers,$apiuser->username); $user=$this->em->getRepository("App:User")->findOneBy(["username"=>$apiuser->username]); $this->writeln(" - ".$apiuser->username); if(!$simulate) { if(!$user) { $user = new User(); $key = Uuid::uuid4(); $user->setUsername($apiuser->username); $user->setPassword("NOPASSWORD"); $user->setApiKey($key); } $user->setLastname($apiuser->lastname); $user->setFirstname($apiuser->firstname); $user->setEmail($apiuser->email); $user->setAvatar($apiuser->avatar); if(in_array($apiuser->username,$this->container->getParameter("ldapAdmins"))) $role="ROLE_ADMIN"; else $role=($apiuser->role=="ROLE_ANIM"?"ROLE_MASTER":$apiuser->role); if(!$user->hasRole($role)) { $roles=$user->getRoles(); array_push($roles,$role); $user->setRoles($roles); } $this->em->persist($user); $this->em->flush(); } } } else die("Erreur de communication"); $this->writeln(''); $this->writeln('== USERS GROUP ======================================'); $groups=$this->em->getRepository('App:Group')->findAll(); $tabgroups = json_decode(json_encode($apigroups), true); foreach($groups as $group) { if(!$group->getIdexternal()) continue; $this->writeln($group->getName()); $usergroups=[]; if($tabgroups[$group->getIdexternal()]) $usergroups = $tabgroups[$group->getIdexternal()]["users"]; $tbusers=[]; foreach($usergroups as $user) { array_push($tbusers,$user["username"]); // On recherche le user en question $user=$this->em->getRepository("App:User")->findOneBy(["username"=>$user["username"]]); if($user) { $this->writeln(" - Rattachement ".$user->getUsername()); if(!$simulate) { if(!$group->getUsers()->contains($user)) { $group->addUser($user); } } } } foreach($group->getUsers() as $user) { if(!in_array($user->getUsername(),$tbusers)) { $this->writeln(" - Détachement ".$user->getUsername()); if(!$simulate) { $group->removeUser($user); } } } $this->em->persist($group); $this->em->flush(); } $this->writeln(''); $this->writeln('====================================================='); $this->writeln('== SYNCHONISATION BUNDLE TO NINEGATE ================'); $this->writeln('====================================================='); $this->writeln(''); $this->writeln('== USERS ============================================'); // Pour chaque utilisateur de la base $users=$this->em->getRepository("App:User")->findAll(); foreach($users as $user) { if(!in_array($user->getUsername(),$lstusers)) { if($user->getUsername()=="admin") $this->writeln(" - Ne jamais supprimer >> ".$user->getUsername()); else { $this->writeln(" - Suppression dans Bundle >> ".$user->getUsername()); if(!$simulate) { $this->em->remove($user); $this->em->flush(); } } } } $this->writeln(''); $this->writeln('== GROUPS ============================================'); $groups=$this->em->getRepository("App:Group")->findAll(); foreach($groups as $group) { if(!$group->getIdexternal()) continue; if(!in_array($group->getIdexternal(),$lstgroups)) { $this->writeln(" - Suppression dans Bundle >> ".$group->getName()); if(!$simulate) { $this->em->remove($group); $this->em->flush(); } } } $this->writeln(''); } private function writelnred($string) { $this->output->writeln(''.$string.''); $this->filesystem->appendToFile($this->rootlog.'cron.log', $string."\n"); } private function writeln($string) { $this->output->writeln($string); $this->filesystem->appendToFile($this->rootlog.'cron.log', $string."\n"); } protected function addmodGroup($label,$ldapfilter,$fgcanshare) { $group=$this->em->getRepository('App:Group')->findOneBy(array('name' => $label)); if(!$group) { $group=new Group(); } $group->setName($label); $group->setLdapfilter($ldapfilter); $this->em->persist($group); $this->em->flush(); array_push($this->ldapgroups,$group->getId()); } protected function addtoGroup($user,$group) { if(!$group->getUsers()->contains($user)) { $group->addUser($user); $this->em->persist($group); $this->em->flush(); } } protected function addUser($username,$firstname,$lastname,$email,$usersadmin) { $user = new User(); $key = Uuid::uuid4(); $user->setUsername($username); $user->setPassword("NOPASSWORD"); $user->setLastname($lastname); $user->setFirstname($firstname); $user->setEmail($email); $user->setApiKey($key); // Definition du role if(in_array($username,$usersadmin)) $role="ROLE_ADMIN"; else { $ldapfilter="(|(&(uid=".$user->getUsername().")(ENTPersonProfils=enseignant))(&(uid=".$user->getUsername().")(typeadmin=0))(&(uid=".$user->getUsername().")(typeadmin=2)))"; $results = $this->ldap->search($ldapfilter, ['uid'], $this->ldap_basedn); if($results) $role="ROLE_MASTER"; else $role="ROLE_USER"; } if(!$user->hasRole($role)) { $roles=$user->getRoles(); array_push($roles,$role); $user->setRoles($roles); } $this->em->persist($user); $this->em->flush(); } protected function modUser($user,$username,$firstname,$lastname,$email,$usersadmin) { $user->setLastname($lastname); $user->setFirstname($firstname); $user->setEmail($email); // Definition du role if(in_array($username,$usersadmin)) $role="ROLE_ADMIN"; else { $ldapfilter="(|(&(uid=".$user->getUsername().")(ENTPersonProfils=enseignant))(&(uid=".$user->getUsername().")(typeadmin=0))(&(uid=".$user->getUsername().")(typeadmin=2)))"; $results = $this->ldap->search($ldapfilter, ['uid'], $this->ldap_basedn); if($results) $role="ROLE_MASTER"; else $role="ROLE_USER"; } if(!$user->hasRole($role)) { $roles=$user->getRoles(); array_push($roles,$role); $user->setRoles($roles); } $this->em->persist($user); $this->em->flush(); } }