nineschool/src/nineschool-1.0/src/Controller/SecurityController.php

354 lines
13 KiB
PHP
Executable File

<?php
namespace App\Controller;
use App\Entity\User;
use App\Entity\Group;
use App\Service\ldapService as ldapService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class SecurityController extends AbstractController
{
private $ldapService;
public function __construct(ldapService $ldapService)
{
$this->ldapService = $ldapService;
}
public function login(Request $request, AuthenticationUtils $authenticationUtils)
{
$auth_mode=$this->getParameter("appAuth");
switch($auth_mode) {
case "SQL":
return $this->loginMYSQL($request,$authenticationUtils);
break;
case "CAS":
return $this->loginCAS($request,$authenticationUtils);
break;
}
}
public function loginMYSQL(Request $request, AuthenticationUtils $authenticationUtils) {
// activer les activités par défaut
$this->get('session')->set('activeactivity',true);
return $this->render('Home/login.html.twig', array(
'last_username' => $authenticationUtils->getLastUsername(),
'error' => $authenticationUtils->getLastAuthenticationError(),
));
}
public function loginCAS(Request $request, AuthenticationUtils $authenticationUtils)
{
// Récupération de la cible de navigation
$redirect = $this->get('session')->get("_security.main.target_path");
// Init Client CAS
$alias=$this->getParameter('appAlias');
\phpCAS::setDebug('/var/www/html/'.$alias.'/var/log/cas.log');
\phpCAS::client(CAS_VERSION_2_0, $this->getParameter('casHost'), intval($this->getParameter('casPort')), is_null($this->getParameter('casPath')) ? '' : $this->getParameter('casPath'), false);
\phpCAS::setNoCasServerValidation();
// Authentification
\phpCAS::forceAuthentication();
// Récupération UID
$username = \phpCAS::getUser();
// Récupération Attribut
$attributes = \phpCAS::getAttributes();
// Rechercher l'utilisateur
$em = $this->getDoctrine()->getManager();
if(isset($attributes[$this->getParameter('casUsername')]))
$username = $attributes[$this->getParameter('casUsername')];
if(isset($attributes[$this->getParameter('casEmail')]))
$email = $attributes[$this->getParameter('casEmail')];
if(isset($attributes[$this->getParameter('casLastname')]))
$lastname = $attributes[$this->getParameter('casLastname')];
if(isset($attributes[$this->getParameter('casFirstname')]))
$firstname = $attributes[$this->getParameter('casFirstname')];
$user = $em->getRepository('App:User')->findOneBy(array("username"=>$username));
$exists = $user ? true : false;
if (!$exists) {
$user = new User();
$user->setUsername($username);
$user->setLastname($lastname);
$user->setFirstname($firstname);
$user->setEmail($email);
$user->setPassword("CASPWD-".$username);
$user->setSalt("CASPWD-".$username);
$em->persist($user);
$em->flush();
}
else {
if(isset($lastname)) $user->setLastname($lastname);
if(isset($firstname)) $user->setFirstname($firstname);
if(isset($email)) $user->setEmail($email);
$em->persist($user);
$em->flush();
}
// Sauvegarde des attributes en session
$this->get('session')->set('attributes', $attributes);
// Mise à jour par rapport au maitre de l'identité
$masteridentity=$this->getParameter("appMasteridentity");
if($masteridentity=="Ninegate") {
$this->updateNinegate($user);
}
else {
$this->updateLDAP($user);
}
// activer les activités par défaut
$this->get('session')->set('activeactivity',true);
// Autoconnexion
// Récupérer le token de l'utilisateur
$token = new UsernamePasswordToken($user, null, "main", $user->getRoles());
$this->get("security.token_storage")->setToken($token);
// Simuler l'evenement de connexion
$event = new InteractiveLoginEvent($request, $token);
$dispatcher = new EventDispatcher();
$dispatcher->dispatch($event);
// Redirection
if($redirect)
return $this->redirect($redirect);
else
return $this->redirect($this->generateUrl('app_home'));
}
public function logout() {
$auth_mode=$this->getParameter("appAuth");
switch($auth_mode) {
case "SQL":
return $this->logoutMYSQL();
break;
case "CAS":
return $this->logoutCAS();
break;
}
}
public function logoutMYSQL() {
$this->get('security.token_storage')->setToken(null);
$this->get('session')->invalidate();
return $this->redirect($this->generateUrl("app_home"));
}
public function logoutcas() {
$this->get('security.token_storage')->setToken(null);
$this->get('session')->invalidate();
// Init Client CAS
$alias=$this->getParameter('appAlias');
\phpCAS::setDebug('/var/www/html/'.$alias.'/var/log/cas.log');
\phpCAS::client(CAS_VERSION_2_0, $this->getParameter('casHost'), intval($this->getParameter('casPort')), is_null($this->getParameter('casPath')) ? '' : $this->getParameter('casPath'), false);
\phpCAS::setNoCasServerValidation();
// Logout
$url=$this->generateUrl('app_home', array(), UrlGeneratorInterface::ABSOLUTE_URL);
\phpCAS::logout(array("service"=>$url));
return true;
}
private function updateNinegate($user) {
$em = $this->getDoctrine()->getManager();
$appmasterurl = $this->getParameter("appMasterurl");
$appmasterkey = $this->getParameter("appMasterkey");
// Généraltion de l'urol de communication
if(stripos($appmasterurl,"/")===0) {
$url="https://".$this->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->getParameter("proxyUse");
if($proxyUse) {
$proxyHost = $this->getParameter("proxyHost");
$proxyPort = $this->getParameter("proxyPort");
\Unirest\Request::proxy($proxyHost, $proxyPort, CURLPROXY_HTTP, true);
try{
$response = \Unirest\Request::post($url.'/rest/login',$headers,["key"=>$appmasterkey]);
}
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");
// Récupération des informations du user
try{
$response = \Unirest\Request::post($url.'/rest/user/'.$user->getUsername(),$headers,["key"=>$appmasterkey,"only"=>"user,groups"]);
}
catch (\Exception $e) {
die("Erreur de communication API = ".$e->getMessage()."\n");
}
if($response->code=="200"&&is_object($response->body)) {
// Mise à jour du user
$user->setLastname($response->body->user->lastname);
$user->setFirstname($response->body->user->firstname);
$user->setEmail($response->body->user->email);
$user->setAvatar($response->body->user->avatar);
// Definition du role du user
if(in_array($user->getUsername(),$this->getParameter("ldapAdmins")))
$role="ROLE_ADMIN";
else
$role=($response->body->user->role=="ROLE_ANIM"?"ROLE_MASTER":$response->body->user->role);
if(!$user->hasRole($role)) {
$roles=$user->getRoles();
array_push($roles,$role);
$user->setRoles($roles);
}
// Sauvegarde user
$em->persist($user);
$em->flush();
// Mise à jour des groupes
$groups=$response->body->groups;
$mygroup=[];
foreach($groups as $groupexternal) {
array_push($mygroup,$groupexternal->id);
// Le groupe existe-t-il
$group=$em->getRepository("App:Group")->findOneBy(["idexternal"=>$groupexternal->id]);
if(!$group)
$group = new Group();
$group->setIdexternal($groupexternal->id);
$group->setName($groupexternal->title);
if(!$group->getUsers()->contains($user))
$group->addUser($user);
$em->persist($group);
$em->flush();
}
foreach($user->getGroups() as $group) {
if($group->getIdexternal()) {
if(!in_array($group->getIdexternal(),$mygroup)) {
$user->removeGroup($group);
$em->persist($user);
$em->flush();
}
}
}
}
}
private function updateLDAP($user) {
$em = $this->getDoctrine()->getManager();
$ldap_basedn = $this->getParameter('ldapBasedn');
$ldap_username = $this->getParameter('ldapUsername');
$ldap_firstname = $this->getParameter('ldapFirstname');
$ldap_lastname = $this->getParameter('ldapLastname');
$ldap_email = $this->getParameter('ldapEmail');
$ldap_admins = $this->getParameter('ldapAdmins');
$ldap_model = $this->getParameter('ldapModel');
$fieldstoread = array($ldap_username,$ldap_firstname,$ldap_lastname,$ldap_email);
if($ldap_model=="scribe") {
$ldap_filtergroup="(&(type=Groupe)(cn=*))";
$ldap_filteruser="(&(uid=*)(objectclass=inetOrgPerson)(!(description=Computer)))";
}
else {
$ldap_filtergroup=$this->getParameter('ldapFiltergroup');
$ldap_filteruser=$this->getParameter('ldapFilteruser');
}
// On recherche l'utilisateur dans l'annuaire
$results = $this->ldapService->search(str_replace("*",$user->getUsername(),$ldap_filteruser), $fieldstoread, $ldap_basedn);
foreach($results as $result) {
if(!isset($result[$ldap_lastname])) $result[$ldap_lastname] = "";
if(!isset($result[$ldap_firstname])) $result[$ldap_firstname] = "";
$result[$ldap_email]=strtolower($result[$ldap_email]);
$result[$ldap_email]=utf8_encode($result[$ldap_email]);
// Mise à jour du user
$user->setLastname($result[$ldap_lastname]);
$user->setFirstname($result[$ldap_firstname]);
$user->setEmail($result[$ldap_email]);
// Definition du role
if(in_array($user->getUsername(),$ldap_admins))
$role="ROLE_ADMIN";
else {
$ldapfilter="(|(&(uid=".$user->getUsername().")(ENTPersonProfils=enseignant))(&(uid=".$user->getUsername().")(typeadmin=0))(&(uid=".$user->getUsername().")(typeadmin=2)))";
$results = $this->ldapService->search($ldapfilter, ['uid'], $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);
}
// Sauvegarde user
$em->persist($user);
$em->flush();
}
}
}