You are here

class Oauth2AuthorizeController in Simple OAuth (OAuth2) & OpenID Connect 8.3

Oauth2AuthorizeController.

Hierarchy

Expanded class hierarchy of Oauth2AuthorizeController

File

simple_oauth_extras/src/Controller/Oauth2AuthorizeController.php, line 30

Namespace

Drupal\simple_oauth_extras\Controller
View source
class Oauth2AuthorizeController extends ControllerBase {

  /**
   * @var \Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface
   */
  protected $messageFactory;

  /**
   * @var \Drupal\simple_oauth\Plugin\Oauth2GrantManagerInterface
   */
  protected $grantManager;

  /**
   * @var \Drupal\Core\Form\FormBuilderInterface
   */
  protected $formBuilder;

  /**
   * The messenger service.
   *
   * @var \Drupal\Core\Messenger\MessengerInterface
   */
  protected $messenger;

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The known client repository service.
   *
   * @var \Drupal\simple_oauth\KnownClientsRepositoryInterface
   */
  protected $knownClientRepository;

  /**
   * Oauth2AuthorizeController construct.
   *
   * @param \Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface $message_factory
   *   The PSR-7 converter.
   * @param \Drupal\simple_oauth\Plugin\Oauth2GrantManagerInterface $grant_manager
   *   The plugin.manager.oauth2_grant.processor service.
   * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
   *   The form builder.
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   The messenger service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   * @param \Drupal\simple_oauth\KnownClientsRepositoryInterface $known_clients_repository
   *   The known client repository service.
   */
  public function __construct(HttpMessageFactoryInterface $message_factory, Oauth2GrantManagerInterface $grant_manager, FormBuilderInterface $form_builder, MessengerInterface $messenger, ConfigFactoryInterface $config_factory, KnownClientsRepositoryInterface $known_clients_repository) {
    $this->messageFactory = $message_factory;
    $this->grantManager = $grant_manager;
    $this->formBuilder = $form_builder;
    $this->messenger = $messenger;
    $this->configFactory = $config_factory;
    $this->knownClientRepository = $known_clients_repository;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('psr7.http_message_factory'), $container
      ->get('plugin.manager.oauth2_grant.processor'), $container
      ->get('form_builder'), $container
      ->get('messenger'), $container
      ->get('config.factory'), $container
      ->get('simple_oauth.known_clients'));
  }

  /**
   * Authorizes the code generation or prints the confirmation form.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The incoming request.
   *
   * @return mixed
   *   The response.
   */
  public function authorize(Request $request) {
    $client_uuid = $request
      ->get('client_id');
    if (empty($client_uuid)) {
      return OAuthServerException::invalidClient()
        ->generateHttpResponse(new Response());
    }
    try {
      $consumer_storage = $this
        ->entityTypeManager()
        ->getStorage('consumer');
    } catch (InvalidPluginDefinitionException $exception) {
      watchdog_exception('simple_oauth_extras', $exception);
      return RedirectResponse::create(Url::fromRoute('<front>')
        ->toString());
    }
    $client_drupal_entities = $consumer_storage
      ->loadByProperties([
      'uuid' => $client_uuid,
    ]);
    if (empty($client_drupal_entities)) {
      return OAuthServerException::invalidClient()
        ->generateHttpResponse(new Response());
    }
    $client_drupal_entity = reset($client_drupal_entities);
    $is_third_party = $client_drupal_entity
      ->get('third_party')->value;
    $scopes = [];
    if ($request->query
      ->get('scope')) {
      $scopes = explode(' ', $request->query
        ->get('scope'));
    }
    if ($this
      ->currentUser()
      ->isAnonymous()) {
      $this->messenger
        ->addStatus($this
        ->t('An external client application is requesting access to your data in this site. Please log in first to authorize the operation.'));

      // If the user is not logged in.
      $destination = Url::fromRoute('oauth2_token_extras.authorize', [], [
        'query' => UrlHelper::parse('/?' . $request
          ->getQueryString())['query'],
      ]);
      $url = Url::fromRoute('user.login', [], [
        'query' => [
          'destination' => $destination
            ->toString(),
        ],
      ]);

      // Client ID and secret may be passed as Basic Auth. Copy the headers.
      return RedirectResponse::create($url
        ->toString(), 302, $request->headers
        ->all());
    }
    elseif (!$is_third_party || $this
      ->isKnownClient($client_uuid, $scopes)) {

      // Login user may skip the grant step if the client is not third party or
      // known.
      if ($request
        ->get('response_type') == 'code') {
        $grant_type = 'code';
      }
      elseif ($request
        ->get('response_type') == 'token') {
        $grant_type = 'implicit';
      }
      else {
        $grant_type = NULL;
      }
      try {
        $server = $this->grantManager
          ->getAuthorizationServer($grant_type);
        $ps7_request = $this->messageFactory
          ->createRequest($request);
        $auth_request = $server
          ->validateAuthorizationRequest($ps7_request);
      } catch (OAuthServerException $exception) {
        $this->messenger
          ->addMessage($this
          ->t('Fatal error. Unable to get the authorization server.'));
        watchdog_exception('simple_oauth_extras', $exception);
        return RedirectResponse::create(Url::fromRoute('<front>')
          ->toString());
      }
      if ($auth_request) {
        $can_grant_codes = $this
          ->currentUser()
          ->hasPermission('grant simple_oauth codes');
        return static::redirectToCallback($auth_request, $server, $this->currentUser, $can_grant_codes);
      }
    }
    return $this->formBuilder
      ->getForm('Drupal\\simple_oauth_extras\\Controller\\Oauth2AuthorizeForm');
  }

  /**
   * Generates a redirection response to the consumer callback.
   *
   * @param \League\OAuth2\Server\RequestTypes\AuthorizationRequest $auth_request
   *   The auth request.
   * @param \League\OAuth2\Server\AuthorizationServer $server
   *   The authorization server.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The user to be logged in.
   * @param bool $can_grant_codes
   *   Weather or not the user can grant codes.
   * @param bool $remembers_clients
   *   Weather or not the sites remembers consumers that were previously
   *   granted access.
   * @param \Drupal\simple_oauth\KnownClientsRepositoryInterface|null $known_clients_repository
   *   The known clients repository.
   *
   * @return \Drupal\Core\Routing\TrustedRedirectResponse
   *   The response.
   */
  public static function redirectToCallback(AuthorizationRequest $auth_request, AuthorizationServer $server, AccountInterface $current_user, $can_grant_codes, $remembers_clients = FALSE, KnownClientsRepositoryInterface $known_clients_repository = NULL) {

    // Once the user has logged in set the user on the AuthorizationRequest.
    $user_entity = new UserEntity();
    $user_entity
      ->setIdentifier($current_user
      ->id());
    $auth_request
      ->setUser($user_entity);

    // Once the user has approved or denied the client update the status
    // (true = approved, false = denied).
    $auth_request
      ->setAuthorizationApproved($can_grant_codes);

    // Return the HTTP redirect response.
    $response = $server
      ->completeAuthorizationRequest($auth_request, new Response());

    // Remembers the choice for the current user.
    if ($remembers_clients) {
      $scopes = array_map(function (ScopeEntityInterface $scope) {
        return $scope
          ->getIdentifier();
      }, $auth_request
        ->getScopes());
      $known_clients_repository = $known_clients_repository instanceof KnownClientsRepositoryInterface ? $known_clients_repository : \Drupal::service('simple_oauth.known_clients');
      $known_clients_repository
        ->rememberClient($current_user
        ->id(), $auth_request
        ->getClient()
        ->getIdentifier(), $scopes);
    }

    // Get the location and return a secure redirect response.
    return TrustedRedirectResponse::create($response
      ->getHeaderLine('location'), $response
      ->getStatusCode(), $response
      ->getHeaders());
  }

  /**
   * Whether the client with the given scopes is known and already authorized.
   *
   * @param string $client_uuid
   *   The client UUID.
   * @param string[] $scopes
   *   The list of scopes.
   *
   * @return bool
   *   TRUE if the client is authorized, FALSE otherwise.
   */
  protected function isKnownClient($client_uuid, array $scopes) {
    if (!$this->configFactory
      ->get('simple_oauth.settings')
      ->get('remember_clients')) {
      return FALSE;
    }
    return $this->knownClientRepository
      ->isAuthorized($this
      ->currentUser()
      ->id(), $client_uuid, $scopes);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ControllerBase::$currentUser protected property The current user service. 1
ControllerBase::$entityFormBuilder protected property The entity form builder.
ControllerBase::$entityManager protected property The entity manager.
ControllerBase::$entityTypeManager protected property The entity type manager.
ControllerBase::$keyValue protected property The key-value storage. 1
ControllerBase::$languageManager protected property The language manager. 1
ControllerBase::$moduleHandler protected property The module handler. 2
ControllerBase::$stateService protected property The state service.
ControllerBase::cache protected function Returns the requested cache bin.
ControllerBase::config protected function Retrieves a configuration object.
ControllerBase::container private function Returns the service container.
ControllerBase::currentUser protected function Returns the current user. 1
ControllerBase::entityFormBuilder protected function Retrieves the entity form builder.
ControllerBase::entityManager Deprecated protected function Retrieves the entity manager service.
ControllerBase::entityTypeManager protected function Retrieves the entity type manager.
ControllerBase::formBuilder protected function Returns the form builder service. 2
ControllerBase::keyValue protected function Returns a key/value storage collection. 1
ControllerBase::languageManager protected function Returns the language manager service. 1
ControllerBase::moduleHandler protected function Returns the module handler. 2
ControllerBase::redirect protected function Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait::redirect
ControllerBase::state protected function Returns the state storage service.
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 public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
Oauth2AuthorizeController::$configFactory protected property The config factory. Overrides ControllerBase::$configFactory
Oauth2AuthorizeController::$formBuilder protected property Overrides ControllerBase::$formBuilder
Oauth2AuthorizeController::$grantManager protected property
Oauth2AuthorizeController::$knownClientRepository protected property The known client repository service.
Oauth2AuthorizeController::$messageFactory protected property
Oauth2AuthorizeController::$messenger protected property The messenger service. Overrides MessengerTrait::$messenger
Oauth2AuthorizeController::authorize public function Authorizes the code generation or prints the confirmation form.
Oauth2AuthorizeController::create public static function Instantiates a new instance of this class. Overrides ControllerBase::create
Oauth2AuthorizeController::isKnownClient protected function Whether the client with the given scopes is known and already authorized.
Oauth2AuthorizeController::redirectToCallback public static function Generates a redirection response to the consumer callback.
Oauth2AuthorizeController::__construct public function Oauth2AuthorizeController construct.
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::$urlGenerator protected property The url generator.
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.