You are here

class LdapUserManager in Lightweight Directory Access Protocol (LDAP) 8.4

LDAP User Manager.

Hierarchy

Expanded class hierarchy of LdapUserManager

6 files declare their use of LdapUserManager
DrupalUserProcessor.php in ldap_user/src/Processor/DrupalUserProcessor.php
LdapEntryDeletionSubscriber.php in ldap_user/src/EventSubscriber/LdapEntryDeletionSubscriber.php
LdapEntryProvisionSubscriber.php in ldap_user/src/EventSubscriber/LdapEntryProvisionSubscriber.php
LdapUserTestForm.php in ldap_user/src/Form/LdapUserTestForm.php
LoginValidatorBase.php in ldap_authentication/src/Controller/LoginValidatorBase.php

... See full list

1 string reference to 'LdapUserManager'
ldap_servers.services.yml in ldap_servers/ldap_servers.services.yml
ldap_servers/ldap_servers.services.yml
1 service uses LdapUserManager
ldap.user_manager in ldap_servers/ldap_servers.services.yml
Drupal\ldap_servers\LdapUserManager

File

ldap_servers/src/LdapUserManager.php, line 20

Namespace

Drupal\ldap_servers
View source
class LdapUserManager extends LdapBaseManager {

  /**
   * Cache.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface
   */
  protected $cache;

  /**
   * Externalauth.
   *
   * @var \Drupal\externalauth\Authmap
   */
  protected $externalAuth;

  /**
   * Constructor.
   *
   * @param \Psr\Log\LoggerInterface $logger
   *   Logger.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Entity Type Manager.
   * @param \Drupal\ldap_servers\LdapBridgeInterface $ldap_bridge
   *   LDAP bridge.
   * @param \Drupal\Core\Extension\ModuleHandler $module_handler
   *   Module handler.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
   *   Cache.
   * @param \Drupal\externalauth\Authmap $external_auth
   *   External auth.
   */
  public function __construct(LoggerInterface $logger, EntityTypeManagerInterface $entity_type_manager, LdapBridgeInterface $ldap_bridge, ModuleHandler $module_handler, CacheBackendInterface $cache, Authmap $external_auth) {
    parent::__construct($logger, $entity_type_manager, $ldap_bridge, $module_handler);
    $this->cache = $cache;
    $this->externalAuth = $external_auth;
  }

  /**
   * Create LDAP User entry.
   *
   * Adds AD-specific password handling.
   *
   * @param \Symfony\Component\Ldap\Entry $entry
   *   LDAP Entry.
   *
   * @return bool
   *   Result of action.
   */
  public function createLdapEntry(Entry $entry) : bool {
    if (!$this
      ->checkAvailability()) {
      return FALSE;
    }

    // Can be mixed case on direction-to-LDAP.
    if ($entry
      ->hasAttribute('unicodePwd', FALSE) && $this->server
      ->get('type') === 'ad') {
      $converted = $this
        ->convertPasswordForActiveDirectoryUnicodePwd($entry
        ->getAttribute('unicodePwd', FALSE)[0]);
      $entry
        ->setAttribute('unicodePwd', [
        $converted,
      ]);
    }
    try {
      $this->ldap
        ->getEntryManager()
        ->add($entry);
    } catch (LdapException $e) {
      $this->logger
        ->error("LDAP server %id exception: %ldap_error", [
        '%id' => $this->server
          ->id(),
        '%ldap_error' => $e
          ->getMessage(),
      ]);
      return FALSE;
    }
    return TRUE;
  }

  /**
   * Apply modifications to entry.
   *
   * @param \Symfony\Component\Ldap\Entry $entry
   *   LDAP Entry.
   * @param \Symfony\Component\Ldap\Entry $current
   *   LDAP Entry.
   *
   * @todo / @FIXME: This is not called.
   */
  protected function applyModificationsToEntry(Entry $entry, Entry $current) : void {
    if ($entry
      ->hasAttribute('unicodePwd', FALSE) && $this->server
      ->get('type') === 'ad') {
      $converted = $this
        ->convertPasswordForActiveDirectoryUnicodePwd($entry
        ->getAttribute('unicodePwd', FALSE)[0]);
      $entry
        ->setAttribute('unicodePwd', [
        $converted,
      ]);
    }
    parent::applyModificationsToEntry($entry, $current);
  }

  /**
   * Convert password to format required by Active Directory.
   *
   * For the purpose of changing or setting the password. Note that AD needs the
   * field to be called unicodePwd (as opposed to userPassword).
   *
   * @param string|array $password
   *   The password that is being formatted for Active Directory unicodePwd
   *   field.
   *
   * @return string|array
   *   $password surrounded with quotes and in UTF-16LE encoding
   */
  protected function convertPasswordForActiveDirectoryUnicodePwd($password) {

    // This function can be called with $attributes['unicodePwd'] as an array.
    if (!is_array($password)) {
      return mb_convert_encoding(sprintf('"%s"', $password), 'UTF-16LE');
    }

    // Presumably there is no use case for there being more than one password
    // in the $attributes array, hence it will be at index 0, and we return in
    // kind.
    return [
      mb_convert_encoding(sprintf('"%s"', $password[0]), 'UTF-16LE'),
    ];
  }

