All checks were successful
Cadoles/nineskeletor/pipeline/pr-master This commit looks good
575 lines
21 KiB
PHP
Executable File
575 lines
21 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Controller;
|
|
|
|
use App\Entity\Group;
|
|
use App\Entity\Niveau01;
|
|
use App\Entity\User;
|
|
use App\Form\LoginType;
|
|
use App\Service\ApiService;
|
|
use App\Service\LdapService;
|
|
use Doctrine\Persistence\ManagerRegistry;
|
|
use Ramsey\Uuid\Uuid;
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
use Symfony\Component\EventDispatcher\EventDispatcher;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpKernel\KernelInterface;
|
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
|
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
|
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
|
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
|
|
|
|
class SecurityController extends AbstractController
|
|
{
|
|
private $appKernel;
|
|
private $tokenstorage;
|
|
private $ldapservice;
|
|
private $apiservice;
|
|
|
|
public function __construct(KernelInterface $appKernel, TokenStorageInterface $tokenstorage, LdapService $ldapservice, ApiService $apiservice)
|
|
{
|
|
$this->appKernel = $appKernel;
|
|
$this->tokenstorage = $tokenstorage;
|
|
$this->ldapservice = $ldapservice;
|
|
$this->apiservice = $apiservice;
|
|
}
|
|
|
|
public function noperm(Request $request)
|
|
{
|
|
return $this->render('Home/noperm.html.twig', [
|
|
'useheader' => true,
|
|
'usemenu' => false,
|
|
]);
|
|
}
|
|
|
|
public function login(Request $request, AuthenticationUtils $authenticationUtils, ManagerRegistry $em)
|
|
{
|
|
switch ($this->getParameter('appAuth')) {
|
|
case 'SQL':
|
|
return $this->loginSQL($request, $authenticationUtils, $em);
|
|
break;
|
|
|
|
case 'CAS':
|
|
return $this->loginCAS($request, $authenticationUtils, $em);
|
|
break;
|
|
|
|
case 'LDAP':
|
|
return $this->loginLDAP($request, $authenticationUtils, $em);
|
|
break;
|
|
|
|
case 'OPENID':
|
|
return $this->loginOPENID($request, $authenticationUtils, $em);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public function loginSQL(Request $request, AuthenticationUtils $authenticationUtils, ManagerRegistry $em)
|
|
{
|
|
return $this->render('Home/loginSQL.html.twig', [
|
|
'last_username' => $authenticationUtils->getLastUsername(),
|
|
'error' => $authenticationUtils->getLastAuthenticationError(),
|
|
]);
|
|
}
|
|
|
|
public function loginCAS(Request $request, AuthenticationUtils $authenticationUtils, ManagerRegistry $em)
|
|
{
|
|
// Récupération de la cible de navigation
|
|
$redirect = $request->getSession()->get('_security.main.target_path');
|
|
|
|
// Masteridentity
|
|
$appMasteridentity = $this->getParameter('appMasteridentity');
|
|
|
|
// Init Client CAS
|
|
$alias = $this->getParameter('appAlias');
|
|
\phpCAS::setDebug($this->appKernel->getProjectDir().'/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 = "$username@nomail.fr";
|
|
$lastname = $username;
|
|
$firstname = ' ';
|
|
$avatar = 'noavatar.png';
|
|
|
|
// Rechercher l'utilisateur
|
|
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')];
|
|
}
|
|
|
|
if (isset($attributes[$this->getParameter('casAvatar')])) {
|
|
$avatar = $attributes[$this->getParameter('casAvatar')];
|
|
}
|
|
|
|
// Rechercher l'utilisateur
|
|
$user = $em->getRepository('App\Entity\User')->findOneBy(['username' => $username]);
|
|
if (!$user) {
|
|
if (!$this->getParameter('casAutosubmit')) {
|
|
return $this->redirect($this->generateUrl('app_noperm'));
|
|
}
|
|
|
|
$this->submitSSONiveau01($attributes, $em);
|
|
$this->submitSSOGroup($attributes, $em);
|
|
$niveau01 = $em->getRepository('App\Entity\Niveau01')->calculateSSONiveau01($attributes);
|
|
$user = $this->submituser($username, $firstname, $lastname, $email, $avatar, $niveau01, $em);
|
|
$user = $em->getRepository('App\Entity\Group')->calculateSSOGroup($user, $attributes);
|
|
} elseif ($this->getParameter('casAutoupdate')) {
|
|
$this->submitSSONiveau01($attributes, $em);
|
|
$this->submitSSOGroup($attributes, $em);
|
|
$this->updateuser($user, $firstname, $lastname, $email, $avatar, $em);
|
|
$user = $em->getRepository('App\Entity\Group')->calculateSSOGroup($user, $attributes);
|
|
}
|
|
|
|
// Autoconnexion
|
|
return $this->autoconnexion($user, $redirect, $request);
|
|
}
|
|
|
|
public function loginLDAP(Request $request, AuthenticationUtils $authenticationUtils, ManagerRegistry $em)
|
|
{
|
|
// Création du formulaire
|
|
$form = $this->createForm(LoginType::class);
|
|
|
|
// Récupération des data du formulaire
|
|
$form->handleRequest($request);
|
|
|
|
// Affichage du formulaire
|
|
return $this->render('Home/loginLDAP.html.twig', [
|
|
'useheader' => false,
|
|
'usemenu' => false,
|
|
'usesidebar' => false,
|
|
'form' => $form->createView(),
|
|
]);
|
|
}
|
|
|
|
public function loginldapcheck(Request $request, AuthenticationUtils $authenticationUtils, ManagerRegistry $em)
|
|
{
|
|
$username = $request->get('login')['username'];
|
|
$password = $request->get('login')['password'];
|
|
|
|
// Récupération de la cible de navigation
|
|
$redirect = $request->getSession()->get('_security.main.target_path');
|
|
|
|
// L'utilisateur se co à l'annuaire
|
|
$userldap = $this->ldapservice->userconnect($username, $password);
|
|
if ($userldap) {
|
|
$userldap = $userldap[0];
|
|
|
|
// Init
|
|
$email = "$username@nomail.fr";
|
|
$lastname = $username;
|
|
$firstname = ' ';
|
|
$avatar = 'noavatar.png';
|
|
|
|
// Rechercher l'utilisateur
|
|
if (isset($userldap[$this->getParameter('ldapFirstname')])) {
|
|
$firstname = $userldap[$this->getParameter('ldapFirstname')];
|
|
}
|
|
|
|
if (isset($userldap[$this->getParameter('ldapLastname')])) {
|
|
$lastname = $userldap[$this->getParameter('ldapLastname')];
|
|
}
|
|
|
|
if (isset($userldap[$this->getParameter('ldapEmail')])) {
|
|
$email = $userldap[$this->getParameter('ldapEmail')];
|
|
}
|
|
|
|
if (isset($userldap[$this->getParameter('ldapAvatar')])) {
|
|
$avatar = $userldap[$this->getParameter('ldapAvatar')];
|
|
}
|
|
|
|
$user = $em->getRepository('App\Entity\User')->findOneBy(['username' => $username]);
|
|
|
|
if (!$user) {
|
|
if (!$this->getParameter('ldapAutosubmit')) {
|
|
return $this->redirect($this->generateUrl('app_noperm'));
|
|
}
|
|
$niveau01 = $em->getRepository('App\Entity\Niveau01')->calculateLDAPNiveau01($username);
|
|
$user = $this->submituser($username, $firstname, $lastname, $email, $avatar, $niveau01, $em);
|
|
} elseif ($this->getParameter('ldapAutoupdate')) {
|
|
$this->updateuser($user, $firstname, $lastname, $email, $avatar, $em);
|
|
}
|
|
|
|
// Autoconnexion
|
|
return $this->autoconnexion($user, $redirect, $request);
|
|
}
|
|
|
|
return $this->redirect($this->generateUrl('app_login'));
|
|
}
|
|
|
|
public function loginOPENID(Request $request, AuthenticationUtils $authenticationUtils, ManagerRegistry $em)
|
|
{
|
|
$state = Uuid::uuid4();
|
|
$request->getSession()->set('oauthState', $state);
|
|
$callback = $this->generateUrl('app_loginopenidcallback', [], UrlGeneratorInterface::ABSOLUTE_URL);
|
|
$url = $this->getParameter('oauthLoginurl').'?client_id='.$this->getParameter('oauthClientid').'&redirect_uri='.$callback.'&response_type=code&state='.$state.'&scope=openid';
|
|
|
|
return $this->redirect($url);
|
|
}
|
|
|
|
public function loginopenidcallback(Request $request, AuthenticationUtils $authenticationUtils, ManagerRegistry $em)
|
|
{
|
|
// Récupération de la cible de navigation
|
|
$redirect = $request->getSession()->get('_security.main.target_path');
|
|
|
|
// Masteridentity
|
|
$appMasteridentity = $this->getParameter('appMasteridentity');
|
|
|
|
$callback = $this->generateUrl('app_loginopenidcallback', [], UrlGeneratorInterface::ABSOLUTE_URL);
|
|
$apiurl = $this->getParameter('oauthTokenurl');
|
|
$query = [
|
|
'grant_type' => 'authorization_code',
|
|
'code' => $request->get('code'),
|
|
'redirect_uri' => $callback,
|
|
'client_id' => $this->getParameter('oauthClientid'),
|
|
'client_secret' => $this->getParameter('oauthClientsecret'),
|
|
];
|
|
$response = $this->apiservice->run('POST', $apiurl, $query, null, 'form');
|
|
|
|
if (!$response || '200' != $response->code) {
|
|
exit('pb openid 01');
|
|
}
|
|
$accesstoken = $response->body->access_token;
|
|
$accesstokentype = $response->body->token_type;
|
|
$îdtoken = $response->body->id_token;
|
|
|
|
$request->getSession()->set('oauthAccesstoken', $accesstoken);
|
|
$request->getSession()->set('oauthIdtoken', $îdtoken);
|
|
|
|
$apiurl = $this->getParameter('oauthUserinfo');
|
|
|
|
$response = $this->apiservice->run('GET', $apiurl, null, ['Authorization' => $accesstokentype.' '.$accesstoken]);
|
|
if (!$response || '200' != $response->code) {
|
|
exit('pb openid 02');
|
|
}
|
|
|
|
$attributes = json_decode(json_encode($response->body), true);
|
|
|
|
// Username
|
|
$username = '';
|
|
if (isset($attributes[$this->getParameter('oauthUsername')])) {
|
|
$username = $attributes[$this->getParameter('oauthUsername')];
|
|
}
|
|
|
|
// Valeur par défaut
|
|
$email = "$username@nomail.fr";
|
|
$lastname = $username;
|
|
$firstname = ' ';
|
|
$avatar = 'noavatar.png';
|
|
|
|
// Récupérer les attributs associés
|
|
if (isset($attributes[$this->getParameter('oauthEmail')])) {
|
|
$email = $attributes[$this->getParameter('oauthEmail')];
|
|
}
|
|
|
|
if (isset($attributes[$this->getParameter('oauthLastname')])) {
|
|
$lastname = $attributes[$this->getParameter('oauthLastname')];
|
|
}
|
|
|
|
if (isset($attributes[$this->getParameter('oauthFirstname')])) {
|
|
$firstname = $attributes[$this->getParameter('oauthFirstname')];
|
|
}
|
|
|
|
if (isset($attributes[$this->getParameter('oauthAvatar')])) {
|
|
$avatar = $attributes[$this->getParameter('oauthAvatar')];
|
|
}
|
|
|
|
// Rechercher l'utilisateur
|
|
$user = $em->getRepository('App\Entity\User')->findOneBy(['username' => $username]);
|
|
if (!$user) {
|
|
if (!$this->getParameter('oauthAutosubmit')) {
|
|
return $this->redirect($this->generateUrl('app_noperm'));
|
|
}
|
|
|
|
$this->submitSSONiveau01($attributes, $em);
|
|
$this->submitSSOGroup($attributes, $em);
|
|
$niveau01 = $em->getRepository('App\Entity\Niveau01')->calculateSSONiveau01($attributes);
|
|
$user = $this->submituser($username, $firstname, $lastname, $email, $avatar, $niveau01, $em);
|
|
} elseif ($this->getParameter('oauthAutoupdate')) {
|
|
$this->submitSSONiveau01($attributes, $em);
|
|
$this->submitSSOGroup($attributes, $em);
|
|
$this->updateuser($user, $firstname, $lastname, $email, $avatar, $em);
|
|
$user = $em->getRepository('App\Entity\Group')->calculateSSOGroup($user, $attributes);
|
|
}
|
|
|
|
// Autoconnexion
|
|
return $this->autoconnexion($user, $redirect, $request);
|
|
}
|
|
|
|
public function logout(Request $request)
|
|
{
|
|
$auth_mode = $this->getParameter('appAuth');
|
|
switch ($auth_mode) {
|
|
case 'SQL':
|
|
return $this->logoutSQL($request);
|
|
break;
|
|
|
|
case 'CAS':
|
|
return $this->logoutCAS($request);
|
|
break;
|
|
|
|
case 'LDAP':
|
|
return $this->logoutLDAP($request);
|
|
break;
|
|
|
|
case 'OPENID':
|
|
return $this->logoutOPENID($request);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public function logoutSQL(Request $request)
|
|
{
|
|
$this->tokenstorage->setToken(null);
|
|
$request->getSession()->invalidate();
|
|
|
|
return $this->redirect($this->generateUrl('app_home'));
|
|
}
|
|
|
|
public function logoutCAS(Request $request)
|
|
{
|
|
$this->tokenstorage->setToken(null);
|
|
$request->getSession()->invalidate();
|
|
|
|
// Init Client CAS
|
|
$alias = $this->getParameter('appAlias');
|
|
\phpCAS::setDebug($this->appKernel->getProjectDir().'/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', [], UrlGeneratorInterface::ABSOLUTE_URL);
|
|
\phpCAS::logout(['service' => $url]);
|
|
|
|
return true;
|
|
}
|
|
|
|
public function logoutLDAP(Request $request)
|
|
{
|
|
$this->tokenstorage->setToken(null);
|
|
$request->getSession()->invalidate();
|
|
|
|
return $this->redirect($this->generateUrl('app_home'));
|
|
}
|
|
|
|
public function logoutOPENID(Request $request)
|
|
{
|
|
$accesstoken = $request->getSession()->get('oauthAccesstoken');
|
|
$idtoken = $request->getSession()->get('oauthIdtoken');
|
|
$state = $request->getSession()->get('oauthState');
|
|
|
|
$this->tokenstorage->setToken(null);
|
|
$request->getSession()->invalidate();
|
|
|
|
$url = $this->getParameter('oauthLogouturl');
|
|
if ($url) {
|
|
$callback = ($request->isSecure() ? 'https://' : 'http://').str_replace('//', '/', $this->getParameter('appWeburl').$this->getParameter('appAlias').$this->generateUrl('app_home'));
|
|
$callback = substr($callback, 0, -1);
|
|
|
|
$url .= "?id_token_hint=$idtoken&scope=openid&post_logout_redirect_uri=$callback";
|
|
|
|
return $this->redirect($url);
|
|
} else {
|
|
return $this->redirect($this->generateUrl('app_home'));
|
|
}
|
|
}
|
|
|
|
// Génération automatique des niveau01 provenant de l'attribut casniveau01
|
|
private function submitSSONiveau01($attributes, ManagerRegistry $em)
|
|
{
|
|
$attrNiveau01 = ('CAS' == $this->getParameter('appAuth') ? $this->getParameter('casNiveau01') : $this->getParameter('oauthNiveau01'));
|
|
if (!$attrNiveau01) {
|
|
return null;
|
|
}
|
|
|
|
// Si l'utilisateur possège l'attribut niveau01 dans ses attributs
|
|
if (array_key_exists($attrNiveau01, $attributes)) {
|
|
if (!is_array($attributes[$attrNiveau01])) {
|
|
$attributes[$attrNiveau01] = [$attributes[$attrNiveau01]];
|
|
}
|
|
|
|
foreach ($attributes[$attrNiveau01] as $ssoniveau01) {
|
|
$basedn = $this->getParameter('ldapBasedn');
|
|
$name = $ssoniveau01;
|
|
if ('' != $basedn) {
|
|
// 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
|
|
if (false !== stripos($name, $basedn)) {
|
|
$tbname = explode(',', $name);
|
|
$tbname = explode('=', $tbname[0]);
|
|
$name = $tbname[1];
|
|
}
|
|
}
|
|
|
|
// Recherche du groupe
|
|
$niveau01 = $em->getRepository("App\Entity\Niveau01")->findOneBy(['label' => $name]);
|
|
if (!$niveau01) {
|
|
$niveau01 = new Niveau01();
|
|
$niveau01->setLabel($name);
|
|
$niveau01->setApikey(Uuid::uuid4());
|
|
}
|
|
|
|
$niveau01->setAttributes('{"'.$attrNiveau01.'":"'.$ssoniveau01.'"}');
|
|
$em->getManager()->persist($niveau01);
|
|
$em->getManager()->flush();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Génération automatique des groupes provenant de l'attribut casgroup ou oauthgroup
|
|
private function submitSSOGroup($attributes, ManagerRegistry $em)
|
|
{
|
|
$attrGroup = ('CAS' == $this->getParameter('appAuth') ? $this->getParameter('casGroup') : $this->getParameter('oauthGroup'));
|
|
if (!$attrGroup) {
|
|
return null;
|
|
}
|
|
|
|
// Si l'utilisateur possège l'attribut groupe dans ses attributs
|
|
if (array_key_exists($attrGroup, $attributes)) {
|
|
if (!is_array($attributes[$attrGroup])) {
|
|
$attributes[$attrGroup] = [$attributes[$attrGroup]];
|
|
}
|
|
|
|
foreach ($attributes[$attrGroup] as $ssogroup) {
|
|
$basedn = $this->getParameter('ldapBasedn');
|
|
$name = $ssogroup;
|
|
if ('' != $basedn) {
|
|
// 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
|
|
if (false !== stripos($name, $basedn)) {
|
|
$tbname = explode(',', $name);
|
|
$tbname = explode('=', $tbname[0]);
|
|
$name = $tbname[1];
|
|
}
|
|
}
|
|
|
|
// Recherche du groupe
|
|
$group = $em->getRepository("App\Entity\Group")->findOneBy(['label' => $name]);
|
|
if (!$group) {
|
|
$group = new Group();
|
|
$group->setLabel($name);
|
|
$group->setIsopen(false);
|
|
$group->setIsworkgroup(false);
|
|
$group->setApikey(Uuid::uuid4());
|
|
}
|
|
|
|
$group->setAttributes('{"'.$attrGroup.'":"'.$ssogroup.'"}');
|
|
$em->getManager()->persist($group);
|
|
$em->getManager()->flush();
|
|
}
|
|
}
|
|
}
|
|
|
|
private function submituser($username, $firstname, $lastname, $email, $avatar, $niveau01, $em)
|
|
{
|
|
if (empty($email)) {
|
|
$email = $username.'@nomail.com';
|
|
}
|
|
if (empty($avatar)) {
|
|
$avatar = 'noavatar.png';
|
|
}
|
|
if (empty($firstname)) {
|
|
$firstname = ' ';
|
|
}
|
|
if (empty($lastname)) {
|
|
$lastname = $username;
|
|
}
|
|
$uuid = Uuid::uuid4();
|
|
$password = $this->getParameter('appAuth').'PWD-'.$username.'-'.$uuid;
|
|
|
|
// Si aucun niveau01 on prend par défaut le niveau system
|
|
if (!$niveau01) {
|
|
$niveau01 = $em->getRepository('App\Entity\Niveau01')->find(-1);
|
|
}
|
|
|
|
// Autogénération du user vu qu'il a pu se connecter
|
|
$user = new User();
|
|
|
|
$user->setUsername($username);
|
|
$user->setEmail($email);
|
|
$user->setLastname($lastname);
|
|
$user->setFirstname($firstname);
|
|
$user->setApikey(Uuid::uuid4());
|
|
|
|
$user->setPassword($password);
|
|
$user->setNiveau01($niveau01);
|
|
|
|
$user->setAvatar($avatar);
|
|
$user->setIsvisible(true);
|
|
$user->setRole('ROLE_USER');
|
|
|
|
if (in_array($username, $this->getParameter('appAdmins'))) {
|
|
$user->setRole('ROLE_ADMIN');
|
|
}
|
|
|
|
$em->getManager()->persist($user);
|
|
$em->getManager()->flush();
|
|
|
|
return $user;
|
|
}
|
|
|
|
private function updateuser($user, $firstname, $lastname, $email, $avatar, $em)
|
|
{
|
|
if ('noavatar.png' == $avatar) {
|
|
$avatar = $user->getAvatar();
|
|
}
|
|
|
|
if (!empty($lastname)) {
|
|
$user->setLastname($lastname);
|
|
}
|
|
if (!empty($firstname)) {
|
|
$user->setFirstname($firstname);
|
|
}
|
|
if (!empty($email)) {
|
|
$user->setEmail($email);
|
|
}
|
|
if (!empty($avatar)) {
|
|
$user->setAvatar($avatar);
|
|
}
|
|
|
|
if (in_array($user->getUsername(), $this->getParameter('appAdmins'))) {
|
|
$user->setRole('ROLE_ADMIN');
|
|
}
|
|
|
|
$em->getManager()->flush();
|
|
}
|
|
|
|
private function autoconnexion($user, $redirect, Request $request)
|
|
{
|
|
// Récupérer le token de l'utilisateur
|
|
$token = new UsernamePasswordToken($user, 'main', $user->getRoles());
|
|
$this->tokenstorage->setToken($token);
|
|
$request->getSession()->set('_security_main', serialize($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'));
|
|
}
|
|
}
|
|
}
|