359 lines
13 KiB
PHP
Executable File
359 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;
|
|
use Ramsey\Uuid\Uuid;
|
|
|
|
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) {
|
|
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();
|
|
|
|
// Init
|
|
$email = "";
|
|
$lastname = "";
|
|
$firstname = "";
|
|
|
|
// 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) {
|
|
if(empty($email)) $email = $username."@nomail.com";
|
|
|
|
$user = new User();
|
|
$key = Uuid::uuid4();
|
|
|
|
$user->setUsername($username);
|
|
$user->setLastname($lastname);
|
|
$user->setFirstname($firstname);
|
|
$user->setEmail($email);
|
|
$user->setApiKey($key);
|
|
|
|
$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);
|
|
}
|
|
|
|
|
|
// 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();
|
|
}
|
|
}
|
|
}
|