You are here

class LoginValidatorLoginForm in Lightweight Directory Access Protocol (LDAP) 8.4

Handles the actual testing of credentials and authentication of users.

Hierarchy

Expanded class hierarchy of LoginValidatorLoginForm

3 files declare their use of LoginValidatorLoginForm
LdapProtectedUserFieldConstraintValidator.php in ldap_user/src/Plugin/Validation/Constraint/LdapProtectedUserFieldConstraintValidator.php
LoginTest.php in ldap_authentication/tests/src/Kernel/LoginTest.php
ProtectedUserFieldConstraintValidatorTest.php in ldap_user/tests/src/Unit/ProtectedUserFieldConstraintValidatorTest.php
1 string reference to 'LoginValidatorLoginForm'
ldap_authentication.services.yml in ldap_authentication/ldap_authentication.services.yml
ldap_authentication/ldap_authentication.services.yml
1 service uses LoginValidatorLoginForm
ldap_authentication.login_validator in ldap_authentication/ldap_authentication.services.yml
\Drupal\ldap_authentication\Controller\LoginValidatorLoginForm

File

ldap_authentication/src/Controller/LoginValidatorLoginForm.php, line 13

Namespace

Drupal\ldap_authentication\Controller
View source
class LoginValidatorLoginForm extends LoginValidatorBase {

  /**
   * Starts login process.
   *
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   *
   * @return \Drupal\Core\Form\FormStateInterface
   *   The form state.
   */
  public function validateLogin(FormStateInterface $form_state) : FormStateInterface {
    $this->authName = trim($form_state
      ->getValue('name') ?? '');
    $this->formState = $form_state;
    $this->detailLog
      ->log('%auth_name : Beginning authentication', [
      '%auth_name' => $this->authName,
    ], 'ldap_authentication');
    $this
      ->processLogin();
    return $this->formState;
  }

  /**
   * {@inheritdoc}
   */
  public function processLogin() : void {
    if ($this
      ->userAlreadyAuthenticated()) {
      return;
    }
    if (!$this
      ->validateCommonLoginConstraints()) {
      return;
    }
    $credentialsAuthenticationResult = $this
      ->testCredentials();
    if ($credentialsAuthenticationResult === self::AUTHENTICATION_FAILURE_FIND && $this->config
      ->get('authenticationMode') === 'exclusive') {
      $this->formState
        ->setErrorByName('non_ldap_login_not_allowed', $this
        ->t('User disallowed'));
    }
    if ($credentialsAuthenticationResult !== self::AUTHENTICATION_SUCCESS) {
      return;
    }
    if (!$this
      ->deriveDrupalUserName()) {
      return;
    }

    // We now have an LDAP account, matching username and password and the
    // reference Drupal user.
    if (!$this->drupalUser && $this->serverDrupalUser) {
      $this
        ->updateAuthNameFromPuid();
    }

    // Existing Drupal but not mapped to LDAP.
    if ($this->drupalUser && !$this->drupalUserAuthMapped) {
      if (!$this
        ->matchExistingUserWithLdap()) {
        return;
      }
    }

    // Existing Drupal account with incorrect email. Fix email if appropriate.
    $this
      ->fixOutdatedEmailAddress();

    // No existing Drupal account. Consider provisioning Drupal account.
    if (!$this->drupalUser) {
      if (!$this
        ->provisionDrupalUser()) {
        return;
      }
    }

    // All passed, log the user in by handing over the UID.
    if ($this->drupalUser) {
      $this->formState
        ->set('uid', $this->drupalUser
        ->id());
    }
  }

  /**
   * {@inheritdoc}
   */
  public function testCredentials() : int {
    $authenticationResult = self::AUTHENTICATION_FAILURE_UNKNOWN;
    foreach ($this->authenticationServers
      ->getAvailableAuthenticationServers() as $server) {
      $this->serverDrupalUser = $this->entityTypeManager
        ->getStorage('ldap_server')
        ->load($server);
      $this->ldapBridge
        ->setServer($this->serverDrupalUser);
      $this->detailLog
        ->log('%username: Trying server %id with %bind_method', [
        '%username' => $this->authName,
        '%id' => $this->serverDrupalUser
          ->id(),
        '%bind_method' => $this->serverDrupalUser
          ->getFormattedBind(),
      ], 'ldap_authentication');

      // @todo Verify new usage of CredentialsStorage here.
      $bindResult = $this
        ->bindToServer();
      if ($bindResult !== self::AUTHENTICATION_SUCCESS) {
        $authenticationResult = $bindResult;

        // If bind fails, onto next server.
        continue;
      }

      // Check if user exists in LDAP.
      $this->ldapUserManager
        ->setServer($this->serverDrupalUser);
      $entry = $this->ldapUserManager
        ->queryAllBaseDnLdapForUsername($this->authName);
      if ($entry) {
        $this->ldapUserManager
          ->sanitizeUserDataResponse($entry, $this->authName);
      }
      $this->ldapEntry = $entry;
      if (!$this->ldapEntry) {
        $authenticationResult = self::AUTHENTICATION_FAILURE_FIND;

        // Next server, please.
        continue;
      }
      if (!$this
        ->checkAllowedExcluded($this->authName, $this->ldapEntry)) {
        $authenticationResult = self::AUTHENTICATION_FAILURE_DISALLOWED;

        // Regardless of how many servers, disallowed user fails.
        break;
      }
      if (!$this
        ->testUserPassword()) {
        $authenticationResult = self::AUTHENTICATION_FAILURE_CREDENTIALS;

        // Next server, please.
        continue;
      }
      $authenticationResult = self::AUTHENTICATION_SUCCESS;
      break;
    }
    $this->detailLog
      ->log('%username: Authentication result is "%err_text"', [
      '%username' => $this->authName,
      '%err_text' => $this
        ->authenticationHelpText($authenticationResult) . ' ' . $this
        ->additionalDebuggingResponse($authenticationResult),
    ], 'ldap_authentication');
    if ($authenticationResult !== self::AUTHENTICATION_SUCCESS) {
      $this
        ->failureResponse($authenticationResult);
    }
    return $authenticationResult;
  }

