first commit

This commit is contained in:
2023-07-20 11:56:10 +02:00
parent 08c221d3d5
commit f624b15207
341 changed files with 64075 additions and 103 deletions

88
src/Command/InitCommand.php Executable file
View File

@ -0,0 +1,88 @@
<?php
namespace App\Command;
use App\Entity\Config;
use App\Entity\Cron;
use App\Entity\Group;
use App\Entity\Niveau01;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Id\AssignedGenerator;
use Doctrine\ORM\Mapping\ClassMetadata;
use Ramsey\Uuid\Uuid;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Filesystem\Filesystem;
class InitCommand extends Command
{
private $container;
private $em;
private $output;
private $appname;
public function __construct(ContainerInterface $container, EntityManagerInterface $em)
{
parent::__construct();
$this->container = $container;
$this->em = $em;
}
protected function configure()
{
$this
->setName('app:Init')
->setDescription('Init Data for App')
->setHelp('This command Init Data App')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->output = $output;
$this->writeln('APP = Default Data');
// On s'assure que le user admin existe
$metadata = $this->em->getClassMetaData('App\Entity\User');
$metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
$metadata->setIdGenerator(new AssignedGenerator());
$user = $this->em->getRepository('App\Entity\User')->findOneBy(['id' => '-1']);
if (!$user) {
$user = new User();
$user->setId(-1);
$user->setUsername('admin');
$user->setFirstname('admin');
$user->setLastname($this->appname);
$user->setPassword($this->container->getParameter('appSecret'));
$user->setEmail('admin@noreply.fr');
$user->setAvatar('admin.jpg');
$user->setRole('ROLE_ADMIN');
$this->em->persist($user);
$this->em->flush();
}
else {
$user->setRole('ROLE_ADMIN');
$this->em->flush();
}
$output->writeln('');
return Command::SUCCESS;
}
private function writelnred($string)
{
$this->output->writeln('<fg=red>'.$string.'</>');
}
private function writeln($string)
{
$this->output->writeln($string);
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class HomeController extends AbstractController
{
public function home(Request $request)
{
return $this->render('Home/home.html.twig');
}
}

View File

@ -0,0 +1,208 @@
<?php
namespace App\Controller;
use App\Form\LoginType;
use App\Service\ApiService;
use App\Service\LdapService;
use App\Service\PasswordEncoder;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class HydraController extends AbstractController
{
private $apiservice;
private $passwordencoder;
private $ldapservice;
public function __construct(ApiService $apiservice, LdapService $ldapservice, PasswordEncoder $passwordencoder)
{
$this->apiservice = $apiservice;
$this->passwordencoder = $passwordencoder;
$this->ldapservice = $ldapservice;
}
public function loginsql(Request $request): Response
{
$challenge = $request->query->get('login_challenge');
$error = $request->query->get('error');
// S'il n'y a pas de challenge, on déclenche une bad request
if (!$challenge) {
return $this->redirectToRoute('app_login');
}
// On vérifie que la requête d'identification provient bien de hydra
$response = $this->apiservice->run('GET', $this->getParameter('hydraLoginchallenge').$challenge, null);
if (!$response) {
return $this->redirectToRoute('app_login');
}
// si le challenge est validé par hydra, on le stocke en session pour l'utiliser par la suite et on redirige vers une route interne protégée qui va déclencher l'identification FranceConnect
$request->getSession()->set('hydraChallenge', $challenge);
// 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/loginHYDRA.html.twig', [
'useheader' => false,
'usemenu' => false,
'usesidebar' => false,
'form' => $form->createView(),
'mode' => 'SQL',
'error' => $error,
]);
}
public function checkloginsql(Request $request, ManagerRegistry $em)
{
$username = $request->get('login')['username'];
$password = $request->get('login')['password'];
// user exist ?
$user = $em->getRepository("App\Entity\User")->findOneBy(['username' => $username]);
if (!$user) {
return $this->redirect($this->generateUrl('app_hydra_loginsql', ['login_challenge' => $request->getSession()->get('hydraChallenge'), 'error' => 'Utilisateur inexistant']));
}
$islogin = $this->passwordencoder->verify($user->getPassword(), $password, $user->getSalt());
if (!$islogin) {
return $this->redirect($this->generateUrl('app_hydra_loginsql', ['login_challenge' => $request->getSession()->get('hydraChallenge'), 'error' => 'Password incorrect']));
}
$response = $this->apiservice->run('PUT', $this->getParameter('hydraLoginchallengeaccept').$request->getSession()->get('hydraChallenge'), ['subject' => $user->getEmail(), 'acr' => 'string']);
if (!$response || '200' != $response->code) {
return $this->redirectToRoute('app_login');
}
$datas = [
'username' => $user->getUsername(),
'email' => $user->getEmail(),
'firstname' => $user->getFirstname(),
'lastname' => $user->getLastname(),
];
$request->getSession()->set('datas', $datas);
$redirect = $response->body->redirect_to;
return $this->redirect($redirect, 301);
}
public function loginldap(Request $request): Response
{
$challenge = $request->query->get('login_challenge');
$error = $request->query->get('error');
// S'il n'y a pas de challenge, on déclenche une bad request
if (!$challenge) {
return $this->redirect('app_login');
}
// On vérifie que la requête d'identification provient bien de hydra
$response = $this->apiservice->run('GET', $this->getParameter('hydraLoginchallenge').$challenge, null);
if (!$response) {
return $this->redirect('app_login');
}
// si le challenge est validé par hydra, on le stocke en session pour l'utiliser par la suite et on redirige vers une route interne protégée qui va déclencher l'identification FranceConnect
$request->getSession()->set('hydraChallenge', $challenge);
// 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/loginHYDRA.html.twig', [
'useheader' => false,
'usemenu' => false,
'usesidebar' => false,
'form' => $form->createView(),
'mode' => 'LDAP',
'error' => $error,
]);
}
public function checkloginldap(Request $request, ManagerRegistry $em)
{
$username = $request->get('login')['username'];
$password = $request->get('login')['password'];
// L'utilisateur se co à l'annuaire ?
$userldap = $this->ldapservice->userconnect($username, $password);
if (!$userldap) {
return $this->redirect($this->generateUrl('app_hydra_loginldap', ['login_challenge' => $request->getSession()->get('hydraChallenge'), 'error' => 'Utilisateur ou password incorrect']));
}
$userldap = $userldap[0];
// Init
$email = "$username@nomail.fr";
$lastname = $username;
$firstname = ' ';
// 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')];
}
$response = $this->apiservice->run('PUT', $this->getParameter('hydraLoginchallengeaccept').$request->getSession()->get('hydraChallenge'), ['subject' => $email, 'acr' => 'string']);
if (!$response || '200' != $response->code) {
return $this->redirect('app_login');
}
$datas = [
'username' => $username,
'email' => $email,
'firstname' => $firstname,
'lastname' => $lastname,
];
$request->getSession()->set('datas', $datas);
$redirect = $response->body->redirect_to;
return $this->redirect($redirect, 301);
}
public function consent(Request $request)
{
$challenge = $request->query->get('consent_challenge');
if (!$challenge) {
throw new BadRequestException("Le challenge n'est pas disponible");
}
// On vérifie que la requête d'identification provient bien de hydra
$response = $this->apiservice->run('GET', $this->getParameter('hydraConsentchallenge').$challenge, null);
if (!$response) {
throw new BadRequestException('challenge invalide');
}
$response = $this->apiservice->run('PUT', $this->getParameter('hydraConsentchallengeaccept').$challenge, [
'grant_scope' => ['openid', 'offline_access'],
'session' => ['id_token' => $request->getSession()->get('datas')],
]);
if (!$response) {
throw new BadRequestException('challenge not accept');
}
$redirect = $response->body->redirect_to;
return $this->redirect($redirect, 301);
}
}

