View source
<?php
namespace Drupal\ldap_user\Processor;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\file\Entity\File;
use Drupal\ldap_servers\Entity\Server;
use Drupal\ldap_servers\Helper\ConversionHelper;
use Drupal\ldap_servers\Processor\TokenProcessor;
use Drupal\ldap_user\Helper\ExternalAuthenticationHelper;
use Drupal\ldap_servers\LdapUserAttributesInterface;
use Drupal\ldap_user\Helper\LdapConfiguration;
use Drupal\ldap_user\Helper\SemaphoreStorage;
use Drupal\ldap_user\Helper\SyncMappingHelper;
use Drupal\user\Entity\User;
use Drupal\user\UserInterface;
class DrupalUserProcessor implements LdapUserAttributesInterface {
private $config;
private $account;
private $server;
private $factory;
private $detailLog;
protected $tokenProcessor;
public function __construct() {
$this->config = \Drupal::config('ldap_user.settings');
$this->factory = \Drupal::service('ldap.servers');
$this->detailLog = \Drupal::service('ldap.detail_log');
$this->tokenProcessor = \Drupal::service('ldap.token_processor');
}
public function getUserAccount() {
return $this->account;
}
public function ldapAssociateDrupalAccount($drupalUsername) {
if ($this->config
->get('drupalAcctProvisionServer')) {
$ldapServer = $this->factory
->getServerByIdEnabled($this->config
->get('drupalAcctProvisionServer'));
$this->account = user_load_by_name($drupalUsername);
if (!$this->account) {
\Drupal::logger('ldap_user')
->error('Failed to LDAP associate Drupal account %drupal_username because account not found', [
'%drupal_username' => $drupalUsername,
]);
return FALSE;
}
$ldap_user = $ldapServer
->matchUsernameToExistingLdapEntry($drupalUsername);
if (!$ldap_user) {
\Drupal::logger('ldap_user')
->error('Failed to LDAP associate Drupal account %drupal_username because corresponding LDAP entry not found', [
'%drupal_username' => $drupalUsername,
]);
return FALSE;
}
$persistentUid = $ldapServer
->userPuidFromLdapEntry($ldap_user['attr']);
if ($persistentUid) {
$this->account
->set('ldap_user_puid', $persistentUid);
}
$this->account
->set('ldap_user_puid_property', $ldapServer
->get('unique_persistent_attr'));
$this->account
->set('ldap_user_puid_sid', $ldapServer
->id());
$this->account
->set('ldap_user_current_dn', $ldap_user['dn']);
$this->account
->set('ldap_user_last_checked', time());
$this->account
->set('ldap_user_ldap_exclude', 0);
$this
->saveAccount();
$this
->syncToDrupalAccount(self::EVENT_CREATE_DRUPAL_USER, $ldap_user);
return TRUE;
}
else {
return FALSE;
}
}
public function provisionDrupalAccount(array $userData) {
$this->account = User::create($userData);
$ldapUser = FALSE;
if ($this->config
->get('drupalAcctProvisionServer')) {
$ldapUser = $this->factory
->getUserDataFromServerByIdentifier($userData['name'], $this->config
->get('drupalAcctProvisionServer'));
}
if (!$ldapUser) {
\Drupal::service('ldap.detail_log')
->log('@username: Failed to find associated LDAP entry for username in provision.', [
'@username' => $userData['name'],
], 'ldap-user');
return FALSE;
}
$this->server = $this->factory
->getServerByIdEnabled($this->config
->get('drupalAcctProvisionServer'));
if (!$this->account
->getAccountName()) {
$this->account
->set('name', $ldapUser[$this->server
->get('user_attr')]);
}
$params = [
'account' => $this->account,
'user_values' => $userData,
'prov_event' => self::EVENT_CREATE_DRUPAL_USER,
'module' => 'ldap_user',
'function' => 'provisionDrupalAccount',
'direction' => self::PROVISION_TO_DRUPAL,
];
\Drupal::moduleHandler()
->alter('ldap_entry', $ldapUser, $params);
$persistentUid = $this->server
->userPuidFromLdapEntry($ldapUser['attr']);
$accountFromPuid = $persistentUid ? $this->server
->userAccountFromPuid($persistentUid) : FALSE;
if ($accountFromPuid) {
$this
->updateExistingAccountByPersistentUid($ldapUser, $accountFromPuid);
}
else {
if (!$this
->createDrupalUser($ldapUser)) {
return FALSE;
}
}
return TRUE;
}
public function ldapExcludeDrupalAccount($drupalUsername) {
$account = User::load($drupalUsername);
if (!$account) {
\Drupal::logger('ldap_user')
->error('Failed to exclude user from LDAP association because Drupal account %username was not found', [
'%username' => $drupalUsername,
]);
return FALSE;
}
$account
->set('ldap_user_ldap_exclude', 1);
$account
->save();
return (bool) $account;
}
public function alterUserAttributes(array $attributes, array $params) {
if (isset($params['sid']) && $params['sid']) {
if (is_scalar($params['sid'])) {
$ldapServer = $this->factory
->getServerByIdEnabled($params['sid']);
}
else {
$ldapServer = $params['sid'];
}
if ($ldapServer) {
if (!isset($attributes['dn'])) {
$attributes['dn'] = [];
}
$attributes['dn'] = ConversionHelper::setAttributeMap($attributes['dn']);
switch ($params['ldap_context']) {
case 'ldap_user_insert_drupal_user':
case 'ldap_user_update_drupal_user':
case 'ldap_user_ldap_associate':
if ($ldapServer
->get('user_attr')) {
$attributes[$ldapServer
->get('user_attr')] = ConversionHelper::setAttributeMap(@$attributes[$ldapServer
->get('user_attr')]);
}
if ($ldapServer
->get('mail_attr')) {
$attributes[$ldapServer
->get('mail_attr')] = ConversionHelper::setAttributeMap(@$attributes[$ldapServer
->get('mail_attr')]);
}
if ($ldapServer
->get('picture_attr')) {
$attributes[$ldapServer
->get('picture_attr')] = ConversionHelper::setAttributeMap(@$attributes[$ldapServer
->get('picture_attr')]);
}
if ($ldapServer
->get('unique_persistent_attr')) {
$attributes[$ldapServer
->get('unique_persistent_attr')] = ConversionHelper::setAttributeMap(@$attributes[$ldapServer
->get('unique_persistent_attr')]);
}
if ($ldapServer
->get('mail_template')) {
ConversionHelper::extractTokenAttributes($attributes, $ldapServer
->get('mail_template'));
}
break;
}
$ldapContext = empty($params['ldap_context']) ? NULL : $params['ldap_context'];
$direction = empty($params['direction']) ? $this
->ldapContextToProvDirection($ldapContext) : $params['direction'];
$helper = new SyncMappingHelper();
$attributesRequiredByOtherModuleMappings = $helper
->getLdapUserRequiredAttributes($direction, $ldapContext);
$attributes = array_merge($attributesRequiredByOtherModuleMappings, $attributes);
return $attributes;
}
}
return $attributes;
}
public function alterLdapUserAttributes(array $availableUserAttributes, array $params) {
if (isset($params['direction'])) {
$direction = $params['direction'];
}
else {
$direction = self::PROVISION_TO_NONE;
}
if ($direction == self::PROVISION_TO_LDAP) {
$availableUserAttributes['[property.name]'] = [
'name' => 'Property: Username',
'source' => '',
'direction' => self::PROVISION_TO_LDAP,
'enabled' => TRUE,
'prov_events' => [
self::EVENT_CREATE_DRUPAL_USER,
self::EVENT_SYNC_TO_DRUPAL_USER,
],
'config_module' => 'ldap_user',
'prov_module' => 'ldap_user',
'configurable_to_ldap' => TRUE,
];
$availableUserAttributes['[property.mail]'] = [
'name' => 'Property: Email',
'source' => '',
'direction' => self::PROVISION_TO_LDAP,
'enabled' => TRUE,
'prov_events' => [
self::EVENT_CREATE_DRUPAL_USER,
self::EVENT_SYNC_TO_DRUPAL_USER,
],
'config_module' => 'ldap_user',
'prov_module' => 'ldap_user',
'configurable_to_ldap' => TRUE,
];
$availableUserAttributes['[property.picture]'] = [
'name' => 'Property: picture',
'source' => '',
'direction' => self::PROVISION_TO_LDAP,
'enabled' => TRUE,
'prov_events' => [
self::EVENT_CREATE_DRUPAL_USER,
self::EVENT_SYNC_TO_DRUPAL_USER,
],
'config_module' => 'ldap_user',
'prov_module' => 'ldap_user',
'configurable_to_ldap' => TRUE,
];
$availableUserAttributes['[property.uid]'] = [
'name' => 'Property: Drupal User Id (uid)',
'source' => '',
'direction' => self::PROVISION_TO_LDAP,
'enabled' => TRUE,
'prov_events' => [
self::EVENT_CREATE_DRUPAL_USER,
self::EVENT_SYNC_TO_DRUPAL_USER,
],
'config_module' => 'ldap_user',
'prov_module' => 'ldap_user',
'configurable_to_ldap' => TRUE,
];
}
foreach ([
'property.status',
'property.timezone',
'property.signature',
] as $property_id) {
$property_token = '[' . $property_id . ']';
if (!isset($availableUserAttributes[$property_token]) || !is_array($availableUserAttributes[$property_token])) {
$availableUserAttributes[$property_token] = [];
}
}
$availableUserAttributes['[property.status]'] = $availableUserAttributes['[property.status]'] + [
'name' => 'Property: Account Status',
'configurable_to_drupal' => 1,
'configurable_to_ldap' => 1,
'user_tokens' => '1=enabled, 0=blocked.',
'enabled' => FALSE,
'config_module' => 'ldap_user',
'prov_module' => 'ldap_user',
];
$availableUserAttributes['[property.timezone]'] = $availableUserAttributes['[property.timezone]'] + [
'name' => 'Property: User Timezone',
'configurable_to_drupal' => 1,
'configurable_to_ldap' => 1,
'enabled' => FALSE,
'config_module' => 'ldap_user',
'prov_module' => 'ldap_user',
];
$availableUserAttributes['[property.signature]'] = $availableUserAttributes['[property.signature]'] + [
'name' => 'Property: User Signature',
'configurable_to_drupal' => 1,
'configurable_to_ldap' => 1,
'enabled' => FALSE,
'config_module' => 'ldap_user',
'prov_module' => 'ldap_user',
];
$user_fields = \Drupal::entityManager()
->getFieldStorageDefinitions('user');
foreach ($user_fields as $field_name => $field_instance) {
$field_id = "[field.{$field_name}]";
if (!isset($availableUserAttributes[$field_id]) || !is_array($availableUserAttributes[$field_id])) {
$availableUserAttributes[$field_id] = [];
}
$availableUserAttributes[$field_id] = $availableUserAttributes[$field_id] + [
'name' => t('Field: @label', [
'@label' => $field_instance
->getLabel(),
]),
'configurable_to_drupal' => 1,
'configurable_to_ldap' => 1,
'enabled' => FALSE,
'config_module' => 'ldap_user',
'prov_module' => 'ldap_user',
];
}
if (!LdapConfiguration::provisionsDrupalAccountsFromLdap()) {
$availableUserAttributes['[property.mail]']['config_module'] = 'ldap_user';
$availableUserAttributes['[property.name]']['config_module'] = 'ldap_user';
$availableUserAttributes['[property.picture]']['config_module'] = 'ldap_user';
}
if ($direction == self::PROVISION_TO_LDAP) {
$availableUserAttributes['[password.random]'] = [
'name' => 'Password: Random password',
'source' => '',
'direction' => self::PROVISION_TO_LDAP,
'enabled' => TRUE,
'prov_events' => [
self::EVENT_CREATE_DRUPAL_USER,
self::EVENT_SYNC_TO_DRUPAL_USER,
],
'config_module' => 'ldap_user',
'prov_module' => 'ldap_user',
'configurable_to_ldap' => TRUE,
];
$availableUserAttributes['[password.user-random]'] = [
'name' => 'Password: Plain user password or random',
'source' => '',
'direction' => self::PROVISION_TO_LDAP,
'enabled' => TRUE,
'prov_events' => [
self::EVENT_CREATE_DRUPAL_USER,
self::EVENT_SYNC_TO_DRUPAL_USER,
],
'config_module' => 'ldap_user',
'prov_module' => 'ldap_user',
'configurable_to_ldap' => TRUE,
];
$availableUserAttributes['[password.user-only]'] = [
'name' => 'Password: Plain user password',
'source' => '',
'direction' => self::PROVISION_TO_LDAP,
'enabled' => TRUE,
'prov_events' => [
self::EVENT_CREATE_DRUPAL_USER,
self::EVENT_SYNC_TO_DRUPAL_USER,
],
'config_module' => 'ldap_user',
'prov_module' => 'ldap_user',
'configurable_to_ldap' => TRUE,
];
}
$mappings = $this->config
->get('ldapUserSyncMappings');
if (!empty($mappings[$direction])) {
$availableUserAttributes = $this
->applyUserAttributes($availableUserAttributes, $mappings, $direction);
}
return [
$availableUserAttributes,
$params,
];
}
public function isUserLdapAssociated(UserInterface $account) {
$associated = FALSE;
if (property_exists($account, 'ldap_user_current_dn') && !empty($account
->get('ldap_user_current_dn')->value)) {
$associated = TRUE;
}
elseif ($account
->id()) {
$authmap = ExternalAuthenticationHelper::getUserIdentifierFromMap($account
->id());
if (!empty($authmap)) {
$associated = TRUE;
}
}
return $associated;
}
public function newDrupalUserCreated(UserInterface $account) {
$this->account = $account;
if (ExternalAuthenticationHelper::excludeUser($account)) {
return;
}
if (is_object($account) && $account
->getAccountName()) {
if (SemaphoreStorage::get('provision', $account
->getAccountName()) || SemaphoreStorage::get('sync', $account
->getAccountName()) || $this
->newAccountRequest($account)) {
return;
}
}
if ($account
->isActive() && LdapConfiguration::provisionAvailableToDrupal(self::PROVISION_DRUPAL_USER_ON_USER_UPDATE_CREATE)) {
$this
->syncToDrupalAccount(self::EVENT_CREATE_DRUPAL_USER);
}
$this
->provisionLdapEntryOnUserCreation($account);
}
public function drupalUserUpdated(UserInterface $account) {
$this->account = clone $account;
if (ExternalAuthenticationHelper::excludeUser($this->account)) {
return;
}
if ($this
->provisionsLdapEntriesFromDrupalUsers() && LdapConfiguration::provisionAvailableToLdap(self::PROVISION_LDAP_ENTRY_ON_USER_ON_USER_UPDATE_CREATE)) {
$this
->provisionLdapEntryOnUserUpdateCreateEvent();
}
if (SemaphoreStorage::get('sync_drupal', $this->account
->getAccountName())) {
return;
}
else {
SemaphoreStorage::set('sync_drupal', $this->account
->getAccountName());
if (LdapConfiguration::provisionsDrupalAccountsFromLdap() && in_array(self::EVENT_SYNC_TO_DRUPAL_USER, array_keys(LdapConfiguration::provisionsDrupalEvents()))) {
$this
->syncToDrupalAccount(self::EVENT_SYNC_TO_DRUPAL_USER);
}
}
}
public function drupalUserLogsIn(UserInterface $account) {
$this->account = $account;
if (ExternalAuthenticationHelper::excludeUser($this->account)) {
return;
}
$this
->loginDrupalAccountProvisioning();
$this
->loginLdapEntryProvisioning();
}
public function drupalUserDeleted(UserInterface $account) {
$this
->deleteProvisionedLdapEntry($account);
ExternalAuthenticationHelper::deleteUserIdentifier($account
->id());
}
private function applyUserAttributes(array $availableUserAttributes, array $mappings, $direction) {
foreach ($mappings[$direction] as $target_token => $mapping) {
if ($direction == self::PROVISION_TO_DRUPAL && isset($mapping['user_attr'])) {
$key = $mapping['user_attr'];
}
elseif ($direction == self::PROVISION_TO_LDAP && isset($mapping['ldap_attr'])) {
$key = $mapping['ldap_attr'];
}
else {
continue;
}
$keys = [
'ldap_attr',
'user_attr',
'convert',
'direction',
'enabled',
'prov_events',
];
foreach ($keys as $subKey) {
if (isset($mapping[$subKey])) {
$availableUserAttributes[$key][$subKey] = $mapping[$subKey];
}
else {
$availableUserAttributes[$key][$subKey] = NULL;
}
$availableUserAttributes[$key]['config_module'] = 'ldap_user';
$availableUserAttributes[$key]['prov_module'] = 'ldap_user';
}
if ($mapping['user_attr'] == 'user_tokens') {
$availableUserAttributes['user_attr'] = $mapping['user_tokens'];
}
}
return $availableUserAttributes;
}
private function createDrupalUser(array $ldap_user) {
$this->account
->enforceIsNew();
$this
->applyAttributesToAccount($ldap_user, self::PROVISION_TO_DRUPAL, [
self::EVENT_CREATE_DRUPAL_USER,
]);
$tokens = [
'%drupal_username' => $this->account
->getAccountName(),
];
if (empty($this->account
->getAccountName())) {
drupal_set_message(t('User account creation failed because of invalid, empty derived Drupal username.'), 'error');
\Drupal::logger('ldap_user')
->error('Failed to create Drupal account %drupal_username because Drupal username could not be derived.', $tokens);
return FALSE;
}
if (!($mail = $this->account
->getEmail())) {
drupal_set_message(t('User account creation failed because of invalid, empty derived email address.'), 'error');
\Drupal::logger('ldap_user')
->error('Failed to create Drupal account %drupal_username because email address could not be derived by LDAP User module', $tokens);
return FALSE;
}
if ($account_with_same_email = user_load_by_mail($mail)) {
\Drupal::logger('ldap_user')
->error('LDAP user %drupal_username has email address (%email) conflict with a Drupal user %duplicate_name', [
'%drupal_username' => $this->account
->getAccountName(),
'%email' => $mail,
'%duplicate_name' => $account_with_same_email
->getAccountName(),
]);
drupal_set_message(t('Another user already exists in the system with the same email address. You should contact the system administrator in order to solve this conflict.'), 'error');
return FALSE;
}
$this
->saveAccount();
if (!$this->account) {
drupal_set_message(t('User account creation failed because of system problems.'), 'error');
}
else {
ExternalAuthenticationHelper::setUserIdentifier($this->account, $this->account
->getAccountName());
return TRUE;
}
}
private function updateExistingAccountByPersistentUid(array $ldap_user, UserInterface $accountFromPuid) {
$this->account = $accountFromPuid;
ExternalAuthenticationHelper::setUserIdentifier($this->account, $this->account
->getAccountName());
$this
->syncToDrupalAccount(self::EVENT_SYNC_TO_DRUPAL_USER, $ldap_user);
}
private function userPictureFromLdapEntry(array $ldap_entry) {
if ($ldap_entry && $this->server
->get('picture_attr')) {
if (isset($ldap_entry[$this->server
->get('picture_attr')][0])) {
$ldapUserPicture = $ldap_entry[$this->server
->get('picture_attr')][0];
}
else {
return FALSE;
}
if (!$this->account || $this->account
->isAnonymous() || $this->account
->id() == 1) {
return FALSE;
}
$currentUserPicture = $this->account
->get('user_picture')
->getValue();
if (empty($currentUserPicture)) {
return $this
->saveUserPicture($this->account
->get('user_picture'), $ldapUserPicture);
}
else {
$file = File::load($currentUserPicture[0]['target_id']);
if ($file && md5(file_get_contents($file
->getFileUri())) == md5($ldapUserPicture)) {
return FALSE;
}
else {
return $this
->saveUserPicture($this->account
->get('user_picture'), $ldapUserPicture);
}
}
}
}
private function saveUserPicture(FieldItemListInterface $field, $ldapUserPicture) {
$fileName = uniqid();
$unmanagedFile = file_directory_temp() . '/' . $fileName;
file_put_contents($unmanagedFile, $ldapUserPicture);
$image_type = exif_imagetype($unmanagedFile);
$extension = image_type_to_extension($image_type, FALSE);
unlink($unmanagedFile);
$fieldSettings = $field
->getFieldDefinition()
->getItemDefinition()
->getSettings();
$tokenService = \Drupal::token();
$directory = $tokenService
->replace($fieldSettings['file_directory']);
$fullDirectoryPath = $fieldSettings['uri_scheme'] . '://' . $directory;
if (!is_dir(\Drupal::service('file_system')
->realpath($fullDirectoryPath))) {
\Drupal::service('file_system')
->mkdir($fullDirectoryPath, NULL, TRUE);
}
$managed_file = file_save_data($ldapUserPicture, $fullDirectoryPath . '/' . $fileName . '.' . $extension);
$validators = [
'file_validate_is_image' => [],
'file_validate_image_resolution' => [
$fieldSettings['max_resolution'],
],
'file_validate_size' => [
$fieldSettings['max_filesize'],
],
];
$errors = file_validate($managed_file, $validators);
if ($managed_file && empty(file_validate($managed_file, $validators))) {
return [
'target_id' => $managed_file
->id(),
];
}
else {
foreach ($errors as $error) {
$this->detailLog
->log('File upload error for user image with validation error @error', [
'@error' => $error,
]);
}
return FALSE;
}
}
private function provisionsLdapEntriesFromDrupalUsers() {
if ($this->config
->get('ldapEntryProvisionServer') && count(array_filter(array_values($this->config
->get('ldapEntryProvisionTriggers')))) > 0) {
return TRUE;
}
else {
return FALSE;
}
}
private function ldapContextToProvDirection($ldapContext = NULL) {
switch ($ldapContext) {
case 'ldap_user_prov_to_drupal':
$result = self::PROVISION_TO_DRUPAL;
break;
case 'ldap_user_prov_to_ldap':
case 'ldap_user_delete_drupal_user':
$result = self::PROVISION_TO_LDAP;
break;
case 'ldap_user_insert_drupal_user':
case 'ldap_user_update_drupal_user':
case 'ldap_authentication_authenticate':
case 'ldap_user_disable_drupal_user':
$result = self::PROVISION_TO_ALL;
break;
default:
$result = self::PROVISION_TO_ALL;
break;
}
return $result;
}
private function deleteProvisionedLdapEntry(UserInterface $account) {
if ($this
->provisionsLdapEntriesFromDrupalUsers() && LdapConfiguration::provisionAvailableToLdap(self::PROVISION_LDAP_ENTRY_ON_USER_ON_USER_DELETE)) {
$ldapProcessor = new LdapUserProcessor();
$ldapProcessor
->deleteProvisionedLdapEntries($account);
}
}
private function loginLdapEntryProvisioning() {
if ($this
->provisionsLdapEntriesFromDrupalUsers() && LdapConfiguration::provisionAvailableToLdap(self::PROVISION_LDAP_ENTRY_ON_USER_ON_USER_AUTHENTICATION)) {
$ldapUserProcessor = new LdapUserProcessor();
if (SemaphoreStorage::get('provision', $this->account
->getAccountName()) == FALSE && !$ldapUserProcessor
->getProvisionRelatedLdapEntry($this->account)) {
$provisionResult = $ldapUserProcessor
->provisionLdapEntry($this->account);
if ($provisionResult['status'] == 'success') {
SemaphoreStorage::set('provision', $this->account
->getAccountName());
}
}
if (SemaphoreStorage::get('provision', $this->account
->getAccountName()) == FALSE && SemaphoreStorage::get('sync', $this->account
->getAccountName()) == FALSE) {
$result = $ldapUserProcessor
->syncToLdapEntry($this->account);
if ($result) {
SemaphoreStorage::set('sync', $this->account
->getAccountName());
}
}
}
}
private function loginDrupalAccountProvisioning() {
if (LdapConfiguration::provisionsDrupalAccountsFromLdap() && in_array(self::EVENT_SYNC_TO_DRUPAL_USER, array_keys(LdapConfiguration::provisionsDrupalEvents()))) {
$ldap_user = $this->factory
->getUserDataFromServerByAccount($this->account, $this->config
->get('drupalAcctProvisionServer'), 'ldap_user_prov_to_drupal');
if ($ldap_user) {
$this->server = $this->factory
->getServerById($this->config
->get('drupalAcctProvisionServer'));
$this
->applyAttributesToAccount($ldap_user, self::PROVISION_TO_DRUPAL, [
self::EVENT_SYNC_TO_DRUPAL_USER,
]);
}
$this
->saveAccount();
}
}
private function provisionLdapEntryOnUserUpdateCreateEvent() {
if (SemaphoreStorage::get('provision', $this->account
->getAccountName()) || SemaphoreStorage::get('sync', $this->account
->getAccountName())) {
return;
}
$processor = new LdapUserProcessor();
if (!$processor
->getProvisionRelatedLdapEntry($this->account)) {
$provisionResult = $processor
->provisionLdapEntry($this->account);
if ($provisionResult['status'] == 'success') {
SemaphoreStorage::set('provision', $this->account
->getAccountName());
}
}
if (SemaphoreStorage::get('provision', $this->account
->getAccountName()) == FALSE) {
if (LdapConfiguration::provisionAvailableToLdap(self::PROVISION_LDAP_ENTRY_ON_USER_ON_USER_UPDATE_CREATE) && $processor
->getProvisionRelatedLdapEntry($this->account)) {
$ldapProcessor = new LdapUserProcessor();
if ($ldapProcessor
->syncToLdapEntry($this->account)) {
SemaphoreStorage::set('sync', $this->account
->getAccountName());
}
}
}
}
private function saveAccount() {
$this->account
->save();
}
private function applyAttributesToAccount(array $ldapUser, $direction = NULL, array $prov_events = NULL) {
if ($direction == NULL) {
$direction = self::PROVISION_TO_DRUPAL;
}
if (!$prov_events) {
$prov_events = LdapConfiguration::getAllEvents();
}
$this
->setLdapBaseFields($ldapUser, $direction, $prov_events);
if ($direction == self::PROVISION_TO_DRUPAL && in_array(self::EVENT_CREATE_DRUPAL_USER, $prov_events)) {
$this
->setFieldsOnDrupalUserCreation($ldapUser);
}
$this
->setUserDefinedMappings($ldapUser, $direction, $prov_events);
$context = [
'ldap_server' => $this->server,
'prov_events' => $prov_events,
];
\Drupal::moduleHandler()
->alter('ldap_user_edit_user', $this->account, $ldapUser, $context);
$this->account
->set('ldap_user_last_checked', time());
}
private function syncToDrupalAccount($provisioningEvent = NULL, array $ldapUser = NULL) {
if ($provisioningEvent == NULL) {
$provisioningEvent = self::EVENT_SYNC_TO_DRUPAL_USER;
}
if (!$ldapUser && !method_exists($this->account, 'getAccountName') || !$this->account) {
\Drupal::logger('ldap_user')
->notice('Invalid selection passed to syncToDrupalAccount.');
return FALSE;
}
if (!$ldapUser && $this->config
->get('drupalAcctProvisionServer')) {
$ldapUser = $this->factory
->getUserDataFromServerByAccount($this->account, $this->config
->get('drupalAcctProvisionServer'), 'ldap_user_prov_to_drupal');
}
if (!$ldapUser) {
return FALSE;
}
if ($this->config
->get('drupalAcctProvisionServer')) {
$this->server = Server::load($this->config
->get('drupalAcctProvisionServer'));
$this
->applyAttributesToAccount($ldapUser, self::PROVISION_TO_DRUPAL, [
$provisioningEvent,
]);
}
$this
->saveAccount();
return TRUE;
}
private function provisionLdapEntryOnUserCreation(UserInterface $account) {
if ($this
->provisionsLdapEntriesFromDrupalUsers()) {
$processor = new LdapUserProcessor();
if (LdapConfiguration::provisionAvailableToLdap(self::PROVISION_LDAP_ENTRY_ON_USER_ON_USER_UPDATE_CREATE)) {
if (!$processor
->getProvisionRelatedLdapEntry($account)) {
$provision_result = $processor
->provisionLdapEntry($account);
if ($provision_result['status'] == 'success') {
SemaphoreStorage::set('provision', $account
->getAccountName());
}
}
else {
if ($processor
->syncToLdapEntry($account)) {
SemaphoreStorage::set('sync', $account
->getAccountName());
}
}
}
}
}
private function newAccountRequest(UserInterface $account) {
if (\Drupal::currentUser()
->isAnonymous() && $account
->isNew()) {
return TRUE;
}
else {
return FALSE;
}
}
private function setFieldsOnDrupalUserCreation(array $ldapUser) {
$derived_mail = $this->server
->userEmailFromLdapEntry($ldapUser['attr']);
if (!$this->account
->getEmail()) {
$this->account
->set('mail', $derived_mail);
}
if (!$this->account
->getPassword()) {
$this->account
->set('pass', user_password(20));
}
if (!$this->account
->getInitialEmail()) {
$this->account
->set('init', $derived_mail);
}
if (!$this->account
->isBlocked()) {
$this->account
->set('status', 1);
}
}
private function setLdapBaseFields(array $ldapUser, $direction, array $prov_events) {
$mappingHelper = new SyncMappingHelper();
if ($mappingHelper
->isSynced('[property.name]', $prov_events, $direction)) {
$this->account
->set('name', $this->server
->userUsernameFromLdapEntry($ldapUser['attr']));
}
if ($mappingHelper
->isSynced('[property.mail]', $prov_events, $direction)) {
$derived_mail = $this->server
->userEmailFromLdapEntry($ldapUser['attr']);
if ($derived_mail) {
$this->account
->set('mail', $derived_mail);
}
}
if ($mappingHelper
->isSynced('[property.picture]', $prov_events, $direction)) {
$picture = $this
->userPictureFromLdapEntry($ldapUser['attr']);
if ($picture) {
$this->account
->set('user_picture', $picture);
}
}
if ($mappingHelper
->isSynced('[field.ldap_user_puid]', $prov_events, $direction)) {
$ldap_user_puid = $this->server
->userPuidFromLdapEntry($ldapUser['attr']);
if ($ldap_user_puid) {
$this->account
->set('ldap_user_puid', $ldap_user_puid);
}
}
if ($mappingHelper
->isSynced('[field.ldap_user_puid_property]', $prov_events, $direction)) {
$this->account
->set('ldap_user_puid_property', $this->server
->get('unique_persistent_attr'));
}
if ($mappingHelper
->isSynced('[field.ldap_user_puid_sid]', $prov_events, $direction)) {
$this->account
->set('ldap_user_puid_sid', $this->server
->id());
}
if ($mappingHelper
->isSynced('[field.ldap_user_current_dn]', $prov_events, $direction)) {
$this->account
->set('ldap_user_current_dn', $ldapUser['dn']);
}
}
private function setUserDefinedMappings(array $ldapUser, $direction, array $prov_events) {
$mappingHelper = new SyncMappingHelper();
$mappings = $mappingHelper
->getSyncMappings($direction, $prov_events);
foreach ($mappings as $key => $fieldDetails) {
if ($mappingHelper
->isSynced($key, $prov_events, $direction)) {
if ($fieldDetails['convert'] && strpos($fieldDetails['ldap_attr'], ';') === FALSE) {
$fieldDetails['ldap_attr'] = str_replace(']', ';binary]', $fieldDetails['ldap_attr']);
}
$value = $this->tokenProcessor
->tokenReplace($ldapUser['attr'], $fieldDetails['ldap_attr'], 'ldap_entry');
list($value_type, $value_name, $value_instance) = $this
->parseUserAttributeNames($key);
if ($value_type == 'field' || $value_type == 'property') {
$this->account
->set($value_name, $value);
}
}
}
}
private function parseUserAttributeNames($user_attr_key) {
$user_attr_key = trim($user_attr_key, TokenProcessor::PREFIX . TokenProcessor::SUFFIX);
$parts = explode('.', $user_attr_key);
$attr_type = $parts[0];
$attr_name = isset($parts[1]) ? $parts[1] : FALSE;
$attr_ordinal = FALSE;
if ($attr_name) {
$attr_name_parts = explode(':', $attr_name);
if (isset($attr_name_parts[1])) {
$attr_name = $attr_name_parts[0];
$attr_ordinal = $attr_name_parts[1];
}
}
return [
$attr_type,
$attr_name,
$attr_ordinal,
];
}
}