You are here

protected function LoginValidatorBase::provisionDrupalUser in Lightweight Directory Access Protocol (LDAP) 8.4

Provision the Drupal user.

Return value

bool Provisioning successful.

2 calls to LoginValidatorBase::provisionDrupalUser()
LoginValidatorLoginForm::processLogin in ldap_authentication/src/Controller/LoginValidatorLoginForm.php
Perform the actual logging in.
LoginValidatorSso::processLogin in ldap_authentication/src/Controller/LoginValidatorSso.php
Perform the actual logging in.

File

ldap_authentication/src/Controller/LoginValidatorBase.php, line 792

Class

LoginValidatorBase
Handles the actual testing of credentials and authentication of users.

Namespace

Drupal\ldap_authentication\Controller

Code

protected function provisionDrupalUser() : bool {
  $users = $this->entityTypeManager
    ->getStorage('user')
    ->loadByProperties([
    'mail' => $this->serverDrupalUser
      ->deriveEmailFromLdapResponse($this->ldapEntry),
  ]);
  $accountDuplicateMail = $users ? reset($users) : FALSE;

  // Do not provision Drupal account if another account has same email.
  if ($accountDuplicateMail) {
    $emailAvailable = FALSE;
    if (!$this->emailTemplateUsed && $this->config
      ->get('emailTemplateUsageResolveConflict')) {
      $this->detailLog
        ->log('Conflict detected, using template generated email for %username', [
        '%duplicate_name' => $accountDuplicateMail
          ->getAccountName(),
      ], 'ldap_authentication');
      $this
        ->replaceUserMailWithTemplate();
      $this->emailTemplateUsed = TRUE;

      // Recheck with the template email to make sure it doesn't also exist.
      $users = $this->entityTypeManager
        ->getStorage('user')
        ->loadByProperties([
        'mail' => $this->serverDrupalUser
          ->deriveEmailFromLdapResponse($this->ldapEntry),
      ]);
      $accountDuplicateMail = $users ? reset($users) : FALSE;
      if ($accountDuplicateMail) {
        $emailAvailable = FALSE;
      }
      else {
        $emailAvailable = TRUE;
      }
    }
    if (!$emailAvailable) {

      /*
       * Username does not exist but email does. Since
       * user_external_login_register does not deal with mail attribute and
       * the email conflict error needs to be caught beforehand, need to throw
       * error here.
       */
      $this->logger
        ->error('LDAP user with DN %dn has email address (%mail) conflict with a Drupal user %duplicate_name', [
        '%dn' => $this->ldapEntry
          ->getDn(),
        '%duplicate_name' => $accountDuplicateMail
          ->getAccountName(),
      ]);
      $this->messenger
        ->addError($this
        ->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.'));
      return FALSE;
    }
  }

  // Do not provision Drupal account if provisioning disabled.
  $triggers = $this->configFactory
    ->get('ldap_user.settings')
    ->get('drupalAcctProvisionTriggers');
  if (!in_array(self::PROVISION_DRUPAL_USER_ON_USER_AUTHENTICATION, $triggers, TRUE)) {
    $this->logger
      ->error('Drupal account for authname=%authname does not exist and provisioning of Drupal accounts on authentication is not enabled', [
      '%authname' => $this->authName,
    ]);
    return FALSE;
  }

  /*
   * New ldap_authentication provisioned account could let
   * user_external_login_register create the account and set authmaps, but
   * would need to add mail and any other user->data data in hook_user_presave
   * which would mean requerying LDAP or having a global variable. At this
   * point the account does not exist, so there is no reason not to create
   * it here.
   */
  if ($this->configFactory
    ->get('ldap_user.settings')
    ->get('acctCreation') === self::ACCOUNT_CREATION_USER_SETTINGS_FOR_LDAP && $this->configFactory
    ->get('user.settings')
    ->get('register') === UserInterface::REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL) {

    // If admin approval required, set status to 0.
    $user_values = [
      'name' => $this->drupalUserName,
      'status' => 0,
    ];
  }
  else {
    $user_values = [
      'name' => $this->drupalUserName,
      'status' => 1,
    ];
  }
  if ($this->emailTemplateUsed) {
    $user_values['mail'] = $this->serverDrupalUser
      ->deriveEmailFromLdapResponse($this->ldapEntry);
  }
  $result = $this->drupalUserProcessor
    ->createDrupalUserFromLdapEntry($user_values);
  if (!$result) {
    $this->logger
      ->error('Failed to find or create %drupal_accountname on logon.', [
      '%drupal_accountname' => $this->drupalUserName,
    ]);
    if ($this->formState) {
      $this->formState
        ->setErrorByName('name', $this
        ->t('Server Error: Failed to create Drupal user account for %drupal_accountname', [
        '%drupal_accountname' => $this->drupalUserName,
      ]));
    }
    return FALSE;
  }
  $this->drupalUser = $this->drupalUserProcessor
    ->getUserAccount();
  return TRUE;
}