View File

@ -0,0 +1,457 @@
<?php
namespace App\Controller;
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'));
}
$user = $this->submituser($username, $firstname, $lastname, $email, $avatar, $em);
} elseif ($this->getParameter('casAutoupdate')) {
$this->updateuser($user, $firstname, $lastname, $email, $avatar, $em);
}
// 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'));
}
$user = $this->submituser($username, $firstname, $lastname, $email, $avatar, $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'));
}
$user = $this->submituser($username, $firstname, $lastname, $email, $avatar, $em);
} elseif ($this->getParameter('oauthAutoupdate')) {
$this->updateuser($user, $firstname, $lastname, $email, $avatar, $em);
}
// 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 && $idtoken) {
$callback = $this->generateUrl('app_home', [], UrlGeneratorInterface::ABSOLUTE_URL);
$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'));
}
}
private function submituser($username, $firstname, $lastname, $email, $avatar, $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;
// 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->setPassword($password);
$user->setAvatar($avatar);
$user->setRole('ROLE_USER');
$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);
}
$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'));
}
}
}

254
src/Entity/User.php Executable file
View File

@ -0,0 +1,254 @@
<?php
namespace App\Entity;
use App\Validator;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\LegacyPasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ORM\Entity
* @ORM\Table(name="useraccount")
* @ORM\HasLifecycleCallbacks()
*
* @UniqueEntity(fields="username", message="Un utilisateur existe déjà avec ce login.")
* @UniqueEntity(fields="email", message="Un utilisateur existe déjà avec ce mail.")
*/
class User implements UserInterface, LegacyPasswordAuthenticatedUserInterface
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=128, unique=true)
* @Validator\Userusername()
*/
private $username;
/**
* @ORM\Column(type="string", length=250, nullable=true)
*/
private $firstname;
/**
* @ORM\Column(type="string", length=250, nullable=true)
*/
private $lastname;
/**
* @var array
*
* @ORM\Column(type="array", length=255)
*/
private $roles = [];
/**
* @ORM\Column(type="string", length=250)
*/
private $password;
/**
* @Validator\Password()
*/
private $passwordplain;
/**
* @ORM\Column(type="string", length=250)
*/
private $salt;
/**
* @ORM\Column(type="string", length=128, unique=true)
*/
private $email;
/**
* @ORM\Column(type="string", length=250, nullable=true, options={"default" : 0})
*/
private $avatar;
// == CODE A NE PAS REGENERER
public function setId(int $id): self
{
$this->id = $id;
return $this;
}
public function getUserIdentifier(): string
{
return $this->username;
}
public function setPasswordDirect($password)
{
// Permet de setter le password généré lors de l'inscription
$this->password = $password;
return $this;
}
/**
* @see PasswordAuthenticatedUserInterface
*/
public function getPassword(): string
{
return $this->password;
}
public function setPassword($password): self
{
if ($password != $this->password && '' != $password) {
// Placer le password non encodé dans une variable tempo sur laquel on va appliquer la contraite de form
$this->passwordplain = $password;
// Password encrypté format openldap
$this->salt = uniqid(mt_rand(), true);
$hash = '{SSHA}'.base64_encode(pack('H*', sha1($password.$this->salt)).$this->salt);
$this->password = $hash;
}
return $this;
}
/**
* Returning a salt is only needed, if you are not using a modern
* hashing algorithm (e.g. bcrypt or sodium) in your security.yaml.
*
* @see UserInterface
*/
public function getSalt(): ?string
{
return $this->salt;
}
/**
* @see UserInterface
*/
public function eraseCredentials()
{
$this->passwordplain = null;
}
public function getRoles(): array
{
return $this->roles;
}
public function hasRole(string $role): ?bool
{
return in_array($role, $this->getRoles());
}
public function setRole(string $role): self
{
if (!$this->hasRole($role)) {
array_push($this->roles, $role);
}
return $this;
}
public function getDisplayname()
{
return $this->firstname.' '.$this->lastname.(!$this->isactive ? ' (inactif)' : '');
}
public function getFullname()
{
return $this->username.' = '.$this->firstname.' '.$this->lastname.(!$this->isactive ? ' (inactif)' : '');
}
// == FIN DU CODE A NE PAS REGENERER
public function getId(): ?int
{
return $this->id;
}
public function getUsername(): ?string
{
return $this->username;
}
public function setUsername(string $username): static
{
$this->username = $username;
return $this;
}
public function getFirstname(): ?string
{
return $this->firstname;
}
public function setFirstname(?string $firstname): static
{
$this->firstname = $firstname;
return $this;
}
public function getLastname(): ?string
{
return $this->lastname;
}
public function setLastname(?string $lastname): static
{
$this->lastname = $lastname;
return $this;
}
public function setRoles(array $roles): static
{
$this->roles = $roles;
return $this;
}
public function setSalt(string $salt): static
{
$this->salt = $salt;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): static
{
$this->email = $email;
return $this;
}
public function getAvatar(): ?string
{
return $this->avatar;
}
public function setAvatar(?string $avatar): static
{
$this->avatar = $avatar;
return $this;
}
}

37
src/Form/LoginType.php Executable file
View File

@ -0,0 +1,37 @@
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class LoginType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('submit',
SubmitType::class, [
'label' => 'Valider',
'attr' => ['class' => 'btn btn-success mt-4 float-end'],
]
);
$builder->add('username',
TextType::class, [
'label' => 'Login',
'attr' => ['autocomplete' => 'new-password'],
]
);
$builder->add('password',
PasswordType::class, [
'always_empty' => true,
'label' => 'Mot de Passe',
'attr' => ['autocomplete' => 'new-password'],
]
);
}
}

111
src/Service/ApiService.php Executable file
View File