  /**
   * Fetches the user account based on the persistent UID.
   *
   * @param string $puid
   *   As returned from ldap_read or other LDAP function (can be binary).
   *
   * @return \Drupal\user\UserInterface|null
   *   The updated user or error.
   */
  public function getUserAccountFromPuid(string $puid) : ?UserInterface {
    $result = NULL;
    if ($this
      ->checkAvailability()) {
      $storage = $this->entityTypeManager
        ->getStorage('user');
      $query = $storage
        ->getQuery();
      $query
        ->condition('ldap_user_puid_sid', $this->server
        ->id(), '=')
        ->condition('ldap_user_puid', $puid, '=')
        ->condition('ldap_user_puid_property', $this->server
        ->getUniquePersistentAttribute(), '=')
        ->accessCheck(FALSE);
      $queryResult = $query
        ->execute();
      if (count($queryResult) === 1) {

        /** @var \Drupal\user\UserInterface $result */
        $result = $storage
          ->load(array_values($queryResult)[0]);
      }
      if (count($queryResult) > 1) {
        $uids = implode(',', $queryResult);
        $this->logger
          ->error('Multiple users (uids: %uids) with same puid (puid=%puid, sid=%sid, ldap_user_puid_property=%ldap_user_puid_property)', [
          '%uids' => $uids,
          '%puid' => $puid,
          '%id' => $this->server
            ->id(),
          '%ldap_user_puid_property' => $this->server
            ->getUniquePersistentAttribute(),
        ]);
      }
    }
    return $result;
  }

  /**
   * Fetch user data from server by Identifier.
   *
   * @param string $identifier
   *   User identifier.
   *
   * @return \Symfony\Component\Ldap\Entry|false
   *
   *   This should go into LdapUserProcessor or LdapUserManager, leaning toward
   *   the former.
   */
  public function getUserDataByIdentifier(string $identifier) {
    if (!$this
      ->checkAvailability()) {
      return FALSE;
    }

    // Try to retrieve the user from the cache.
    $cache = $this->cache
      ->get('ldap_servers:user_data:' . $identifier);
    if ($cache && $cache->data) {
      return $cache->data;
    }
    $ldap_entry = $this
      ->queryAllBaseDnLdapForUsername($identifier);
    if ($ldap_entry) {
      $ldap_entry = $this
        ->sanitizeUserDataResponse($ldap_entry, $identifier);
      $cache_expiry = 5 * 60 + time();
      $cache_tags = [
        'ldap',
        'ldap_servers',
        'ldap_servers.user_data',
      ];
      $this->cache
        ->set('ldap_servers:user_data:' . $identifier, $ldap_entry, $cache_expiry, $cache_tags);
    }
    return $ldap_entry;
  }

  /**
   * Fetch user data from server by user account.
   *
   * @param \Drupal\user\UserInterface $account
   *   Drupal user account.
   *
   * @return \Symfony\Component\Ldap\Entry|false
   *   Returns entry or FALSE.
   *
   *   @todo This should go into LdapUserProcessor or LdapUserManager,
   *   leaning toward the former.
   */
  public function getUserDataByAccount(UserInterface $account) {
    if (!$this
      ->checkAvailability()) {
      return FALSE;
    }
    $identifier = $this->externalAuth
      ->get($account
      ->id(), 'ldap_user');
    if ($identifier) {
      return $this
        ->getUserDataByIdentifier($identifier);
    }
    return FALSE;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
LdapBaseManager::$entityTypeManager protected property Entity Type Manager.
LdapBaseManager::$ldap protected property Symfony Ldap.
LdapBaseManager::$ldapBridge protected property LDAP Bridge.
LdapBaseManager::$logger protected property Logger.
LdapBaseManager::$moduleHandler protected property Module handler.
LdapBaseManager::$server protected property Server.
LdapBaseManager::checkAvailability protected function Check availability of service.
LdapBaseManager::checkDnExists public function Does dn exist for this server?
LdapBaseManager::checkDnExistsIncludeData public function Does dn exist for this server and what is its data?
LdapBaseManager::deleteLdapEntry public function Perform an LDAP delete.
LdapBaseManager::matchUsernameToExistingLdapEntry public function Match username to existing LDAP entry.
LdapBaseManager::modifyLdapEntry public function Modify attributes of LDAP entry.
LdapBaseManager::queryAllBaseDnLdapForUsername public function Queries LDAP server for the user.
LdapBaseManager::queryLdapForUsername public function Queries LDAP server for the user.
LdapBaseManager::sanitizeUserDataResponse public function Sanitize user data response.
LdapBaseManager::searchAllBaseDns public function Perform an LDAP search on all base dns and aggregate into one result.
LdapBaseManager::setServer public function Set server by ID.
LdapBaseManager::setServerById public function Set server by ID.
LdapTransformationTraits::ldapEscapeDn protected function Wrapper for ldap_escape().
LdapTransformationTraits::ldapEscapeFilter protected function Wrapper for ldap_escape().
LdapTransformationTraits::php56PolyfillLdapEscape public static function Stub implementation of the {@link ldap_escape()} function of ext-ldap.
LdapTransformationTraits::splitDnWithAttributes public static function Wrapper for ldap_explode_dn().
LdapTransformationTraits::splitDnWithValues public static function Wrapper for ldap_explode_dn().
LdapUserManager::$cache protected property Cache.
LdapUserManager::$externalAuth protected property Externalauth.
LdapUserManager::applyModificationsToEntry protected function Apply modifications to entry. Overrides LdapBaseManager::applyModificationsToEntry
LdapUserManager::convertPasswordForActiveDirectoryUnicodePwd protected function Convert password to format required by Active Directory.
LdapUserManager::createLdapEntry public function Create LDAP User entry. Overrides LdapBaseManager::createLdapEntry
LdapUserManager::getUserAccountFromPuid public function Fetches the user account based on the persistent UID.
LdapUserManager::getUserDataByAccount public function Fetch user data from server by user account.
LdapUserManager::getUserDataByIdentifier public function Fetch user data from server by Identifier.
LdapUserManager::__construct public function Constructor. Overrides LdapBaseManager::__construct