You are here

public function CasUserManager::login in CAS 2.x

Same name and namespace in other branches
  1. 8 src/Service/CasUserManager.php \Drupal\cas\Service\CasUserManager::login()

Attempts to log the user in to the Drupal site.

Parameters

\Drupal\cas\CasPropertyBag $property_bag: CasPropertyBag containing username and attributes from CAS.

string $ticket: The service ticket.

Throws

\Drupal\cas\Exception\CasLoginException Thrown if there was a problem logging in the user.

File

src/Service/CasUserManager.php, line 174

Class

CasUserManager
Provides the 'cas.user_manager' service default implementation.

Namespace

Drupal\cas\Service

Code

public function login(CasPropertyBag $property_bag, $ticket) {
  $account = $this->externalAuth
    ->load($property_bag
    ->getUsername(), $this->provider);
  if ($account === FALSE) {

    // Check if we should create the user or not.
    $config = $this->settings
      ->get('cas.settings');
    if ($config
      ->get('user_accounts.auto_register') === TRUE) {
      $this->casHelper
        ->log(LogLevel::DEBUG, 'Existing account not found for user, attempting to auto-register.');

      // Dispatch an event that allows modules to deny automatic registration
      // for this user account or to set properties for the user that will
      // be created.
      $cas_pre_register_event = new CasPreRegisterEvent($property_bag);
      $cas_pre_register_event
        ->setPropertyValue('mail', $this
        ->getEmailForNewAccount($property_bag));
      $this->casHelper
        ->log(LogLevel::DEBUG, 'Dispatching EVENT_PRE_REGISTER.');
      $this->eventDispatcher
        ->dispatch(CasHelper::EVENT_PRE_REGISTER, $cas_pre_register_event);
      if ($cas_pre_register_event
        ->getAllowAutomaticRegistration()) {
        $account = $this
          ->register($property_bag
          ->getUsername(), $cas_pre_register_event
          ->getDrupalUsername(), $cas_pre_register_event
          ->getPropertyValues());
      }
      else {
        $reason = $cas_pre_register_event
          ->getCancelRegistrationReason();
        throw (new CasLoginException("Cannot register user, an event listener denied access.", CasLoginException::SUBSCRIBER_DENIED_REG))
          ->setSubscriberCancelReason($reason);
      }
    }
    else {
      throw new CasLoginException("Cannot login, local Drupal user account does not exist.", CasLoginException::NO_LOCAL_ACCOUNT);
    }
  }

  // Check if the retrieved user is blocked before moving forward.
  if (!$account
    ->isActive()) {
    throw new CasLoginException(sprintf('The username %s has not been activated or is blocked.', $account
      ->getAccountName()), CasLoginException::ACCOUNT_BLOCKED);
  }

  // Dispatch an event that allows modules to prevent this user from logging
  // in and/or alter the user entity before we save it.
  $pre_login_event = new CasPreLoginEvent($account, $property_bag);
  $this->casHelper
    ->log(LogLevel::DEBUG, 'Dispatching EVENT_PRE_LOGIN.');
  $this->eventDispatcher
    ->dispatch(CasHelper::EVENT_PRE_LOGIN, $pre_login_event);

  // Save user entity since event listeners may have altered it.
  // @todo Don't take it for granted. Find if the account was really altered.
  // @todo Should this be swapped with the following if(...) block? Why
  //   altering the account if the login has been denied?
  $account
    ->save();
  if (!$pre_login_event
    ->getAllowLogin()) {
    $reason = $pre_login_event
      ->getCancelLoginReason();
    throw (new CasLoginException('Cannot login, an event listener denied access.', CasLoginException::SUBSCRIBER_DENIED_LOGIN))
      ->setSubscriberCancelReason($reason);
  }
  $this->externalAuth
    ->userLoginFinalize($account, $property_bag
    ->getUsername(), $this->provider);
  $this
    ->storeLoginSessionData($this->session
    ->getId(), $ticket);
  $this->session
    ->set('is_cas_user', TRUE);
  $this->session
    ->set('cas_username', $property_bag
    ->getOriginalUsername());
  $postLoginEvent = new CasPostLoginEvent($account, $property_bag);
  $this->casHelper
    ->log(LogLevel::DEBUG, 'Dispatching EVENT_POST_LOGIN.');
  $this->eventDispatcher
    ->dispatch(CasHelper::EVENT_POST_LOGIN, $postLoginEvent);
  if ($this->settings
    ->get('proxy.initialize') && $property_bag
    ->getPgt()) {
    $this->casHelper
      ->log(LogLevel::DEBUG, "Storing PGT information for this session.");
    $this->casProxyHelper
      ->storePgtSession($property_bag
      ->getPgt());
  }
}