@ -0,0 +1,111 @@
<?php
namespace App\Service;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ApiService
{
private $params;
public function __construct(ParameterBagInterface $params)
{
$this->params = $params;
}
public function setbody(array $array)
{
return \Unirest\Request\Body::json($array);
}
public function run($method, $url, $query, $header = null, $content = 'json')
{
// Entete
$headerini = null;
switch ($content) {
case 'json':
$headerini = [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
];
if ($query) {
$query = \Unirest\Request\Body::json($query);
}
break;
case 'form':
$headerini = [
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded',
];
if ($query) {
$query = \Unirest\Request\Body::form($query);
}
break;
}
if ($header) {
$header = array_merge($headerini, $header);
} else {
$header = $headerini;
}
// Paramétrage unirest
\Unirest\Request::verifyPeer(false);
\Unirest\Request::verifyHost(false);
\Unirest\Request::timeout(5);
// Déclaration du proxy
$proxyUse = $this->params->get('proxyUse');
if ($proxyUse) {
$proxyHost = $this->params->get('proxyHost');
$proxyPort = $this->params->get('proxyPort');
\Unirest\Request::proxy($proxyHost, $proxyPort, CURLPROXY_HTTP, true);
}
$response = false;
switch ($method) {
case 'POST':
try {
$response = \Unirest\Request::post($url, $header, $query);
} catch (\Exception $e) {
return false;
}
break;
case 'GET':
try {
$response = @\Unirest\Request::get($url, $header, $query);
} catch (\Exception $e) {
return false;
}
break;
case 'PUT':
try {
$response = \Unirest\Request::put($url, $header, $query);
} catch (\Exception $e) {
return false;
}
break;
case 'DELETE':
try {
$response = \Unirest\Request::delete($url, $header, $query);
} catch (\Exception $e) {
return false;
}
break;
case 'PATCH':
try {
$response = \Unirest\Request::patch($url, $header, $query);
} catch (\Exception $e) {
return false;
}
break;
}
return $response;
}
}

1382
src/Service/LdapService.php Executable file
View File