  /**
   * Validate already authenticated user.
   *
   * @return bool
   *   User already authenticated.
   */
  protected function userAlreadyAuthenticated() : bool {
    if (!empty($this->formState
      ->get('uid'))) {
      if ($this->config
        ->get('authenticationMode') === 'mixed') {
        $this->detailLog
          ->log('%username: Previously authenticated in mixed mode, pass on validation.', [
          '%username' => $this->authName,
        ], 'ldap_authentication');
        return TRUE;
      }
    }
    return FALSE;
  }

  /**
   * Check credentials on an signed-in user from the account.
   *
   * This helper function is intended for the user edit form to allow
   * the constraint validator to check against LDAP for the current password.
   *
   * @param \Drupal\user\UserInterface $account
   *   User account.
   *
   * @return int
   *   Authentication status.
   */
  public function validateCredentialsLoggedIn(UserInterface $account) : int {
    $this->drupalUser = $account;
    $data = $this->externalAuth
      ->getAuthData($account
      ->id(), 'ldap_user');
    if (!empty($data) && $data['authname']) {
      $this->authName = $data['authname'];
      $this->drupalUserAuthMapped = TRUE;
    }
    $this->detailLog
      ->log('%auth_name : Testing existing credentials authentication', [
      '%auth_name' => $this->authName,
    ], 'ldap_authentication');
    return $this
      ->testCredentials();
  }

}

Members

