You are here

class ClientTestForm in OAuth2 Client 8.2

Defines the form for testing OAuth2 Client integrations.

Hierarchy

Expanded class hierarchy of ClientTestForm

File

src/Form/ClientTestForm.php, line 19

Namespace

Drupal\oauth2_client\Form
View source
class ClientTestForm extends FormBase {

  /**
   * The current request.
   *
   * @var \Symfony\Component\HttpFoundation\Request
   */
  protected $currentRequest;

  /**
   * The Drupal tempstore.
   *
   * @var \Drupal\Core\TempStore\PrivateTempStore
   */
  protected $tempstore;

  /**
   * The URL generator service.
   *
   * @var \Drupal\Core\Routing\UrlGeneratorInterface
   */
  protected $urlGenerator;

  /**
   * The OAuth2 Client plugin manager.
   *
   * @var \Drupal\oauth2_client\PluginManager\Oauth2ClientPluginManagerInterface
   */
  protected $oauth2ClientPluginManager;

  /**
   * The OAuth2 Client service.
   *
   * @var \Drupal\oauth2_client\Service\Oauth2ClientServiceInterface
   */
  protected $oauth2ClientService;

  /**
   * Constructs a ClientTestForm object.
   *
   * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
   *   The request stack.
   * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $tempstoreFactory
   *   The Drupal private tempstore factory.
   * @param \Drupal\Core\Routing\UrlGeneratorInterface $urlGenerator
   *   The URL generator service.
   * @param \Drupal\oauth2_client\PluginManager\Oauth2ClientPluginManagerInterface $oauth2ClientPluginManager
   *   The OAuth2 Client plugin manager.
   * @param \Drupal\oauth2_client\Service\Oauth2ClientServiceInterface $oauth2ClientService
   *   The OAuth2 client service.
   * @param \Drupal\Core\Routing\RouteMatchInterface $currentRouteMatch
   *   Current route match.
   */
  public function __construct(RequestStack $requestStack, PrivateTempStoreFactory $tempstoreFactory, UrlGeneratorInterface $urlGenerator, Oauth2ClientPluginManagerInterface $oauth2ClientPluginManager, Oauth2ClientServiceInterface $oauth2ClientService, RouteMatchInterface $currentRouteMatch) {
    $this->currentRequest = $requestStack
      ->getCurrentRequest();
    $this->tempstore = $tempstoreFactory
      ->get('oauth2_client');
    $this->urlGenerator = $urlGenerator;
    $this->oauth2ClientPluginManager = $oauth2ClientPluginManager;
    $this->oauth2ClientService = $oauth2ClientService;
    $this->routeMatch = $currentRouteMatch;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('request_stack'), $container
      ->get('tempstore.private'), $container
      ->get('url_generator'), $container
      ->get('oauth2_client.plugin_manager'), $container
      ->get('oauth2_client.service'), $container
      ->get('current_route_match'));
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'oauth2_client_client_test_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['#prefix'] = '<div id="oauth2_client_client_test_form_wrapper">';
    $form['#suffix'] = '</div>';