@ -0,0 +1,1382 @@
<?php
namespace App\Service;
use App\Entity\Group;
use App\Entity\Niveau01;
use App\Entity\Niveau02;
use App\Entity\Niveau03;
use App\Entity\Niveau04;
use App\Entity\User;
use App\Entity\UserGroup;
use Symfony\Component\DependencyInjection\ContainerInterface;
class LdapService
{
private $appMasteridentity;
private $synchro;
private $host;
private $port;
private $usetls;
private $userwriter;
private $user;
private $password;
private $basedn;
private $baseorganisation;
private $baseniveau01;
private $baseniveau02;
private $baseniveau03;
private $baseniveau04;
private $basegroup;
private $baseuser;
private $username;
private $firstname;
private $lastname;
private $email;
private $avatar;
private $memberof;
private $groupgid;
private $groupname;
private $groupmember;
private $groupmemberisdn;
private $filtergroup;
private $filteruser;
private $userattributes;
private $connection;
public function __construct(ContainerInterface $container)
{
$this->appMasteridentity = $container->getParameter('appMasteridentity');
$this->synchro = $container->getParameter('appSynchro');
$this->host = $container->getParameter('ldapHost');
$this->port = $container->getParameter('ldapPort');
$this->usetls = $container->getParameter('ldapUsetls');
$this->userwriter = $container->getParameter('ldapUserwriter');
$this->user = $container->getParameter('ldapUser');
$this->password = $container->getParameter('ldapPassword');
$this->basedn = $container->getParameter('ldapBasedn');
$this->baseorganisation = $container->getParameter('ldapBaseorganisation');
$this->baseniveau01 = $container->getParameter('ldapBaseniveau01');
$this->baseniveau02 = $container->getParameter('ldapBaseniveau02');
$this->baseniveau03 = $container->getParameter('ldapBaseniveau03');
$this->baseniveau04 = $container->getParameter('ldapBaseniveau04');
$this->basegroup = $container->getParameter('ldapBasegroup');
$this->baseuser = $container->getParameter('ldapBaseuser');
$this->username = $container->getParameter('ldapUsername');
$this->firstname = $container->getParameter('ldapFirstname');
$this->lastname = $container->getParameter('ldapLastname');
$this->email = $container->getParameter('ldapEmail');
$this->avatar = $container->getParameter('ldapAvatar');
$this->memberof = $container->getParameter('ldapMemberof');
$this->groupgid = $container->getParameter('ldapGroupgid');
$this->groupname = $container->getParameter('ldapGroupname');
$this->groupmember = $container->getParameter('ldapGroupmember');
$this->groupmemberisdn = $container->getParameter('ldapGroupmemberisdn');
$this->filtergroup = $container->getParameter('ldapFiltergroup');
$this->filteruser = $container->getParameter('ldapFilteruser');
$this->userattributes = [$this->username, $this->firstname, $this->lastname, $this->email, $this->avatar, $this->memberof];
}
public function isNine2Ldap()
{
return ('SQL' == $this->appMasteridentity) && 'NINE2LDAP' == $this->synchro && $this->userwriter && $this->baseorganisation && $this->baseniveau01 && $this->baseniveau02 && $this->baseniveau03 && $this->baseniveau04 && $this->basegroup && $this->baseuser && $this->connect();
}
public function connect()
{
// Si on est déjà co = on rebind pour gérer le cas d'un timeout de connection
if ($this->connection) {
if (!@ldap_bind($this->connection, $this->user, $this->password)) {
$this->disconnect();
}
}
if ($this->connection) {
return $this->connection;
} else {
$ldapConn = ldap_connect($this->host, $this->port);
if ($ldapConn) {
ldap_set_option($ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapConn, LDAP_OPT_REFERRALS, 0);
if ($this->usetls) {
ldap_start_tls($ldapConn);
}
if (@ldap_bind($ldapConn, $this->user, $this->password)) {
$this->connection = $ldapConn;
return $this->connection;
}
}
}
return false;
}
public function userconnect($username, $userpassword)
{
$ldapConn = ldap_connect($this->host, $this->port);
$this->connection = $ldapConn;
if ($this->connection) {
ldap_set_option($ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapConn, LDAP_OPT_REFERRALS, 0);
if ($this->usetls) {
ldap_start_tls($ldapConn);
}
$dn = $this->getUserDN($username);
if (@ldap_bind($ldapConn, $dn, $userpassword)) {
$res = $this->search(str_replace('*', $username, $this->filteruser), $this->userattributes, $this->baseuser);
$this->disconnect();
return $res;
}
}
$this->disconnect();
return false;
}
public function getParameter($key)
{
switch ($key) {
case 'baseuser': return $this->baseuser;
break;
case 'basegroup': return $this->basegroup;
break;
case 'baseniveau01': return $this->baseniveau01;
break;
case 'baseniveau02': return $this->baseniveau02;
break;
case 'baseniveau03': return $this->baseniveau03;
break;
case 'baseniveau04': return $this->baseniveau04;
break;
case 'basedn': return $this->basedn;
break;
case 'baseorganisation': return $this->baseorganisation;
break;
case 'filteruser': return $this->filteruser;
break;
}
}
public function search($filter, $attributes = [], $subBranch = '')
{
$connection = $this->connect();
$branch = ($subBranch ? $subBranch : $this->basedn);
$result = ldap_search($connection, $branch, $filter, $attributes, 0, 0, 0);
if (!$result) {
$this->ldapError();
}
return $this->resultToArray($result);
}
public function searchdn($dn, $subBranch = '')
{
$connection = $this->connect();
$tbdn = ldap_explode_dn($dn, 0);
$branch = ($subBranch ? $subBranch : $this->basedn);
$result = ldap_search($connection, $branch, '('.$tbdn[0].')', [], 0, 0, 0);
if (!$result) {
$this->ldapError();
}
return $this->resultToArray($result);
}
public function deleteByDN($dn, $recursive = false)
{
$connection = $this->connect();
if (false == $recursive) {
$ldapentrys = $this->searchdn($dn);
if (!empty($ldapentrys)) {
$removed = ldap_delete($connection, $dn);
if (!$removed) {
$this->ldapError();
}
}
} else {
$ldapentrys = $this->searchdn($dn);
if (!empty($ldapentrys)) {
// searching for sub entries
$sr = ldap_list($connection, $dn, 'ObjectClass=*', ['']);
$info = ldap_get_entries($connection, $sr);
for ($i = 0; $i < $info['count']; ++$i) {
$result = $this->deleteByDN($info[$i]['dn'], $recursive);
if (!$result) {
return $result;
}
}
return ldap_delete($connection, $dn);
}
}
}
public function rename($oldDN, $newDN, $parentDN = '', $deleteOldDN = true)
{
$connection = $this->connect();
$result = ldap_rename($connection, $oldDN, $newDN, $parentDN, $deleteOldDN);
if (!$result) {
$this->ldapError();
}
return $result;
}
private function resultToArray($result)
{
$connection = $this->connect();
$resultArray = [];
if ($result) {
$entry = ldap_first_entry($connection, $result);
while ($entry) {
$row = [];
$attr = ldap_first_attribute($connection, $entry);
while ($attr) {
$val = ldap_get_values_len($connection, $entry, $attr);
if (array_key_exists('count', $val) and 1 == $val['count']) {
$row[strtolower($attr)] = $val[0];
} else {
$row[strtolower($attr)] = $val;
}
if (is_array($row[strtolower($attr)])) {
unset($row[strtolower($attr)]['count']);
}
$attr = ldap_next_attribute($connection, $entry);
}
$resultArray[] = $row;
$entry = ldap_next_entry($connection, $entry);
}
}
return $resultArray;
}
public function in_array_r($item, $array)
{
return preg_match('/"'.$item.'"/i', json_encode($array));
}
public function disconnect()
{
if ($this->connection) {
ldap_unbind($this->connection);
$this->connection = null;
}
}
public function ldapError()
{
$connection = $this->connect();
throw new \Exception('Error: ('.ldap_errno($connection).') '.ldap_error($connection));
}
public function ldapModify($dn, $attrs)
{
$connection = $this->connect();
$result = ldap_modify($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
}
// ==================================================================================================================================================================
// == Function Organisation==========================================================================================================================================
// ==================================================================================================================================================================
public function addOrganisations()
{
$ldapentrys = $this->searchdn($this->baseorganisation);
if (empty($ldapentrys)) {
$this->addOrganisation($this->baseorganisation);
}
$ldapentrys = $this->searchdn($this->baseniveau01, $this->baseorganisation);
if (empty($ldapentrys)) {
$this->addOrganisation($this->baseniveau01);
}
$ldapentrys = $this->searchdn($this->baseniveau02, $this->baseorganisation);
if (empty($ldapentrys)) {
$this->addOrganisation($this->baseniveau02);
}
$ldapentrys = $this->searchdn($this->baseniveau03, $this->baseorganisation);
if (empty($ldapentrys)) {
$this->addOrganisation($this->baseniveau03);
}
$ldapentrys = $this->searchdn($this->baseniveau04, $this->baseorganisation);
if (empty($ldapentrys)) {
$this->addOrganisation($this->baseniveau04);
}
$ldapentrys = $this->searchdn($this->basegroup, $this->baseorganisation);
if (empty($ldapentrys)) {
$this->addOrganisation($this->basegroup);
}
$ldapentrys = $this->searchdn($this->baseuser, $this->baseorganisation);
if (empty($ldapentrys)) {
$this->addOrganisation($this->baseuser);
}
}
public function addOrganisation($dn)
{
$connection = $this->connect();
$attrs = [];
$attrs['objectclass'] = ['top', 'organizationalUnit'];
$result = ldap_add($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
return $result;
}
// ==================================================================================================================================================================
// == Function User==================================================================================================================================================
// ==================================================================================================================================================================
public function addUser(User $user)
{
$connection = $this->connect();
$dn = $this->getUserDN($user->getUsername());
$attrs = [];
$attrs['objectclass'] = $this->getObjectClassesUser();
$this->fillAttributesUser($user, $attrs);
foreach ($attrs as $key => $value) {
if (empty($value)) {
unset($attrs[$key]);
}
}
$result = ldap_add($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
return $result;
}
public function ismodifyUser(User $user, $entry)
{
$attrs = [];
$this->fillAttributesUser($user, $attrs);
foreach ($attrs as $key => $value) {
if (!array_key_exists($key, $entry) && !empty($value)) {
return true;
} elseif (array_key_exists($key, $entry) && $value != $entry[$key]) {
return true;
}
}
foreach ($entry as $key => $value) {
if (!array_key_exists($key, $attrs) && !empty($value)) {
return true;
} elseif (array_key_exists($key, $attrs) && $value != $attrs[$key]) {
return true;
}
}
return false;
}
public function modifyUser(User $user)
{
$dn = $this->basedn;
$connection = $this->connect();
$attrs = [];
$this->fillAttributesUser($user, $attrs);
// Rechercher le DN du user
$dn = $this->getUserDN($user->getUsername());
foreach ($attrs as $key => $value) {
if (empty($value)) {
// Bien mettre un @ car si l'attribut est déjà vide cela crache une erreur car l'attribut n'existe déjà plus
@ldap_mod_del($connection, $dn, [$key => []]);
unset($attrs[$key]);
}
}
$result = ldap_modify($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
}
public function modifyUserpwd(User $user)
{
$dn = $this->basedn;
$connection = $this->connect();
$attrs = [];
// Attributs associés au password
$attrs['userpassword'] = $user->getPassword();
// Rechercher le DN du user
$dn = $this->getUserDN($user->getUsername());
foreach ($attrs as $key => $value) {
if (empty($value)) {
// Bien mettre un @ car si l'attribut est déjà vide cela crache une erreur car l'attribut n'existe déjà plus
@ldap_mod_del($connection, $dn, [$key => []]);
unset($attrs[$key]);
}
}
$result = ldap_modify($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
}
public function updateNiveauUser(User $user, $todel = false)
{
$dn = $this->basedn;
$connection = $this->connect();
$result = null;
if (!$user->isIsactive()) {
$todel = true;
}
// NIVEAU01
// On recherche le Niveau01 actuellement asscocié à l'utilisateur
$criteria = '(&(cn=*)(memberUid='.$user->getUsername().'))';
$subbranch = $this->baseniveau01;
$results = $this->search($criteria, ['cn'], $subbranch);
foreach ($results as $result) {
// Si Niveau01 différent de celui en cours on le détache de ce Niveau01
if ($result['cn'] != $user->getNiveau01()->getLabel() || $todel) {
$dn = $this->getNiveau01DN($result['cn']);
$entry['memberuid'] = $user->getUsername();
$result = ldap_mod_del($connection, $dn, $entry);
if (!$result) {
$this->ldapError();
}
}
}
// On recherche le Niveau01 en cours
if (!$todel) {
$criteria = '(cn='.$user->getNiveau01()->getLabel().')';
$subbranch = $this->baseniveau01;
$result = $this->search($criteria, ['memberuid'], $subbranch);
// S'il n'est pas membre du Niveau01 on le rattache
if (!$this->in_array_r($user->getUsername(), $result[0])) {
$dn = $this->getNiveau01DN($user->getNiveau01()->getLabel());
$entry['memberuid'] = $user->getUsername();
$result = ldap_mod_add($connection, $dn, $entry);
if (!$result) {
$this->ldapError();
}
}
}
// NIVEAU02
// On recherche le Niveau02 actuellement asscocié à l'utilisateur
$criteria = '(&(cn=*)(memberUid='.$user->getUsername().'))';
$subbranch = $this->baseniveau02;
$results = $this->search($criteria, ['cn'], $subbranch);
foreach ($results as $result) {
// Si Niveau02 différent de celui en cours on le détache de ce Niveau02
if (null === $user->getNiveau02() || $result['cn'] != $user->getNiveau02()->getLabel() || $todel) {
$dn = $this->getNiveau02DN($result['cn']);
$entry['memberuid'] = $user->getUsername();
$result = ldap_mod_del($connection, $dn, $entry);
if (!$result) {
$this->ldapError();
}
}
}
// On recherche le Niveau02 en cours
if (!$todel) {
if (null !== $user->getNiveau02()) {
$criteria = '(cn='.$user->getNiveau02()->getLabel().')';
$subbranch = $this->baseniveau02;
$result = $this->search($criteria, ['memberuid'], $subbranch);
// S'il n'est pas membre du Niveau02 on le rattache
if (empty($result) || !$this->in_array_r($user->getUsername(), $result[0])) {
$dn = $this->getNiveau02DN($user->getNiveau02()->getLabel());
$entry['memberuid'] = $user->getUsername();
$result = ldap_mod_add($connection, $dn, $entry);
if (!$result) {
$this->ldapError();
}
}
}
}
// NIVEAU03
// On recherche le Niveau03 actuellement asscocié à l'utilisateur
$criteria = '(&(cn=*)(memberUid='.$user->getUsername().'))';
$subbranch = $this->baseniveau03;
$results = $this->search($criteria, ['cn'], $subbranch);
foreach ($results as $result) {
// Si Niveau03 différent de celui en cours on le détache de ce Niveau03
if (null === $user->getNiveau03() || $result['cn'] != $user->getNiveau03()->getLabel() || $todel) {
$dn = $this->getNiveau03DN($result['cn']);
$entry['memberuid'] = $user->getUsername();
$result = ldap_mod_del($connection, $dn, $entry);
if (!$result) {
$this->ldapError();
}
}
}
// On recherche le Niveau03 en cours
if (!$todel) {
if (null !== $user->getNiveau03()) {
$criteria = '(cn='.$user->getNiveau03()->getLabel().')';
$subbranch = $this->baseniveau03;
$result = $this->search($criteria, ['memberuid'], $subbranch);
// S'il n'est pas membre du Niveau03 on le rattache
if (empty($result) || !$this->in_array_r($user->getUsername(), $result[0])) {
$dn = $this->getNiveau03DN($user->getNiveau03()->getLabel());
$entry['memberuid'] = $user->getUsername();
$result = ldap_mod_add($connection, $dn, $entry);
if (!$result) {
$this->ldapError();
}
}
}
}
// NIVEAU04
// On recherche le Niveau04 actuellement asscocié à l'utilisateur
$criteria = '(&(cn=*)(memberUid='.$user->getUsername().'))';
$subbranch = $this->baseniveau04;
$results = $this->search($criteria, ['cn'], $subbranch);
foreach ($results as $result) {
// Si Niveau04 différent de celui en cours on le détache de ce Niveau04
if (null === $user->getNiveau04() || $result['cn'] != $user->getNiveau04()->getLabel() || $todel) {
$dn = $this->getNiveau04DN($result['cn']);
$entry['memberuid'] = $user->getUsername();
$result = ldap_mod_del($connection, $dn, $entry);
if (!$result) {
$this->ldapError();
}
}
}
// On recherche le Niveau04 en cours
if (!$todel) {
if (null !== $user->getNiveau04()) {
$criteria = '(cn='.$user->getNiveau04()->getLabel().')';
$subbranch = $this->baseniveau04;
$result = $this->search($criteria, ['memberuid'], $subbranch);
// S'il n'est pas membre du Niveau04 on le rattache
if (empty($result) || !$this->in_array_r($user->getUsername(), $result[0])) {
$dn = $this->getNiveau04DN($user->getNiveau04()->getLabel());
$entry['memberuid'] = $user->getUsername();
$result = ldap_mod_add($connection, $dn, $entry);
if (!$result) {
$this->ldapError();
}
}
}
}
return $result;
}
public function deleteUser(User $user)
{
$dn = $this->getUserDN($user->getUsername());
return $this->deleteByDN($dn);
}
public function getObjectClassesUser()
{
$oc = [
'top',
'person',
'organizationalPerson',
'inetOrgPerson',
];
return $oc;
}
public function listAttributesUser()
{
return [
'uid',
'cn',
'givenname',
'sn',
'mail',
'displayname',
'telephonenumber',
'postaladdress',
'userpassword',
];
}
public function fillAttributesUser(User $user, array &$attrs)
{
$attrs['uid'] = $user->getUsername();
$attrs['cn'] = $user->getFirstname().' '.$user->getLastname();
$attrs['givenname'] = $user->getFirstname();
$attrs['sn'] = $user->getLastname();
$attrs['mail'] = $user->getEmail();
$attrs['displayname'] = $user->getFirstname().' '.$user->getLastname();
$attrs['telephonenumber'] = $user->getTelephonenumber();
$attrs['postaladdress'] = $user->getPostaladress();
$attrs['userpassword'] = $user->getPassword();
}
public function getUserDN($username)
{
$connection = $this->connect();
$res = ldap_search($connection, $this->basedn, str_replace('*', $username, $this->filteruser));
$first = ldap_first_entry($this->connection, $res);
$dn = ldap_get_dn($this->connection, $first);
return $dn;
}
// ==================================================================================================================================================================
// == Function Niveau01==============================================================================================================================================
// ==================================================================================================================================================================
public function findNiveau01($ldapfilter)
{
$ldapentrys = $this->search($ldapfilter, [$this->groupgid, $this->groupname, $this->groupmember], $this->baseniveau01);
return $ldapentrys;
}
public function findNiveau01ismember($ldapfilter, $username)
{
$ldapentrys = $this->findNiveau01($ldapfilter);
foreach ($ldapentrys as $ldapentry) {
if (is_array($ldapentry[$this->groupmember])) {
if (in_array($username, $ldapentry[$this->groupmember])) {
return true;
}
} elseif ($username == $ldapentry[$this->groupmember]) {
return true;
}
}
return false;
}
public function addNiveau01(Niveau01 $niveau01)
{
$connection = $this->connect();
$dn = $this->getNiveau01DN($niveau01->getLabel());
$attrs = [];
$attrs['objectclass'] = $this->getObjectClassesNiveau01();
$this->fillAttributesNiveau01($niveau01, $attrs);
foreach ($attrs as $key => $value) {
if (empty($value)) {
unset($attrs[$key]);
}
}
$result = ldap_add($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
return $result;
}
public function ismodifyNiveau01(Niveau01 $niveau01, $entry)
{
$attrs = [];
$this->fillAttributesNiveau01($niveau01, $attrs);
foreach ($attrs as $key => $value) {
if (!array_key_exists($key, $entry) && !empty($value)) {
return true;
} elseif (array_key_exists($key, $entry) && $value != $entry[$key]) {
return true;
}
}
foreach ($entry as $key => $value) {
if (!array_key_exists($key, $attrs) && !empty($value)) {
return true;
} elseif (array_key_exists($key, $attrs) && $value != $attrs[$key]) {
return true;
}
}
return false;
}
public function modifyNiveau01(Niveau01 $niveau01, $oldid)
{
$dn = $this->basedn;
$connection = $this->connect();
$attrs = [];
$this->fillAttributesNiveau01($niveau01, $attrs);
unset($attrs['cn']);
$dn = $this->getNiveau01DN($niveau01->getLabel());
foreach ($attrs as $key => $value) {
if (empty($value)) {
// Bien mettre un @ car si l'attribut est déjà vide cela crache une erreur car l'attribut n'existe déjà plus
@ldap_mod_del($connection, $dn, [$key => []]);
unset($attrs[$key]);
}
}
if (isset($oldid) && $oldid != $niveau01->getLabel()) {
$olddn = $this->getNiveau01DN($oldid);
$this->rename($olddn, 'cn='.$niveau01->getLabel(), $this->baseniveau01);
}
$result = ldap_modify($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
}
public function deleteNiveau01(Niveau01 $niveau01)
{
$dn = $this->getNiveau01DN($niveau01->getLabel());
return $this->deleteByDN($dn);
}
private function getObjectClassesNiveau01()
{
$oc = [
'top',
'posixGroup',
];
return $oc;
}
public function listAttributesNiveau01()
{
return [
'cn',
'gidnumber',
'memberuid',
];
}
public function fillAttributesNiveau01(Niveau01 $niveau01, array &$attrs)
{
$attrs['cn'] = $niveau01->getLabel();
$attrs['gidnumber'] = $niveau01->getId();
$attrs['memberuid'] = [];
foreach ($niveau01->getUsers() as $user) {
if ($user->isIsactive()) {
array_push($attrs['memberuid'], $user->getUsername());
}
}
sort($attrs['memberuid']);
if (1 == count($attrs['memberuid'])) {
$attrs['memberuid'] = $attrs['memberuid'][0];
}
}
public function getNiveau01DN($id)
{
return 'cn='.$id.','.$this->baseniveau01;
}
// ==================================================================================================================================================================
// == Function Niveau02==============================================================================================================================================
// ==================================================================================================================================================================
public function addNiveau02(Niveau02 $niveau02)
{
$connection = $this->connect();
$dn = $this->getNiveau02DN($niveau02->getLabel());
$attrs = [];
$attrs['objectclass'] = $this->getObjectClassesNiveau02();
$this->fillAttributesNiveau02($niveau02, $attrs);
foreach ($attrs as $key => $value) {
if (empty($value)) {
unset($attrs[$key]);
}
}
$result = ldap_add($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
return $result;
}
public function ismodifyNiveau02(Niveau02 $niveau02, $entry)
{
$attrs = [];
$this->fillAttributesNiveau02($niveau02, $attrs);
foreach ($attrs as $key => $value) {
if (!array_key_exists($key, $entry) && !empty($value)) {
return true;
} elseif (array_key_exists($key, $entry) && $value != $entry[$key]) {
return true;
}
}
foreach ($entry as $key => $value) {
if (!array_key_exists($key, $attrs) && !empty($value)) {
return true;
} elseif (array_key_exists($key, $attrs) && $value != $attrs[$key]) {
return true;
}
}
return false;
}
public function modifyNiveau02(Niveau02 $niveau02, $oldid)
{
$dn = $this->basedn;
$connection = $this->connect();
$attrs = [];
$this->fillAttributesNiveau02($niveau02, $attrs);
unset($attrs['cn']);
$dn = $this->getNiveau02DN($niveau02->getLabel());
foreach ($attrs as $key => $value) {
if (empty($value)) {
// Bien mettre un @ car si l'attribut est déjà vide cela crache une erreur car l'attribut n'existe déjà plus
@ldap_mod_del($connection, $dn, [$key => []]);
unset($attrs[$key]);
}
}
if (isset($oldid) && $oldid != $niveau02->getLabel()) {
$olddn = $this->getNiveau02DN($oldid);
$this->rename($olddn, 'cn='.$niveau02->getLabel(), $this->baseniveau02);
}
$result = ldap_modify($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
}
public function deleteNiveau02(Niveau02 $niveau02)
{
$dn = $this->getNiveau02DN($niveau02->getLabel());
return $this->deleteByDN($dn);
}
private function getObjectClassesNiveau02()
{
$oc = [
'top',
'posixGroup',
];
return $oc;
}
public function listAttributesNiveau02()
{
return [
'cn',
'gidnumber',
'memberuid',
];
}
public function fillAttributesNiveau02(Niveau02 $niveau02, array &$attrs)
{
$attrs['cn'] = $niveau02->getLabel();
$attrs['gidnumber'] = $niveau02->getId();
$attrs['memberuid'] = [];
foreach ($niveau02->getUsers() as $user) {
if ($user->isIsactive()) {
array_push($attrs['memberuid'], $user->getUsername());
}
}
sort($attrs['memberuid']);
if (1 == count($attrs['memberuid'])) {
$attrs['memberuid'] = $attrs['memberuid'][0];
}
}
public function getNiveau02DN($id)
{
return 'cn='.$id.','.$this->baseniveau02;
}
// ==================================================================================================================================================================
// == Function Niveau03==============================================================================================================================================
// ==================================================================================================================================================================
public function addNiveau03(Niveau03 $niveau03)
{
$connection = $this->connect();
$dn = $this->getNiveau03DN($niveau03->getLabel());
$attrs = [];
$attrs['objectclass'] = $this->getObjectClassesNiveau03();
$this->fillAttributesNiveau03($niveau03, $attrs);
foreach ($attrs as $key => $value) {
if (empty($value)) {
unset($attrs[$key]);
}
}
$result = ldap_add($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
return $result;
}
public function ismodifyNiveau03(Niveau03 $niveau03, $entry)
{
$attrs = [];
$this->fillAttributesNiveau03($niveau03, $attrs);
foreach ($attrs as $key => $value) {
if (!array_key_exists($key, $entry) && !empty($value)) {
return true;
} elseif (array_key_exists($key, $entry) && $value != $entry[$key]) {
return true;
}
}
foreach ($entry as $key => $value) {
if (!array_key_exists($key, $attrs) && !empty($value)) {
return true;
} elseif (array_key_exists($key, $attrs) && $value != $attrs[$key]) {
return true;
}
}
return false;
}
public function modifyNiveau03(Niveau03 $niveau03, $oldid)
{
$dn = $this->basedn;
$connection = $this->connect();
$attrs = [];
$this->fillAttributesNiveau03($niveau03, $attrs);
unset($attrs['cn']);
$dn = $this->getNiveau03DN($niveau03->getLabel());
foreach ($attrs as $key => $value) {
if (empty($value)) {
// Bien mettre un @ car si l'attribut est déjà vide cela crache une erreur car l'attribut n'existe déjà plus
@ldap_mod_del($connection, $dn, [$key => []]);
unset($attrs[$key]);
}
}
if (isset($oldid) && $oldid != $niveau03->getLabel()) {
$olddn = $this->getNiveau03DN($oldid);
$this->rename($olddn, 'cn='.$niveau03->getLabel(), $this->baseniveau03);
}
$result = ldap_modify($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
}
public function deleteNiveau03(Niveau03 $niveau03)
{
$dn = $this->getNiveau03DN($niveau03->getLabel());
return $this->deleteByDN($dn);
}
private function getObjectClassesNiveau03()
{
$oc = [
'top',
'posixGroup',
];
return $oc;
}
public function listAttributesNiveau03()
{
return [
'cn',
'gidnumber',
'memberuid',
];
}
public function fillAttributesNiveau03(Niveau03 $niveau03, array &$attrs)
{
$attrs['cn'] = $niveau03->getLabel();
$attrs['gidnumber'] = $niveau03->getId();
$attrs['memberuid'] = [];
foreach ($niveau03->getUsers() as $user) {
if ($user->isIsactive()) {
array_push($attrs['memberuid'], $user->getUsername());
}
}
sort($attrs['memberuid']);
if (1 == count($attrs['memberuid'])) {
$attrs['memberuid'] = $attrs['memberuid'][0];
}
}
public function getNiveau03DN($id)
{
return 'cn='.$id.','.$this->baseniveau03;
}
// ==================================================================================================================================================================
// == Function Niveau04==============================================================================================================================================
// ==================================================================================================================================================================
public function addNiveau04(Niveau04 $niveau04)
{
$connection = $this->connect();
$dn = $this->getNiveau04DN($niveau04->getLabel());
$attrs = [];
$attrs['objectclass'] = $this->getObjectClassesNiveau04();
$this->fillAttributesNiveau04($niveau04, $attrs);
foreach ($attrs as $key => $value) {
if (empty($value)) {
unset($attrs[$key]);
}
}
$result = ldap_add($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
return $result;
}
public function ismodifyNiveau04(Niveau04 $niveau04, $entry)
{
$attrs = [];
$this->fillAttributesNiveau04($niveau04, $attrs);
foreach ($attrs as $key => $value) {
if (!array_key_exists($key, $entry) && !empty($value)) {
return true;
} elseif (array_key_exists($key, $entry) && $value != $entry[$key]) {
return true;
}
}
foreach ($entry as $key => $value) {
if (!array_key_exists($key, $attrs) && !empty($value)) {
return true;
} elseif (array_key_exists($key, $attrs) && $value != $attrs[$key]) {
return true;
}
}
return false;
}
public function modifyNiveau04(Niveau04 $niveau04, $oldid)
{
$dn = $this->basedn;
$connection = $this->connect();
$attrs = [];
$this->fillAttributesNiveau04($niveau04, $attrs);
unset($attrs['cn']);
$dn = $this->getNiveau04DN($niveau04->getLabel());
foreach ($attrs as $key => $value) {
if (empty($value)) {
// Bien mettre un @ car si l'attribut est déjà vide cela crache une erreur car l'attribut n'existe déjà plus
@ldap_mod_del($connection, $dn, [$key => []]);
unset($attrs[$key]);
}
}
if (isset($oldid) && $oldid != $niveau04->getLabel()) {
$olddn = $this->getNiveau04DN($oldid);
$this->rename($olddn, 'cn='.$niveau04->getLabel(), $this->baseniveau04);
}
$result = ldap_modify($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
}
public function deleteNiveau04(Niveau04 $niveau04)
{
$dn = $this->getNiveau04DN($niveau04->getLabel());
return $this->deleteByDN($dn);
}
private function getObjectClassesNiveau04()
{
$oc = [
'top',
'posixGroup',
];
return $oc;
}
public function listAttributesNiveau04()
{
return [
'cn',
'gidnumber',
'memberuid',
];
}
public function fillAttributesNiveau04(Niveau04 $niveau04, array &$attrs)
{
$attrs['cn'] = $niveau04->getLabel();
$attrs['gidnumber'] = $niveau04->getId();
$attrs['memberuid'] = [];
foreach ($niveau04->getUsers() as $user) {
if ($user->isIsactive()) {
array_push($attrs['memberuid'], $user->getUsername());
}
}
sort($attrs['memberuid']);
if (1 == count($attrs['memberuid'])) {
$attrs['memberuid'] = $attrs['memberuid'][0];
}
}
public function getNiveau04DN($id)
{
return 'cn='.$id.','.$this->baseniveau04;
}
// ==================================================================================================================================================================
// == Function Group=================================================================================================================================================
// ==================================================================================================================================================================
public function addGroup(Group $group)
{
$connection = $this->connect();
$dn = $this->getGroupDN($group->getLabel());
$attrs = [];
$attrs['objectclass'] = $this->getObjectClassesGroup();
$this->fillAttributesGroup($group, $attrs);
foreach ($attrs as $key => $value) {
if (empty($value)) {
unset($attrs[$key]);
}
}
$result = ldap_add($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
return $result;
}
public function ismodifyGroup(Group $group, $entry)
{
$attrs = [];
$this->fillAttributesGroup($group, $attrs);
foreach ($attrs as $key => $value) {
if (!array_key_exists($key, $entry) && !empty($value)) {
return true;
} elseif (array_key_exists($key, $entry) && $value != $entry[$key]) {
return true;
}
}
foreach ($entry as $key => $value) {
if (!array_key_exists($key, $attrs) && !empty($value)) {
return true;
} elseif (array_key_exists($key, $attrs) && $value != $attrs[$key]) {
return true;
}
}
return false;
}
public function modifyGroup(Group $group, $oldid)
{
$dn = $this->basedn;
$connection = $this->connect();
$attrs = [];
$this->fillAttributesGroup($group, $attrs);
unset($attrs['cn']);
$dn = $this->getGroupDN($group->getLabel());
foreach ($attrs as $key => $value) {
if (empty($value)) {
// Bien mettre un @ car si l'attribut est déjà vide cela crache une erreur car l'attribut n'existe déjà plus
@ldap_mod_del($connection, $dn, [$key => []]);
unset($attrs[$key]);
}
}
if (isset($oldid) && $oldid != $group->getLabel()) {
$olddn = $this->getGroupDN($oldid);
$this->rename($olddn, 'cn='.$group->getLabel(), $this->basegroup);
}
$result = ldap_modify($connection, $dn, $attrs);
if (!$result) {
$this->ldapError();
}
}
public function deleteGroup(Group $group)
{
$dn = $this->getGroupDN($group->getLabel());
return $this->deleteByDN($dn);
}
private function getObjectClassesGroup()
{
$oc = [
'top',
'posixGroup',
];
return $oc;
}
public function listAttributesGroup()
{
return [
'cn',
'gidnumber',
'memberuid',
];
}
public function fillAttributesGroup(Group $group, array &$attrs)
{
$attrs['cn'] = $group->getLabel();
$attrs['gidnumber'] = $group->getId();
$attrs['memberuid'] = [];
foreach ($group->getUsers() as $usergroup) {
if ($usergroup->getUser()->isIsactive()) {
array_push($attrs['memberuid'], $usergroup->getUser()->getUsername());
}
}
sort($attrs['memberuid']);
if (1 == count($attrs['memberuid'])) {
$attrs['memberuid'] = $attrs['memberuid'][0];
}
}
public function getGroupDN($id)
{
return 'cn='.$id.','.$this->basegroup;
}
// ==================================================================================================================================================================
// == Function UserGroup=============================================================================================================================================
// ==================================================================================================================================================================
public function addUserGroup(UserGroup $usergroup)
{
$dn = $this->basedn;
$connection = $this->connect();
// On recherche le group en cours
$criteria = '(cn='.$usergroup->getGroup()->getLabel().')';
$subbranch = $this->basegroup;
$result = $this->search($criteria, ['memberuid'], $subbranch);
if (!$this->in_array_r($usergroup->getUser()->getUsername(), $result[0])) {
if ($usergroup->getUser()->isIsactive()) {
$dn = $this->getGroupDN($usergroup->getGroup()->getLabel());
$entry['memberuid'] = $usergroup->getUser()->getUsername();
$result = ldap_mod_add($connection, $dn, $entry);
if (!$result) {
$this->ldapError();
}
}
}
return $result;
}
public function delUserGroup(UserGroup $usergroup)
{
$dn = $this->basedn;
$connection = $this->connect();
// On recherche le group en cours
$criteria = '(cn='.$usergroup->getGroup()->getLabel().')';
$subbranch = $this->basegroup;
$result = $this->search($criteria, ['memberuid'], $subbranch);
if ($this->in_array_r($usergroup->getUser()->getUsername(), $result[0])) {
$dn = $this->getGroupDN($usergroup->getGroup()->getLabel());
$entry['memberuid'] = $usergroup->getUser()->getUsername();
$result = ldap_mod_del($connection, $dn, $entry);
if (!$result) {
$this->ldapError();
}
}
return $result;
}
}

36
src/Service/PasswordEncoder.php Executable file
View File

@ -0,0 +1,36 @@
<?php
namespace App\Service;
use Symfony\Component\PasswordHasher\Exception\InvalidPasswordException;
use Symfony\Component\PasswordHasher\Hasher\CheckPasswordLengthTrait;
use Symfony\Component\PasswordHasher\LegacyPasswordHasherInterface;
class PasswordEncoder implements LegacyPasswordHasherInterface
{
use CheckPasswordLengthTrait;
public function hash(string $plainPassword, string $salt = null): string
{
if ($this->isPasswordTooLong($plainPassword)) {
throw new InvalidPasswordException();
}
$hash = '{SSHA}'.base64_encode(pack('H*', sha1($plainPassword.$salt)).$salt);
return $hash;
}
public function verify(string $hashedPassword, string $plainPassword, string $salt = null): bool
{
if ('' === $plainPassword || $this->isPasswordTooLong($plainPassword)) {
return false;
}
return $this->hash($plainPassword, $salt) === $hashedPassword;
}
public function needsRehash(string $hashedPassword): bool
{
return false;
}
}

26
src/Service/UserChecker.php Executable file
View File

@ -0,0 +1,26 @@
<?php
namespace App\Service;
use App\Entity\User;
use Symfony\Component\Security\Core\Exception\AccountExpiredException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAccountStatusException;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;
class UserChecker implements UserCheckerInterface
{
public function checkPreAuth(UserInterface $user): void
{
if (!$user instanceof User) {
return;
}
}
public function checkPostAuth(UserInterface $user): void
{
if (!$user instanceof User) {
return;
}
}
}

13
src/Validator/Password.php Executable file
View File

@ -0,0 +1,13 @@
<?php
namespace App\Validator;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class Password extends Constraint
{
public $message = 'Votre mot de passe doit contenir au minimum 8 caractères, constitué de chiffres, de lettres et caractères spéciaux';
}

View File

@ -0,0 +1,27 @@
<?php
namespace App\Validator;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
* @Annotation
*/
class PasswordValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
if (!empty($value)) {
if (strlen($value) < '8') {
$this->context->addViolation($constraint->message);
} elseif (!preg_match('#[0-9]+#', $value)) {
$this->context->addViolation($constraint->message);
} elseif (!preg_match('#[a-zA-Z]+#', $value)) {
$this->context->addViolation($constraint->message);
} elseif (!preg_match("/[|!@#$%&*\/=?,;.:\-_+~^\\\]/", $value)) {
$this->context->addViolation($constraint->message);
}
}
}
}

14
src/Validator/Userusername.php Executable file
View File

@ -0,0 +1,14 @@
<?php
namespace App\Validator;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class Userusername extends Constraint
{
public $messageinvalid = "Le login n'est pas valide";
public $messagenotunique = 'Le login exisite déjà';
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Validator;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
* @Annotation
*/
class UserusernameValidator extends ConstraintValidator
{
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function validate($value, Constraint $constraint)
{
if (!empty($value)) {
// On s'assure que le login soit de 5 caractères minimum
if (strlen($value) < '5') {
$this->context->addViolation($constraint->messageinvalid);
}
// On s'assure que le username ne contient pas des caractères speciaux
$string = preg_replace('~[^@a-zA-Z0-9._-]~', '', $value);
if ($string != $value) {
$this->context->addViolation($constraint->messageinvalid);
}
// On s'assure que le username n'existe pas dans la table des registration
$registration = $this->em->getRepository("App\Entity\Registration")->findOneBy(['username' => $value]);
if ($registration) {
$this->context->addViolation($constraint->messagenotunique);
}
}
}
}