Namesort descending Modifiers Type Description Overrides
LdapUserAttributesInterface::ACCOUNT_CREATION_LDAP_BEHAVIOUR public constant Event config.
LdapUserAttributesInterface::ACCOUNT_CREATION_USER_SETTINGS_FOR_LDAP public constant Config.
LdapUserAttributesInterface::EVENT_CREATE_DRUPAL_USER public constant Event config.
LdapUserAttributesInterface::EVENT_CREATE_LDAP_ENTRY public constant Event config.
LdapUserAttributesInterface::EVENT_LDAP_ASSOCIATE_DRUPAL_USER public constant Event config.
LdapUserAttributesInterface::EVENT_SYNC_TO_DRUPAL_USER public constant Event config.
LdapUserAttributesInterface::EVENT_SYNC_TO_LDAP_ENTRY public constant Event config.
LdapUserAttributesInterface::MANUAL_ACCOUNT_CONFLICT_LDAP_ASSOCIATE public constant Config.
LdapUserAttributesInterface::MANUAL_ACCOUNT_CONFLICT_NO_LDAP_ASSOCIATE public constant Config.
LdapUserAttributesInterface::MANUAL_ACCOUNT_CONFLICT_REJECT public constant Config.
LdapUserAttributesInterface::MANUAL_ACCOUNT_CONFLICT_SHOW_OPTION_ON_FORM public constant Config.
LdapUserAttributesInterface::PROVISION_DRUPAL_USER_ON_USER_AUTHENTICATION public constant Provision config.
LdapUserAttributesInterface::PROVISION_DRUPAL_USER_ON_USER_ON_MANUAL_CREATION public constant Provision config.
LdapUserAttributesInterface::PROVISION_DRUPAL_USER_ON_USER_UPDATE_CREATE public constant Provision config.
LdapUserAttributesInterface::PROVISION_LDAP_ENTRY_ON_USER_ON_USER_AUTHENTICATION public constant Provision config.
LdapUserAttributesInterface::PROVISION_LDAP_ENTRY_ON_USER_ON_USER_DELETE public constant Provision config.
LdapUserAttributesInterface::PROVISION_LDAP_ENTRY_ON_USER_ON_USER_UPDATE_CREATE public constant Provision config.
LdapUserAttributesInterface::PROVISION_TO_ALL constant Provision config.
LdapUserAttributesInterface::PROVISION_TO_DRUPAL public constant Provision config.
LdapUserAttributesInterface::PROVISION_TO_LDAP public constant Provision config.
LdapUserAttributesInterface::PROVISION_TO_NONE public constant Provision config.
LdapUserAttributesInterface::USER_CONFLICT_ATTEMPT_RESOLVE public constant Config.
LdapUserAttributesInterface::USER_CONFLICT_LOG public constant Config.
LoginValidatorBase::$authenticationServers protected property Authentication servers.
LoginValidatorBase::$authName protected property Authname.
LoginValidatorBase::$config protected property Config.
LoginValidatorBase::$configFactory protected property Config factory.
LoginValidatorBase::$detailLog protected property Detail log.
LoginValidatorBase::$drupalUser protected property The Drupal user.
LoginValidatorBase::$drupalUserAuthMapped protected property Whether the external authmap is linked with the user.
LoginValidatorBase::$drupalUserName protected property Drupal User name.
LoginValidatorBase::$drupalUserProcessor protected property Drupal User Processor.
LoginValidatorBase::$emailTemplateTokens protected property Email template tokens.
LoginValidatorBase::$emailTemplateUsed protected property Email template used.
LoginValidatorBase::$entityTypeManager protected property Entity type Manager.
LoginValidatorBase::$externalAuth protected property External authentication mapper.
LoginValidatorBase::$formState protected property Form State.
LoginValidatorBase::$ldapBridge protected property LDAP bridge.
LoginValidatorBase::$ldapEntry protected property LDAP Entry.
LoginValidatorBase::$ldapUserManager protected property LDAP User Manager.
LoginValidatorBase::$logger protected property Logger.
LoginValidatorBase::$messenger protected property Messenger.
LoginValidatorBase::$moduleHandler protected property Module handler.
LoginValidatorBase::$serverDrupalUser protected property The Server for the Drupal user.
LoginValidatorBase::additionalDebuggingResponse protected function Provides formatting for authentication failures.
LoginValidatorBase::authenticationHelpText protected function Get human readable authentication error string.
LoginValidatorBase::AUTHENTICATION_FAILURE_BIND public constant Failure value.
LoginValidatorBase::AUTHENTICATION_FAILURE_CREDENTIALS public constant Failure value.
LoginValidatorBase::AUTHENTICATION_FAILURE_DISALLOWED public constant Failure value.
LoginValidatorBase::AUTHENTICATION_FAILURE_FIND public constant Failure value.
LoginValidatorBase::AUTHENTICATION_FAILURE_UNKNOWN public constant Failure value.
LoginValidatorBase::AUTHENTICATION_SUCCESS public constant Success value.
LoginValidatorBase::bindToServer protected function Bind to server.
LoginValidatorBase::bindToServerAsUser protected function Bind to server. 1
LoginValidatorBase::checkAllowedExcluded public function Check if exclusion criteria match. Overrides LoginValidatorInterface::checkAllowedExcluded
LoginValidatorBase::deriveDrupalUserName protected function Derives the Drupal user name from server configuration.
LoginValidatorBase::failureResponse protected function Failure response.
LoginValidatorBase::fixOutdatedEmailAddress protected function Update an outdated email address.
LoginValidatorBase::getDrupalUser public function Returns the derived user account. Overrides LoginValidatorInterface::getDrupalUser
LoginValidatorBase::initializeDrupalUserFromAuthName protected function Determine if the corresponding Drupal account exists and is mapped.
LoginValidatorBase::matchExistingUserWithLdap protected function Match existing user with LDAP.
LoginValidatorBase::prepareEmailTemplateToken protected function Prepare the email template token.
LoginValidatorBase::provisionDrupalUser protected function Provision the Drupal user.
LoginValidatorBase::replaceUserMailWithTemplate protected function Replace user email address with template.
LoginValidatorBase::testUserPassword protected function Tests the user's password.
LoginValidatorBase::updateAuthNameFromPuid protected function Update the authName if it's no longer valid.
LoginValidatorBase::validateCommonLoginConstraints protected function Validate common login constraints for user.
LoginValidatorBase::verifyAccountCreation protected function Verifies whether the user is available or can be created.
LoginValidatorBase::verifyUserAllowed protected function Verifies whether the user is available or can be created.
LoginValidatorBase::__construct public function Constructor.
LoginValidatorLoginForm::processLogin public function Perform the actual logging in. Overrides LoginValidatorInterface::processLogin
LoginValidatorLoginForm::testCredentials public function Credentials are tested. Overrides LoginValidatorInterface::testCredentials
LoginValidatorLoginForm::userAlreadyAuthenticated protected function Validate already authenticated user.
LoginValidatorLoginForm::validateCredentialsLoggedIn public function Check credentials on an signed-in user from the account.
LoginValidatorLoginForm::validateLogin public function Starts login process.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.