authman-1.x-dev/src/Controller/AuthmanOauthAuthorizationCodeController.php

src/Controller/AuthmanOauthAuthorizationCodeController.php
<?php

declare(strict_types = 1);

namespace Drupal\authman\Controller;

use Drupal\authman\Entity\AuthmanAuthInterface;
use Drupal\authman\Token\AuthmanAccessToken;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Provides a controller for sending user offsite or receiving tokens.
 */
class AuthmanOauthAuthorizationCodeController extends ControllerBase {

  /**
   * The private tempstore factory.
   *
   * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
   */
  protected $privateStoreFactory;

  /**
   * The OAuth provider instance factory.
   *
   * @var \Drupal\authman\AuthmanInstance\AuthmanOauthFactoryInterface
   */
  protected $authmanOauthFactory;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    $instance = parent::create($container);
    $instance->entityTypeManager = $container->get('entity_type.manager');
    $instance->privateStoreFactory = $container->get('tempstore.private');
    $instance->authmanOauthFactory = $container->get('authman.oauth');
    $instance->messenger = $container->get('messenger');
    $instance->currentUser = $container->get('current_user');
    $instance->stringTranslation = $container->get('string_translation');
    return $instance;
  }

  /**
   * Starts the authorization code process.
   *
   * Starts the process to request an authorization code from the authorization
   * server by sending the resource owner offsite.
   *
   * We request the appropriate permissions (scope) and hold onto a checksum
   * value (state).
   *
   * Users are redirected back to the website thanks to the redirectUri
   * setting in createProvider.
   *
   * @return \Symfony\Component\HttpFoundation\Response
   *   Redirect response offsite.
   */
  public function start(AuthmanAuthInterface $authman_auth): Response {
    // @todo #94/#95
    $authmanInstance = $this->authmanOauthFactory->get($authman_auth->id());

    // This needs to be called before getState().
    $url = $authmanInstance->authorizationCodeUrl();

    // Keep the state. We need to verify this on user return.
    if (!$authman_auth->uuid()) {
      throw new \LogicException('Instance does not have a UUID');
    }
    $store = $this->privateStoreFactory->get('authman.oauth.' . $authman_auth->uuid());
    $store->set('state', $authmanInstance->getProvider()->getState());

    // Never cache the response for this page.
    $cacheable = (new CacheableMetadata())->setCacheMaxAge(0);
    return (new TrustedRedirectResponse($url->toString()))->addCacheableDependency($cacheable);
  }

  /**
   * For the authorization code process.
   *
   * Represents the redirect URI for a client.
   *
   * The authorization server sends the resource owner back to the site with
   * an authorization code.
   *
   * Receives a redirect back from offsite.
   *
   * Will have query parameters for generating a token.
   *
   * Some parts copied/inspired by docs at
   * https://github.com/thephpleague/oauth2-google.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   Redirects users to info page, displaying success or error message.
   * @param \Drupal\authman\Entity\AuthmanAuthInterface $authman_auth
   *   The Authman instance.
   *
   * @return \Symfony\Component\HttpFoundation\Response
   *   A redirect response.
   */
  public function receive(Request $request, AuthmanAuthInterface $authman_auth): Response {
    $authmanConfigId = $authman_auth->id();

    // @todo #94/#95
    $tokenInfoUrl = Url::fromRoute('entity.authman_auth.information', ['authman_auth' => $authmanConfigId]);

    // Code generated by authorization server and passed back to us by the
    // user agent.
    $authorizationCode = $request->query->get('code');
    $authmanInstance = $this->authmanOauthFactory->get($authmanConfigId);
    try {
      // Get the token via the provided authorization code.
      $token = $authmanInstance->getAccessToken(AuthmanAuthInterface::GRANT_AUTHORIZATION_CODE, ['code' => $authorizationCode]);
    }
    catch (\Exception $e) {
      // Greedy catch.
      $this->messenger->addError($this->t('Error getting access token: @message', ['@message' => $e->getMessage()]));
      return new RedirectResponse($tokenInfoUrl->toString());
    }

    $accessKeyId = $authman_auth->getAccessTokenKeyId();
    /** @var \Drupal\key\KeyInterface $access_key */
    if (!$this->keyStorage()->load($accessKeyId)) {
      $this->messenger->addError($this->t('The key %key does not exist.', ['%key' => $accessKeyId]));
      throw new \LogicException(sprintf('The key %s does not exist', $accessKeyId));
    }

    $this->messenger->addMessage($this->t('Token received successfully.'));

    $token = new AuthmanAccessToken($accessKeyId, $token);
    $token->setKeyStorage($this->entityTypeManager->getStorage('key'));

    $accessKey = $token->saveToKey();
    $editFormUrl = $accessKey->toUrl('edit-form');
    $message = $editFormUrl->access($this->currentUser)
      ? $this->t('<a href=":key_edit_url">Access token</a> key was updated.', [':key_edit_url' => $editFormUrl->toString()])
      : $this->t('Access token key was updated.');
    $this->messenger->addMessage($message);

    return new RedirectResponse($tokenInfoUrl->toString());
  }

  /**
   * Get key config storage.
   *
   * @return \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
   *   The key config storage.
   */
  protected function keyStorage(): EntityStorageInterface {
    return $this->entityTypeManager->getStorage('key');
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc