Commit 3cc36582 authored by Shawn Duncan's avatar Shawn Duncan
Browse files

Issue #3046879 by pbosmans, FatherShawn: Provide collaborators to GenericClient constructor

parent a5f78afc
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -90,6 +90,15 @@ Fill in the various plugin keys with the relevant data. Keys:
 * scope_separator: character that will be added between multiple scope values.
 * success_message: Implementations may conditionally display a message on
   successful storage
 * collaborators: A mapping of keys = class for use as replacements to the
   default objects composed into the GenericProvider. Each key must map to a
   class that extends a specific class.
   See Oauth2ClientPluginInterface::getCollaborators for details. Allowed keys
   are:
   * grantFactory
   * requestFactory
   * httpClient
   * optionProvider

Further examples can be found in `examples/oauth2_client_example_plugins`.

+28 −1
Original line number Diff line number Diff line
@@ -67,13 +67,17 @@ class Oauth2Client extends Plugin {
  /**
   * The set of scopes for the provider to use by default.
   *
   * @var array|string|null
   * OPTIONAL
   *
   * @var string[]|null
   */
  public $scopes;

  /**
   * The separator used to join the scopes in the OAuth2 query string.
   *
   * OPTIONAL
   *
   * @var string|null
   */
  public $scope_separator;
@@ -81,10 +85,33 @@ class Oauth2Client extends Plugin {
  /**
   * A flag that may be used by Oauth2ClientPluginInterface::storeAccessToken.
   *
   * OPTIONAL
   *
   * Implementations may conditionally display a message on successful storage.
   *
   * @var bool
   */
  public $success_message;

  /**
   * An associative array of classes that are composed into the provider.
   *
   * OPTIONAL
   *
   * Allowed keys are:
   * - grantFactory
   * - requestFactory
   * - httpClient
   * - optionProvider
   *
   * @see \League\OAuth2\Client\Provider\AbstractProvider::__construct
   * @see \League\OAuth2\Client\Provider\AbstractProvider::setGrantFactory
   * @see \League\OAuth2\Client\Provider\AbstractProvider::setRequestFactory
   * @see \League\OAuth2\Client\Provider\AbstractProvider::setHttpClient
   * @see \League\OAuth2\Client\Provider\AbstractProvider::setOptionProvider
   *
   * @var string[]|null
   */
  public $collaborators;

}
+49 −0
Original line number Diff line number Diff line
@@ -14,6 +14,10 @@ use Drupal\Core\Url;
use Drupal\oauth2_client\Service\CredentialProvider;
use Drupal\oauth2_client\Exception\Oauth2ClientPluginMissingKeyException;
use Symfony\Component\DependencyInjection\ContainerInterface;
use  League\OAuth2\Client\Grant\GrantFactory;
use  League\OAuth2\Client\Tool\RequestFactory;
use  GuzzleHttp\ClientInterface;
use  League\OAuth2\Client\OptionProvider\OptionProviderInterface;

/**
 * Base class for Oauth2Client plugins.
@@ -64,6 +68,20 @@ abstract class Oauth2ClientPluginBase extends PluginBase implements Oauth2Client
   */
  protected $messenger;

  /**
   * A set of instantiated collaborator objects.
   *
   * OPTIONAL
   *
   * @var array{
   *   grantFactory?: \League\OAuth2\Client\Grant\GrantFactory,
   *   requestFactory?: \League\OAuth2\Client\Tool\RequestFactory,
   *   httpClient?: \GuzzleHttp\ClientInterface,
   *   optionProvider?: \League\OAuth2\Client\OptionProvider\OptionProviderInterface
   *   }
   */
  protected $collaborators;

  /**
   * Constructs a Oauth2ClientPluginBase object.
   *
@@ -381,6 +399,37 @@ abstract class Oauth2ClientPluginBase extends PluginBase implements Oauth2Client
    return $this->pluginDefinition['scopes'] ?: [];
  }

  /**
   * {@inheritdoc}
   */
  public function getCollaborators() {
    if (!empty($this->collaborators)) {
      return $this->collaborators;
    }
    $collaborators = $this->pluginDefinition['collaborators'] ?? [];
    $collaboratorObjects = [];
    foreach ($collaborators as $type => $collaborator) {
      $collaboratorObjects[$type] = new $collaborator();
    }
    // Verify
    if (isset($collaboratorObjects['grantFactory']) && !($collaboratorObjects['grantFactory'] instanceof GrantFactory)) {
      throw new \TypeError('Collaborator key "grantFactory" must be of type GrantFactory');
    }
    if (isset($collaboratorObjects['requestFactory']) && !($collaboratorObjects['requestFactory'] instanceof RequestFactory)) {
      throw new \TypeError('Collaborator key "requestFactory" must be of type RequestFactory');
    }
    if (isset($collaboratorObjects['httpClient']) && !($collaboratorObjects['httpClient'] instanceof ClientInterface)) {
      throw new \TypeError('Collaborator key "httpClient" must be of type ClientInterface');
    }
    if (isset($collaboratorObjects['optionProvider']) && !($collaboratorObjects['optionProvider'] instanceof OptionProviderInterface)) {
      throw new \TypeError('Collaborator key "optionProvider" must be of type OptionProviderInterface');
    }

    $this->collaborators = $collaboratorObjects;
    return $this->collaborators;
  }


  /**
   * {@inheritdoc}
   */
+16 −1
Original line number Diff line number Diff line
@@ -92,7 +92,7 @@ interface Oauth2ClientPluginInterface extends PluginInspectionInterface, Contain
  /**
   * Get the set of scopes for the provider to use by default.
   *
   * @return array|string|null
   * @return array|null
   *   The list of scopes for the provider to use.
   */
  public function getScopes();
@@ -105,6 +105,21 @@ interface Oauth2ClientPluginInterface extends PluginInspectionInterface, Contain
   */
  public function getScopeSeparator();

  /**
   * Returns a set of collaborator objects for use in the provider.
   *
   * Override this method in your plugin if you wish to provide a collaborator
   * object that requires constructor arguments.
   *
   * @return array{
   *   grantFactory?: \League\OAuth2\Client\Grant\GrantFactory,
   *   requestFactory?: \League\OAuth2\Client\Tool\RequestFactory,
   *   httpClient?: \GuzzleHttp\ClientInterface,
   *   optionProvider?: \League\OAuth2\Client\OptionProvider\OptionProviderInterface
   *   }
   */
  public function getCollaborators();

  /**
   * Returns the plugin credentials if they are set, otherwise returns NULL.
   *
+5 −2
Original line number Diff line number Diff line
@@ -93,7 +93,8 @@ abstract class Oauth2ClientGrantServiceBase extends Oauth2ClientServiceBase impl
    else {
      $client = $this->getClient($pluginId);

      $provider = new GenericProvider([
      $provider = new GenericProvider(
        [
          'clientId' => $client->getClientId(),
          'clientSecret' => $client->getClientSecret(),
          'redirectUri' => $client->getRedirectUri(),
@@ -102,7 +103,9 @@ abstract class Oauth2ClientGrantServiceBase extends Oauth2ClientServiceBase impl
          'urlResourceOwnerDetails' => $client->getResourceUri(),
          'scopes' => $client->getScopes(),
          'scopeSeparator' => $client->getScopeSeparator(),
      ]);
        ],
        $client->getCollaborators()
      );
      $this->clientProviderCache[$pluginId] = $provider;
    }
    return $provider;