first commit
This commit is contained in:
115
libraries/vendor/symfony/ldap/Security/CheckLdapCredentialsListener.php
vendored
Normal file
115
libraries/vendor/symfony/ldap/Security/CheckLdapCredentialsListener.php
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Ldap\Security;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\Ldap\Exception\InvalidCredentialsException;
|
||||
use Symfony\Component\Ldap\Exception\InvalidSearchCredentialsException;
|
||||
use Symfony\Component\Ldap\LdapInterface;
|
||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||
use Symfony\Component\Security\Core\Exception\LogicException;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
|
||||
use Symfony\Component\Security\Http\Event\CheckPassportEvent;
|
||||
|
||||
/**
|
||||
* Verifies password credentials using an LDAP service whenever the
|
||||
* LdapBadge is attached to the Security passport.
|
||||
*
|
||||
* @author Wouter de Jong <wouter@wouterj.nl>
|
||||
*/
|
||||
class CheckLdapCredentialsListener implements EventSubscriberInterface
|
||||
{
|
||||
private ContainerInterface $ldapLocator;
|
||||
|
||||
public function __construct(ContainerInterface $ldapLocator)
|
||||
{
|
||||
$this->ldapLocator = $ldapLocator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function onCheckPassport(CheckPassportEvent $event)
|
||||
{
|
||||
$passport = $event->getPassport();
|
||||
if (!$passport->hasBadge(LdapBadge::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var LdapBadge $ldapBadge */
|
||||
$ldapBadge = $passport->getBadge(LdapBadge::class);
|
||||
if ($ldapBadge->isResolved()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$passport->hasBadge(PasswordCredentials::class)) {
|
||||
throw new \LogicException(sprintf('LDAP authentication requires a passport containing password credentials, authenticator "%s" does not fulfill these requirements.', $event->getAuthenticator()::class));
|
||||
}
|
||||
|
||||
/** @var PasswordCredentials $passwordCredentials */
|
||||
$passwordCredentials = $passport->getBadge(PasswordCredentials::class);
|
||||
if ($passwordCredentials->isResolved()) {
|
||||
throw new \LogicException('LDAP authentication password verification cannot be completed because something else has already resolved the PasswordCredentials.');
|
||||
}
|
||||
|
||||
if (!$this->ldapLocator->has($ldapBadge->getLdapServiceId())) {
|
||||
throw new \LogicException(sprintf('Cannot check credentials using the "%s" ldap service, as such service is not found. Did you maybe forget to add the "ldap" service tag to this service?', $ldapBadge->getLdapServiceId()));
|
||||
}
|
||||
|
||||
$presentedPassword = $passwordCredentials->getPassword();
|
||||
if ('' === $presentedPassword) {
|
||||
throw new BadCredentialsException('The presented password cannot be empty.');
|
||||
}
|
||||
|
||||
$user = $passport->getUser();
|
||||
|
||||
/** @var LdapInterface $ldap */
|
||||
$ldap = $this->ldapLocator->get($ldapBadge->getLdapServiceId());
|
||||
try {
|
||||
if ($ldapBadge->getQueryString()) {
|
||||
if ('' !== $ldapBadge->getSearchDn() && '' !== $ldapBadge->getSearchPassword()) {
|
||||
try {
|
||||
$ldap->bind($ldapBadge->getSearchDn(), $ldapBadge->getSearchPassword());
|
||||
} catch (InvalidCredentialsException) {
|
||||
throw new InvalidSearchCredentialsException();
|
||||
}
|
||||
} else {
|
||||
throw new LogicException('Using the "query_string" config without using a "search_dn" and a "search_password" is not supported.');
|
||||
}
|
||||
$identifier = $ldap->escape($user->getUserIdentifier(), '', LdapInterface::ESCAPE_FILTER);
|
||||
$query = str_replace('{user_identifier}', $identifier, $ldapBadge->getQueryString());
|
||||
$result = $ldap->query($ldapBadge->getDnString(), $query)->execute();
|
||||
if (1 !== $result->count()) {
|
||||
throw new BadCredentialsException('The presented user identifier is invalid.');
|
||||
}
|
||||
|
||||
$dn = $result[0]->getDn();
|
||||
} else {
|
||||
$identifier = $ldap->escape($user->getUserIdentifier(), '', LdapInterface::ESCAPE_DN);
|
||||
$dn = str_replace('{user_identifier}', $identifier, $ldapBadge->getDnString());
|
||||
}
|
||||
|
||||
$ldap->bind($dn, $presentedPassword);
|
||||
} catch (InvalidCredentialsException) {
|
||||
throw new BadCredentialsException('The presented password is invalid.');
|
||||
}
|
||||
|
||||
$passwordCredentials->markResolved();
|
||||
$ldapBadge->markResolved();
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [CheckPassportEvent::class => ['onCheckPassport', 144]];
|
||||
}
|
||||
}
|
||||
108
libraries/vendor/symfony/ldap/Security/LdapAuthenticator.php
vendored
Normal file
108
libraries/vendor/symfony/ldap/Security/LdapAuthenticator.php
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Ldap\Security;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
|
||||
use Symfony\Component\Security\Http\Authenticator\InteractiveAuthenticatorInterface;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
|
||||
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
|
||||
use Symfony\Component\Security\Http\EntryPoint\Exception\NotAnEntryPointException;
|
||||
|
||||
/**
|
||||
* This class decorates internal authenticators to add the LDAP integration.
|
||||
*
|
||||
* In your own authenticators, it is recommended to directly use the
|
||||
* LdapBadge in the authenticate() method. This class should only be
|
||||
* used for Symfony or third party authenticators.
|
||||
*
|
||||
* @author Wouter de Jong <wouter@wouterj.nl>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class LdapAuthenticator implements AuthenticationEntryPointInterface, InteractiveAuthenticatorInterface
|
||||
{
|
||||
private AuthenticatorInterface $authenticator;
|
||||
private string $ldapServiceId;
|
||||
private string $dnString;
|
||||
private string $searchDn;
|
||||
private string $searchPassword;
|
||||
private string $queryString;
|
||||
|
||||
public function __construct(AuthenticatorInterface $authenticator, string $ldapServiceId, string $dnString = '{user_identifier}', string $searchDn = '', string $searchPassword = '', string $queryString = '')
|
||||
{
|
||||
$this->authenticator = $authenticator;
|
||||
$this->ldapServiceId = $ldapServiceId;
|
||||
$this->dnString = $dnString;
|
||||
$this->searchDn = $searchDn;
|
||||
$this->searchPassword = $searchPassword;
|
||||
$this->queryString = $queryString;
|
||||
}
|
||||
|
||||
public function supports(Request $request): ?bool
|
||||
{
|
||||
return $this->authenticator->supports($request);
|
||||
}
|
||||
|
||||
public function authenticate(Request $request): Passport
|
||||
{
|
||||
$passport = $this->authenticator->authenticate($request);
|
||||
$passport->addBadge(new LdapBadge($this->ldapServiceId, $this->dnString, $this->searchDn, $this->searchPassword, $this->queryString));
|
||||
|
||||
return $passport;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface
|
||||
{
|
||||
throw new \BadMethodCallException(sprintf('The "%s()" method cannot be called.', __METHOD__));
|
||||
}
|
||||
|
||||
public function createToken(Passport $passport, string $firewallName): TokenInterface
|
||||
{
|
||||
return $this->authenticator->createToken($passport, $firewallName);
|
||||
}
|
||||
|
||||
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
|
||||
{
|
||||
return $this->authenticator->onAuthenticationSuccess($request, $token, $firewallName);
|
||||
}
|
||||
|
||||
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
|
||||
{
|
||||
return $this->authenticator->onAuthenticationFailure($request, $exception);
|
||||
}
|
||||
|
||||
public function start(Request $request, AuthenticationException $authException = null): Response
|
||||
{
|
||||
if (!$this->authenticator instanceof AuthenticationEntryPointInterface) {
|
||||
throw new NotAnEntryPointException(sprintf('Decorated authenticator "%s" does not implement interface "%s".', get_debug_type($this->authenticator), AuthenticationEntryPointInterface::class));
|
||||
}
|
||||
|
||||
return $this->authenticator->start($request, $authException);
|
||||
}
|
||||
|
||||
public function isInteractive(): bool
|
||||
{
|
||||
if ($this->authenticator instanceof InteractiveAuthenticatorInterface) {
|
||||
return $this->authenticator->isInteractive();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
85
libraries/vendor/symfony/ldap/Security/LdapBadge.php
vendored
Normal file
85
libraries/vendor/symfony/ldap/Security/LdapBadge.php
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Ldap\Security;
|
||||
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\BadgeInterface;
|
||||
|
||||
/**
|
||||
* A badge indicating that the credentials should be checked using LDAP.
|
||||
*
|
||||
* This badge must be used together with PasswordCredentials.
|
||||
*
|
||||
* @author Wouter de Jong <wouter@wouterj.nl>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class LdapBadge implements BadgeInterface
|
||||
{
|
||||
private bool $resolved = false;
|
||||
private string $ldapServiceId;
|
||||
private string $dnString;
|
||||
private string $searchDn;
|
||||
private string $searchPassword;
|
||||
private ?string $queryString;
|
||||
|
||||
public function __construct(string $ldapServiceId, string $dnString = '{user_identifier}', string $searchDn = '', string $searchPassword = '', string $queryString = null)
|
||||
{
|
||||
$this->ldapServiceId = $ldapServiceId;
|
||||
$dnString = str_replace('{username}', '{user_identifier}', $dnString, $replaceCount);
|
||||
if ($replaceCount > 0) {
|
||||
trigger_deprecation('symfony/ldap', '6.2', 'Using "{username}" parameter in LDAP configuration is deprecated, consider using "{user_identifier}" instead.');
|
||||
}
|
||||
$this->dnString = $dnString;
|
||||
$this->searchDn = $searchDn;
|
||||
$this->searchPassword = $searchPassword;
|
||||
$queryString = str_replace('{username}', '{user_identifier}', $queryString ?? '', $replaceCount);
|
||||
if ($replaceCount > 0) {
|
||||
trigger_deprecation('symfony/ldap', '6.2', 'Using "{username}" parameter in LDAP configuration is deprecated, consider using "{user_identifier}" instead.');
|
||||
}
|
||||
$this->queryString = $queryString;
|
||||
}
|
||||
|
||||
public function getLdapServiceId(): string
|
||||
{
|
||||
return $this->ldapServiceId;
|
||||
}
|
||||
|
||||
public function getDnString(): string
|
||||
{
|
||||
return $this->dnString;
|
||||
}
|
||||
|
||||
public function getSearchDn(): string
|
||||
{
|
||||
return $this->searchDn;
|
||||
}
|
||||
|
||||
public function getSearchPassword(): string
|
||||
{
|
||||
return $this->searchPassword;
|
||||
}
|
||||
|
||||
public function getQueryString(): ?string
|
||||
{
|
||||
return $this->queryString;
|
||||
}
|
||||
|
||||
public function markResolved(): void
|
||||
{
|
||||
$this->resolved = true;
|
||||
}
|
||||
|
||||
public function isResolved(): bool
|
||||
{
|
||||
return $this->resolved;
|
||||
}
|
||||
}
|
||||
113
libraries/vendor/symfony/ldap/Security/LdapUser.php
vendored
Normal file
113
libraries/vendor/symfony/ldap/Security/LdapUser.php
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Ldap\Security;
|
||||
|
||||
use Symfony\Component\Ldap\Entry;
|
||||
use Symfony\Component\Security\Core\User\EquatableInterface;
|
||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
/**
|
||||
* @author Robin Chalas <robin.chalas@gmail.com>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class LdapUser implements UserInterface, PasswordAuthenticatedUserInterface, EquatableInterface
|
||||
{
|
||||
private Entry $entry;
|
||||
private string $identifier;
|
||||
private ?string $password;
|
||||
private array $roles;
|
||||
private array $extraFields;
|
||||
|
||||
public function __construct(Entry $entry, string $identifier, #[\SensitiveParameter] ?string $password, array $roles = [], array $extraFields = [])
|
||||
{
|
||||
if (!$identifier) {
|
||||
throw new \InvalidArgumentException('The username cannot be empty.');
|
||||
}
|
||||
|
||||
$this->entry = $entry;
|
||||
$this->identifier = $identifier;
|
||||
$this->password = $password;
|
||||
$this->roles = $roles;
|
||||
$this->extraFields = $extraFields;
|
||||
}
|
||||
|
||||
public function getEntry(): Entry
|
||||
{
|
||||
return $this->entry;
|
||||
}
|
||||
|
||||
public function getRoles(): array
|
||||
{
|
||||
return $this->roles;
|
||||
}
|
||||
|
||||
public function getPassword(): ?string
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
public function getSalt(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal for compatibility with Symfony 5.4
|
||||
*/
|
||||
public function getUsername(): string
|
||||
{
|
||||
return $this->getUserIdentifier();
|
||||
}
|
||||
|
||||
public function getUserIdentifier(): string
|
||||
{
|
||||
return $this->identifier;
|
||||
}
|
||||
|
||||
public function eraseCredentials(): void
|
||||
{
|
||||
$this->password = null;
|
||||
}
|
||||
|
||||
public function getExtraFields(): array
|
||||
{
|
||||
return $this->extraFields;
|
||||
}
|
||||
|
||||
public function setPassword(#[\SensitiveParameter] string $password): void
|
||||
{
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
public function isEqualTo(UserInterface $user): bool
|
||||
{
|
||||
if (!$user instanceof self) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->getPassword() !== $user->getPassword()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->getSalt() !== $user->getSalt()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->getUserIdentifier() !== $user->getUserIdentifier()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
187
libraries/vendor/symfony/ldap/Security/LdapUserProvider.php
vendored
Normal file
187
libraries/vendor/symfony/ldap/Security/LdapUserProvider.php
vendored
Normal file
@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Ldap\Security;
|
||||
|
||||
use Symfony\Component\Ldap\Entry;
|
||||
use Symfony\Component\Ldap\Exception\ExceptionInterface;
|
||||
use Symfony\Component\Ldap\Exception\InvalidCredentialsException;
|
||||
use Symfony\Component\Ldap\Exception\InvalidSearchCredentialsException;
|
||||
use Symfony\Component\Ldap\LdapInterface;
|
||||
use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||
|
||||
/**
|
||||
* LdapUserProvider is a simple user provider on top of LDAP.
|
||||
*
|
||||
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
||||
* @author Charles Sarrazin <charles@sarraz.in>
|
||||
* @author Robin Chalas <robin.chalas@gmail.com>
|
||||
*/
|
||||
class LdapUserProvider implements UserProviderInterface, PasswordUpgraderInterface
|
||||
{
|
||||
private LdapInterface $ldap;
|
||||
private string $baseDn;
|
||||
private ?string $searchDn;
|
||||
private ?string $searchPassword;
|
||||
private array $defaultRoles;
|
||||
private ?string $uidKey;
|
||||
private string $defaultSearch;
|
||||
private ?string $passwordAttribute;
|
||||
private array $extraFields;
|
||||
|
||||
public function __construct(LdapInterface $ldap, string $baseDn, string $searchDn = null, #[\SensitiveParameter] string $searchPassword = null, array $defaultRoles = [], string $uidKey = null, string $filter = null, string $passwordAttribute = null, array $extraFields = [])
|
||||
{
|
||||
$uidKey ??= 'sAMAccountName';
|
||||
$filter ??= '({uid_key}={user_identifier})';
|
||||
|
||||
$this->ldap = $ldap;
|
||||
$this->baseDn = $baseDn;
|
||||
$this->searchDn = $searchDn;
|
||||
$this->searchPassword = $searchPassword;
|
||||
$this->defaultRoles = $defaultRoles;
|
||||
$this->uidKey = $uidKey;
|
||||
$this->defaultSearch = str_replace('{uid_key}', $uidKey, $filter);
|
||||
$this->passwordAttribute = $passwordAttribute;
|
||||
$this->extraFields = $extraFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal for compatibility with Symfony 5.4
|
||||
*/
|
||||
public function loadUserByUsername(string $username): UserInterface
|
||||
{
|
||||
return $this->loadUserByIdentifier($username);
|
||||
}
|
||||
|
||||
public function loadUserByIdentifier(string $identifier): UserInterface
|
||||
{
|
||||
try {
|
||||
$this->ldap->bind($this->searchDn, $this->searchPassword);
|
||||
} catch (InvalidCredentialsException) {
|
||||
throw new InvalidSearchCredentialsException();
|
||||
}
|
||||
|
||||
$identifier = $this->ldap->escape($identifier, '', LdapInterface::ESCAPE_FILTER);
|
||||
$query = str_replace('{username}', '{user_identifier}', $this->defaultSearch, $replaceCount);
|
||||
if ($replaceCount > 0) {
|
||||
trigger_deprecation('symfony/ldap', '6.2', 'Using "{username}" parameter in LDAP configuration is deprecated, consider using "{user_identifier}" instead.');
|
||||
}
|
||||
$query = str_replace('{user_identifier}', $identifier, $query);
|
||||
$search = $this->ldap->query($this->baseDn, $query, ['filter' => 0 == \count($this->extraFields) ? '*' : $this->extraFields]);
|
||||
|
||||
$entries = $search->execute();
|
||||
$count = \count($entries);
|
||||
|
||||
if (!$count) {
|
||||
$e = new UserNotFoundException(sprintf('User "%s" not found.', $identifier));
|
||||
$e->setUserIdentifier($identifier);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($count > 1) {
|
||||
$e = new UserNotFoundException('More than one user found.');
|
||||
$e->setUserIdentifier($identifier);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$entry = $entries[0];
|
||||
|
||||
try {
|
||||
if (null !== $this->uidKey) {
|
||||
$identifier = $this->getAttributeValue($entry, $this->uidKey);
|
||||
}
|
||||
} catch (InvalidArgumentException) {
|
||||
}
|
||||
|
||||
return $this->loadUser($identifier, $entry);
|
||||
}
|
||||
|
||||
public function refreshUser(UserInterface $user): UserInterface
|
||||
{
|
||||
if (!$user instanceof LdapUser) {
|
||||
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_debug_type($user)));
|
||||
}
|
||||
|
||||
return new LdapUser($user->getEntry(), $user->getUserIdentifier(), $user->getPassword(), $user->getRoles(), $user->getExtraFields());
|
||||
}
|
||||
|
||||
/**
|
||||
* @final
|
||||
*/
|
||||
public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void
|
||||
{
|
||||
if (!$user instanceof LdapUser) {
|
||||
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_debug_type($user)));
|
||||
}
|
||||
|
||||
if (null === $this->passwordAttribute) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$user->getEntry()->setAttribute($this->passwordAttribute, [$newHashedPassword]);
|
||||
$this->ldap->getEntryManager()->update($user->getEntry());
|
||||
$user->setPassword($newHashedPassword);
|
||||
} catch (ExceptionInterface) {
|
||||
// ignore failed password upgrades
|
||||
}
|
||||
}
|
||||
|
||||
public function supportsClass(string $class): bool
|
||||
{
|
||||
return LdapUser::class === $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a user from an LDAP entry.
|
||||
*/
|
||||
protected function loadUser(string $identifier, Entry $entry): UserInterface
|
||||
{
|
||||
$password = null;
|
||||
$extraFields = [];
|
||||
|
||||
if (null !== $this->passwordAttribute) {
|
||||
$password = $this->getAttributeValue($entry, $this->passwordAttribute);
|
||||
}
|
||||
|
||||
foreach ($this->extraFields as $field) {
|
||||
$extraFields[$field] = $this->getAttributeValue($entry, $field);
|
||||
}
|
||||
|
||||
return new LdapUser($entry, $identifier, $password, $this->defaultRoles, $extraFields);
|
||||
}
|
||||
|
||||
private function getAttributeValue(Entry $entry, string $attribute): mixed
|
||||
{
|
||||
if (!$entry->hasAttribute($attribute)) {
|
||||
throw new InvalidArgumentException(sprintf('Missing attribute "%s" for user "%s".', $attribute, $entry->getDn()));
|
||||
}
|
||||
|
||||
$values = $entry->getAttribute($attribute);
|
||||
if (!\in_array($attribute, [$this->uidKey, $this->passwordAttribute])) {
|
||||
return $values;
|
||||
}
|
||||
|
||||
if (1 !== \count($values)) {
|
||||
throw new InvalidArgumentException(sprintf('Attribute "%s" has multiple values.', $attribute));
|
||||
}
|
||||
|
||||
return $values[0];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user