    // Get a list of the OAuth2 Client plugin definitions.
    $definitions = $this->oauth2ClientPluginManager
      ->getDefinitions();
    if (!empty($definitions)) {

      /*
       * This form tests the OAuth2 Clients by redirecting to the OAuth2 server,
       * which after authentication (on that server) redirects the user back to
       * a URL on this server. For this testing form, the redirect URL is given
       * as the URL of the page on which the form exists (using the special
       * <current> route). The problem is that when the user is redirected back,
       * we need to re-request the access token, using the state and code values
       * from the URL. This all works fine, however leaving the 'code' and
       * 'state' variables in the URL causes issues on further form submissions,
       * so to get around it, the user is redirected back to this same form
       * without the code and state variables in it.
       */

      // Only do something if the state parameter exists in the URL.
      if ($state = $this->currentRequest->query
        ->get('state')) {

        // Loop through the definitions.
        foreach ($definitions as $definition) {

          // Check if there is a value in the tempstore (the Drupal SESSION) for
          // 'state' for the current OAuth2 Client.
          if ($stored_state = $this->tempstore
            ->get('oauth2_client_state-' . $definition['id'])) {

            // Re-request the access token. That script will complete the
            // retrieval of the authorization token from the OAuth2 server.
            $this->oauth2ClientService
              ->getAccessToken($definition['id']);

            // Redirect back to this page, with the 'code' and 'state' variables
            // removed from the URL.
            $url = $this->urlGenerator
              ->generateFromRoute('<current>', [
              'plugin' => $definition['id'],
            ]);
            $redirect = new RedirectResponse($url);
            $redirect
              ->send();
            exit;
          }
        }
      }

      // Create an array of key => name value pairs of the OAuth2 Client plugins
      // to be used as the #options in the form, allowing users to select the
      // plugin on the system to test.
      $options = array_map(function ($definition) {
        return $definition['name'];
      }, $definitions);
      $form['plugin'] = [
        '#type' => 'container',
      ];

      // Determine the definition plugin that should be displayed (if any).
      $definition_key = $form_state
        ->getValue('oauth2_client_plugin');
      if (!$definition_key) {
        $definition_key = $this->routeMatch
          ->getParameter('plugin');
      }

      // Create a select list of plugins, so users can choose a plugin to test.
      $form['plugin']['oauth2_client_plugin'] = [
        '#type' => 'select',
        '#title' => t('Plugin to test'),
        '#options' => [
          '' => $this
            ->t('- SELECT PLUGIN -'),
        ] + $options,
        '#default_value' => $definition_key,
      ];

      // A non-AJAX submit button is used, as the redirects with OAuth2 don't
      // work well with AJAX.
      $form['plugin']['set_plugin'] = [
        '#type' => 'submit',
        '#value' => $this
          ->t('Apply'),
        '#submit' => [
          '::setPlugin',
        ],
      ];

      // If a plugin has been selected, show more info.
      if ($definition_key) {

        // Get the current definition.
        $definition = $definitions[$definition_key];

        // Walk through the array to make each key a human readable value.
        array_walk($definition, function (&$value, $key) {
          $value = $key . ': ' . $value;
        });

        // Display the plugin info to the user.
        $form['oauth2_client_plugin_info'] = [
          '#prefix' => '<h2>' . $this
            ->t('Plugin Info') . '</h2><pre>',
          '#suffix' => '</pre>',
          '#markup' => implode('<br />', $definition),
        ];
        $form['actions'] = [
          '#type' => 'actions',
        ];

        // Create the button that will test the authentication on the remote
        // server.
        $form['actions']['test_plugin'] = [
          '#type' => 'submit',
          '#value' => $this
            ->t('Test Plugin'),
          '#submit' => [
            '::testPlugin',
          ],
        ];

        // Create a button to clear the access token altogether.
        $form['actions']['clear_access_token'] = [
          '#type' => 'submit',
          '#value' => $this
            ->t('Clear Access Token'),
          '#submit' => [
            '::clearAccessToken',
          ],
        ];

        // Retrieve a stored access token if one exists.
        $access_token = $this->oauth2ClientService
          ->retrieveAccessToken($definition_key);

        // Check if a token was retrieved.
        if ($access_token) {
          $values = [
            $this
              ->t('Access Token: @token', [
              '@token' => $access_token
                ->getToken(),
            ]),
            $this
              ->t('Refresh Token: @token', [
              '@token' => $access_token
                ->getRefreshToken(),
            ]),
            $this
              ->t('Expires: @expires', [
              '@expires' => $access_token
                ->getExpires(),
            ]),
            $this
              ->t('Has Expired: @expired', [
              '@expired' => $access_token
                ->getExpires() && $access_token
                ->hasExpired() ? t('Yes') : t('No'),
            ]),
          ];

          // Display the token details to the user.
          $form['access_token'] = [
            '#prefix' => '<h2>' . $this
              ->t('Current Access Token') . '</h2><pre>',
            '#suffix' => '</pre>',
            '#markup' => implode('<br/>', $values),
          ];
        }
        else {
          $form['no_access_token'] = [
            '#prefix' => '<h2>' . $this
              ->t('Current Access Token') . '</h2><pre>',
            '#suffix' => '</pre>',
            '#markup' => $this
              ->t('No access token has been stored'),
          ];
        }
      }
    }
    else {
      $form['no_plugins'] = [
        '#prefix' => '<p><em>',
        '#suffix' => '</em></p>',
        '#markup' => $this
          ->t('No OAuth2 Client plugins found'),
      ];
    }
    return $form;
  }

  /**
   * Ajax callback form the Oauth2 Client Tester form.
   */
  public function ajaxCallback(array &$form, FormStateInterface $form_state) {
    return $form;
  }

  /**
   * Set the plugin to test.
   */
  public function setPlugin(array &$form, FormStateInterface $form_state) {

    // The current plugin is set through the URL (so as to allow redirects from
    // OAuth2 servers back to this page). As such, when a plugin is selected,
    // a redirect needs to happen.
    if ($plugin = $form_state
      ->getValue('oauth2_client_plugin')) {
      $form_state
        ->setRedirect('oauth2_client.reports.tester.plugin', [
        'plugin' => $plugin,
      ]);
    }
    else {
      $form_state
        ->setRedirect('oauth2_client.reports.tester');
    }
  }

  /**
   * Test the seledted plugin by authenticating to the OAuth2 Server.
   */
  public function testPlugin(array &$form, FormStateInterface $form_state) {
    $form_state
      ->setRebuild(TRUE);

    // Attempt to retrieve an access token.
    $this->oauth2ClientService
      ->getAccessToken($form_state
      ->getValue('oauth2_client_plugin'));
  }

  /**
   * Clear the authorization token for the selected OAuth2 Client.
   */
  public function clearAccessToken(array &$form, FormStateInterface $form_state) {
    $form_state
      ->setRebuild(TRUE);
    $this->oauth2ClientService
      ->clearAccessToken($form_state
      ->getValue('oauth2_client_plugin'));
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $form_state
      ->setRebuild(TRUE);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ClientTestForm::$currentRequest protected property The current request.
ClientTestForm::$oauth2ClientPluginManager protected property The OAuth2 Client plugin manager.
ClientTestForm::$oauth2ClientService protected property The OAuth2 Client service.
ClientTestForm::$tempstore protected property The Drupal tempstore.
ClientTestForm::$urlGenerator protected property The URL generator service. Overrides UrlGeneratorTrait::$urlGenerator
ClientTestForm::ajaxCallback public function Ajax callback form the Oauth2 Client Tester form.
ClientTestForm::buildForm public function Form constructor. Overrides FormInterface::buildForm
ClientTestForm::clearAccessToken public function Clear the authorization token for the selected OAuth2 Client.
ClientTestForm::create public static function Instantiates a new instance of this class. Overrides FormBase::create
ClientTestForm::getFormId public function Returns a unique string identifying the form. Overrides FormInterface::getFormId
ClientTestForm::setPlugin public function Set the plugin to test.
ClientTestForm::submitForm public function Form submission handler. Overrides FormInterface::submitForm
ClientTestForm::testPlugin public function Test the seledted plugin by authenticating to the OAuth2 Server.
ClientTestForm::__construct public function Constructs a ClientTestForm object.
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
FormBase::$configFactory protected property The config factory. 1
FormBase::$requestStack protected property The request stack. 1
FormBase::$routeMatch protected property The route match.
FormBase::config protected function Retrieves a configuration object.
FormBase::configFactory protected function Gets the config factory for this form. 1
FormBase::container private function Returns the service container.
FormBase::currentUser protected function Gets the current user.
FormBase::getRequest protected function Gets the request object.
FormBase::getRouteMatch protected function Gets the route match.
FormBase::logger protected function Gets the logger for a specific channel.
FormBase::redirect protected function Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait::redirect
FormBase::resetConfigFactory public function Resets the configuration factory.
FormBase::setConfigFactory public function Sets the config factory for this form.
FormBase::setRequestStack public function Sets the request stack object to use.
FormBase::validateForm public function Form validation handler. Overrides FormInterface::validateForm 62
LinkGeneratorTrait::$linkGenerator protected property The link generator. 1
LinkGeneratorTrait::getLinkGenerator Deprecated protected function Returns the link generator.
LinkGeneratorTrait::l Deprecated protected function Renders a link to a route given a route name and its parameters.
LinkGeneratorTrait::setLinkGenerator Deprecated public function Sets the link generator service.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
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.
UrlGeneratorTrait::getUrlGenerator Deprecated protected function Returns the URL generator service.
UrlGeneratorTrait::setUrlGenerator Deprecated public function Sets the URL generator service.
UrlGeneratorTrait::url Deprecated protected function Generates a URL or path for a specific route based on the given parameters.