Commit 27930c32 authored by Getulio Valentin Sánchez's avatar Getulio Valentin Sánchez
Browse files

Issue #3033749 by miteshmap: Dispatch events for handling authentication errors in provider

parent c53c6001
Loading
Loading
Loading
Loading
+1 −1
Changes for src/Controller/OAuth2ControllerBase.php: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@ public function redirectToProvider() {
        $state = $this->providerManager->getState();
        $this->dataHandler->set('oauth2state', $state);

        $this->userAuthenticator->dispatchBeforeRedirect($destination);
        return new TrustedRedirectResponse($auth_url);
      }
      catch (PluginException $exception) {
@@ -251,7 +252,6 @@ public function processCallback() {
      // Gets user's info from provider.
      if (!$profile = $this->providerManager->getUserInfo()) {
        $this->messenger->addError($this->t('Login failed, could not load user profile. Contact site administrator.'));

        return NULL;
      }

+82 −0
Changes for src/Event/BeforeRedirectEvent.php: 82 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

namespace Drupal\social_auth\Event;

use Drupal\social_auth\SocialAuthDataHandler;
use Symfony\Component\EventDispatcher\Event;

/**
 * Class BeforeRedirectEvent.
 *
 * @see \Drupal\social_auth\Event\SocialAuthEvents
 */
class BeforeRedirectEvent extends Event {

  /**
   * The Social Auth data handler.
   *
   * @var \Drupal\social_auth\SocialAuthDataHandler
   */
  protected $dataHandler;

  /**
   * The plugin id dispatching this event.
   *
   * @var string
   */
  protected $pluginId;

  /**
   * The destination where use will redirect after successful authentication.
   *
   * @var string
   */
  protected $destination;

  /**
   * BeforeRedirectEvent constructor.
   *
   * @param \Drupal\social_auth\SocialAuthDataHandler $data_handler
   *   The Social Auth data handler.
   * @param string $plugin_id
   *   The plugin Id dispatching this event.
   * @param string $destination
   *   The destination where user will redirect after successful authentication.
   */
  public function __construct(SocialAuthDataHandler $data_handler, $plugin_id, $destination = NULL) {
    $this->dataHandler = $data_handler;
    $this->pluginId = $plugin_id;
    $this->destination = $destination;
  }

  /**
   * Gets the Social Auth data handler object.
   *
   * @return \Drupal\social_auth\SocialAuthDataHandler
   *   The Social Auth data handler.
   */
  public function getDataHandler() {
    return $this->dataHandler;
  }

  /**
   * Gets the plugin id dispatching this event.
   *
   * @return string
   *   The plugin id.
   */
  public function getPluginId() {
    return $this->pluginId;
  }

  /**
   * Gets the destination.
   *
   * @return string
   *   The destination path.
   */
  public function getDestination() {
    return $this->destination;
  }

}
+120 −0
Changes for src/Event/FailedAuthenticationEvent.php: 120 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

namespace Drupal\social_auth\Event;

use Drupal\social_auth\SocialAuthDataHandler;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpFoundation\RedirectResponse;

/**
 * Class FailedAuthenticationEvent.
 *
 * @see \Drupal\social_auth\Event\SocialAuthEvents
 */
class FailedAuthenticationEvent extends Event {

  /**
   * The Social Auth data handler.
   *
   * @var \Drupal\social_auth\SocialAuthDataHandler
   */
  protected $dataHandler;

  /**
   * The plugin id dispatching this event.
   *
   * @var string
   */
  protected $pluginId;

  /**
   * The error string.
   *
   * @var string
   */
  protected $error;

  /**
   * RedirectResponse object.
   *
   * @var \Symfony\Component\HttpFoundation\RedirectResponse
   */
  protected $response;

  /**
   * FailedAuthenticationEvent constructor.
   *
   * @param \Drupal\social_auth\SocialAuthDataHandler $data_handler
   *   The Social Auth data handler.
   * @param string $plugin_id
   *   The plugin Id dispatching this event.
   * @param string $error
   *   The error string.
   */
  public function __construct(SocialAuthDataHandler $data_handler, $plugin_id, $error = NULL) {
    $this->dataHandler = $data_handler;
    $this->pluginId = $plugin_id;
    $this->error = $error;
  }

  /**
   * Gets the Social Auth data handler object.
   *
   * @return \Drupal\social_auth\SocialAuthDataHandler
   *   The Social Auth data handler.
   */
  public function getDataHandler() {
    return $this->dataHandler;
  }

  /**
   * Gets the plugin id dispatching this event.
   *
   * @return string
   *   The plugin id.
   */
  public function getPluginId() {
    return $this->pluginId;
  }

  /**
   * Gets the error string from provider.
   *
   * @return string
   *   The error string.
   */
  public function getError() {
    return $this->error;
  }

  /**
   * Returns the current redirect response object.
   *
   * @return \Symfony\Component\HttpFoundation\Response
   *   The response from the provider.
   */
  public function getResponse() {
    return $this->response;
  }

  /**
   * Sets a new redirect response object.
   *
   * @param \Symfony\Component\HttpFoundation\RedirectResponse $response
   *   The response from the provider.
   */
  public function setResponse(RedirectResponse $response) {
    $this->response = $response;
  }

  /**
   * Returns whether a redirect response was set.
   *
   * @return bool
   *   Whether a response was set.
   */
  public function hasResponse() {
    return $this->response !== NULL;
  }

}
+26 −9
Changes for src/Event/SocialAuthEvents.php: 26 added lines, 9 removed lines.
Original line number Diff line number Diff line
@@ -6,10 +6,9 @@
 * Defines Social Auth Events constants.
 */
final class SocialAuthEvents {

  /**
   * Name of the event fired when social auth is gathering user fields.
   *
   * Fired before a new user is created when gathering fields.
   * Dispatched event when social auth is gathering user fields.
   *
   * @Event
   *
@@ -20,9 +19,7 @@ final class SocialAuthEvents {
  const USER_FIELDS = 'social_auth.user.fields';

  /**
   * Name of the event fired when a new user is created via social auth.
   *
   * Fired after a new user account has been created.
   * Dispatched event when a new user is created via social auth.
   *
   * @Event
   *
@@ -33,9 +30,7 @@ final class SocialAuthEvents {
  const USER_CREATED = 'social_auth.user.created';

  /**
   * Name of the event fired when a new user login using social auth.
   *
   * Fired after a user has logged in.
   * Dispatched event when a new user login using social auth.
   *
   * @Event
   *
@@ -45,4 +40,26 @@ final class SocialAuthEvents {
   */
  const USER_LOGIN = 'social_auth.user.login';

  /**
   * Dispatched event before redirecting to provider.
   *
   * @Event
   *
   * @see \Drupal\social_auth\Event\ProviderRedirectEvent
   *
   * @var string
   */
  const BEFORE_REDIRECT = 'social_auth.before_redirect';

  /**
   * Dispatched event after authentication fails in provider.
   *
   * @Event
   *
   * @see \Drupal\social_auth\Event\ProviderRedirectEvent
   *
   * @var string
   */
  const FAILED_AUTH = 'social_auth.failed_authentication';

}
+33 −0
Changes for src/User/UserAuthenticator.php: 33 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\social_api\User\UserAuthenticator as SocialApiUserAuthenticator;
use Drupal\social_auth\Event\BeforeRedirectEvent;
use Drupal\social_auth\Event\FailedAuthenticationEvent;
use Drupal\social_auth\Event\SocialAuthEvents;
use Drupal\social_auth\Event\SocialAuthUserEvent;
use Drupal\social_auth\SettingsTrait;
@@ -405,4 +407,35 @@ protected function userLoginFinalize(UserInterface $account) {
    user_login_finalize($account);
  }

  /**
   * Dispatch an event when authentication in provider fails.
   *
   * @param string|null $error
   *   The error string/code from provider.
   *
   * @return \Symfony\Component\HttpFoundation\RedirectResponse
   *   Return redirect response.
   */
  public function dispatchAuthenticationError($error = NULL) {
    $event = new FailedAuthenticationEvent($this->dataHandler, $this->getPluginId(), $error ?? NULL);
    $this->eventDispatcher->dispatch(SocialAuthEvents::FAILED_AUTH, $event);

    if ($event->hasResponse()) {
      return $event->getResponse();
    }

    return NULL;
  }

  /**
   * Dispatch an event before user is redirected to the provider.
   *
   * @param string|null $destination
   *   The destination url.
   */
  public function dispatchBeforeRedirect($destination = NULL) {
    $event = new BeforeRedirectEvent($this->dataHandler, $this->getPluginId(), $destination);
    $this->eventDispatcher->dispatch(SocialAuthEvents::BEFORE_REDIRECT, $event);
  }

}