src/Security/WebUser.php line 46

  1. <?php
  2. namespace App\Security;
  3. use App\Entity\User;
  4. use Doctrine\ORM\EntityManager;
  5. use Doctrine\ORM\OptimisticLockException;
  6. //use Doctrine\ORM\ORMException;
  7. use Doctrine\ORM\ORMException;
  8. use Symfony\Component\Ldap\Entry;
  9. use Symfony\Component\Ldap\Exception\ConnectionException;
  10. use Symfony\Component\Ldap\LdapInterface;
  11. use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
  12. use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
  13. use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
  14. //use AppBundle\Entity\User;
  15. //use Symfony\Component\Security\Core\Exception\UserNotFoundException;
  16. use Symfony\Component\Security\Core\User\UserInterface;
  17. use Symfony\Component\Security\Core\User\UserProviderInterface;
  18. //use AppBundle\Security\LdapUserProvider;
  19. class WebUser implements UserProviderInterface
  20. {
  21.     private LdapInterface $ldap;
  22.     private string $baseDn;
  23.     private $searchDn;
  24.     private $searchPassword;
  25.     private array $defaultRoles;
  26.     private string|array $defaultSearch;
  27.     private $filterAdmin;
  28.     private $passwordAttribute;
  29.     private EntityManager $em;
  30.     /**
  31.      * @param LdapInterface $ldap
  32.      * @param string $baseDn
  33.      * @param null $searchDn
  34.      * @param null $searchPassword
  35.      * @param array $defaultRoles
  36.      * @param string $uidKey
  37.      * @param EntityManager $em
  38.      * @param string $filterAdmin
  39.      * @param string $filter
  40.      * @param null $passwordAttribute
  41.      */
  42.     public function __construct(
  43.         LdapInterface $ldap,
  44.         $baseDn,
  45.         $searchDn null,
  46.         $searchPassword null,
  47.         array $defaultRoles = array(),
  48.         $uidKey 'sAMAccountName',
  49.         EntityManager $em,
  50.         $filterAdmin '(memberUid={username})',
  51.         $filter '({uid_key}={username})',
  52.         $passwordAttribute null
  53.     ) {
  54.         $this->ldap $ldap;
  55.         $this->baseDn $baseDn;
  56.         $this->searchDn $searchDn;
  57.         $this->searchPassword $searchPassword;
  58.         $this->defaultRoles $defaultRoles;
  59.         $this->em $em;
  60.         $this->defaultSearch str_replace('{uid_key}'$uidKey$filter);
  61.         $this->filterAdmin $filterAdmin;
  62.         $this->passwordAttribute $passwordAttribute;
  63.     }
  64.     /**
  65.      * @throws OptimisticLockException
  66.      */
  67.     public function loadUserByUsername($username)
  68.     {
  69.         try {
  70.             $this->ldap->bind($this->searchDn$this->searchPassword);
  71.             $username $this->ldap->escape($username''LdapInterface::ESCAPE_FILTER);
  72.             $query str_replace('{username}'$username$this->defaultSearch);
  73.             $search $this->ldap->query($this->baseDn$query);
  74.         } catch (ConnectionException $e) {
  75.             throw new UsernameNotFoundException(sprintf('User "%s" not found.'$username), 0$e);
  76.         }
  77.         $entries $search->execute();
  78.         $count count($entries);
  79.         if (!$count) {
  80.             throw new UsernameNotFoundException(sprintf('User "%s" not found.'$username));
  81.         }
  82.         if ($count 1) {
  83.             throw new UsernameNotFoundException('More than one user found');
  84.         }
  85.         // Lorsque nous avons vérifier que l'utilisateur existe bien dans le LDAP on peut le loader/créer son compte utilisateur
  86.         return $this->loadUser($username$entries[0]);
  87.     }
  88.     /**
  89.      * {@inheritdoc}
  90.      */
  91.     public function refreshUser(UserInterface $user)
  92.     {
  93.         if (!$user instanceof User) {
  94.             throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.'get_class($user)));
  95.         }
  96.         $userRepository $this->em->getRepository("AppBundle:User");
  97.         $user $userRepository->findOneBy(array("username" => $user->getUsername()));
  98.         if ($user === null) {
  99.             throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.'get_class($user)));
  100.         }
  101.         return $user;
  102.     }
  103.     /**
  104.      * {@inheritdoc}
  105.      */
  106.     public function supportsClass($class): bool
  107.     {
  108.         return $class === User::class;
  109.     }
  110.     /**
  111.      * Loads a user from an LDAP entry.
  112.      * @param string $username
  113.      * @param Entry $entry
  114.      * @return User
  115.      * @throws OptimisticLockException|ORMException
  116.      */
  117.     protected function loadUser(string $usernameEntry $entry): User
  118.     {
  119.         $userRepository $this->em->getRepository("AppBundle:User");
  120.         $user $userRepository->findOneBy(array("username" => $username));
  121.         if ($user === null) {
  122.             $user = new User();
  123.             $user->setFirstname($entry->getAttribute("givenName")[0]);
  124.             $user->setLastname($entry->getAttribute("sn")[0]);
  125.             $user->setEmail($entry->getAttribute("mail")[0]);
  126.             $user->setUsername($entry->getAttribute("uid")[0]);
  127.             $user->setRoles($this->defaultRoles);
  128.             $this->em->persist($user);
  129.         }
  130.         $this->em->flush();
  131.         return $user;
  132.     }
  133.     /**
  134.      * Fetches the password from an LDAP entry.
  135.      *
  136.      * @param Entry $entry
  137.      * @return mixed|void
  138.      */
  139.     private function getPassword(Entry $entry)
  140.     {
  141.         if (null === $this->passwordAttribute) {
  142.             return;
  143.         }
  144.         if (!$entry->hasAttribute($this->passwordAttribute)) {
  145.             throw new InvalidArgumentException(sprintf('Missing attribute "%s" for user "%s".'$this->passwordAttribute$entry->getDn()));
  146.         }
  147.         $values $entry->getAttribute($this->passwordAttribute);
  148.         if (!== count($values)) {
  149.             throw new InvalidArgumentException(sprintf('Attribute "%s" has multiple values.'$this->passwordAttribute));
  150.         }
  151.         return $values[0];
  152.     }
  153.     public function loadUserByIdentifier(string $identifier): UserInterface
  154.     {
  155.         // TODO: Implement loadUserByIdentifier() method.
  156.     }
  157. }