View source
<?php
declare (strict_types=1);
namespace Drupal\ldap_servers;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\externalauth\Authmap;
use Drupal\user\UserInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Ldap\Entry;
use Symfony\Component\Ldap\Exception\LdapException;
use function is_array;
class LdapUserManager extends LdapBaseManager {
protected $cache;
protected $externalAuth;
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;
}
public function createLdapEntry(Entry $entry) : bool {
if (!$this
->checkAvailability()) {
return FALSE;
}
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;
}
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);
}
protected function convertPasswordForActiveDirectoryUnicodePwd($password) {
if (!is_array($password)) {
return mb_convert_encoding(sprintf('"%s"', $password), 'UTF-16LE');
}
return [
mb_convert_encoding(sprintf('"%s"', $password[0]), 'UTF-16LE'),
];
}
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) {
$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;
}
public function getUserDataByIdentifier(string $identifier) {
if (!$this
->checkAvailability()) {
return FALSE;
}
$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;
}
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;
}
}