You are here

class SalesforceJWTPlugin in Salesforce Suite 8.4

Same name and namespace in other branches
  1. 5.0.x modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php \Drupal\salesforce_jwt\Plugin\SalesforceAuthProvider\SalesforceJWTPlugin

JWT Oauth plugin.

Plugin annotation


@Plugin(
  id = "jwt",
  label = @Translation("Salesforce JWT OAuth"),
  credentials_class = "\Drupal\salesforce_jwt\Consumer\JWTCredentials"
)

Hierarchy

Expanded class hierarchy of SalesforceJWTPlugin

File

modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php, line 25

Namespace

Drupal\salesforce_jwt\Plugin\SalesforceAuthProvider
View source
class SalesforceJWTPlugin extends SalesforceAuthProviderPluginBase {

  /**
   * The credentials for this auth plugin.
   *
   * @var \Drupal\salesforce_jwt\Consumer\JWTCredentials
   */
  protected $credentials;

  /**
   * Key repository service.
   *
   * @var \Drupal\key\KeyRepositoryInterface
   */
  protected $keyRepository;

  /**
   * SalesforceAuthServiceBase constructor.
   *
   * @param array $configuration
   *   Configuration.
   * @param string $plugin_id
   *   Plugin id.
   * @param mixed $plugin_definition
   *   Plugin definition.
   * @param \OAuth\Common\Http\Client\ClientInterface $httpClient
   *   Http client wrapper.
   * @param \Drupal\salesforce\Storage\SalesforceAuthTokenStorageInterface $storage
   *   Token storage.
   * @param \Drupal\key\KeyRepositoryInterface $keyRepository
   *   Key repository.
   *
   * @throws \OAuth\OAuth2\Service\Exception\InvalidScopeException
   *   On error.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, ClientInterface $httpClient, SalesforceAuthTokenStorageInterface $storage, KeyRepositoryInterface $keyRepository) {
    $this->keyRepository = $keyRepository;
    parent::__construct($configuration, $plugin_id, $plugin_definition, $httpClient, $storage);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    $configuration = array_merge(self::defaultConfiguration(), $configuration);
    return new static($configuration, $plugin_id, $plugin_definition, $container
      ->get('salesforce.http_client_wrapper'), $container
      ->get('salesforce.auth_token_storage'), $container
      ->get('key.repository'));
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultConfiguration() {
    $defaults = parent::defaultConfiguration();
    return array_merge($defaults, [
      'login_user' => '',
      'encrypt_key' => '',
    ]);
  }

  /**
   * {@inheritdoc}
   */
  public function getLoginUrl() {
    return $this
      ->getCredentials()
      ->getLoginUrl();
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    if (!$this->keyRepository
      ->getKeyNamesAsOptions([
      'type' => 'authentication',
    ])) {
      $this
        ->messenger()
        ->addError($this
        ->t('Please <a href="@href">add an authentication key</a> before creating a JWT Auth provider.', [
        '@href' => Url::fromRoute('entity.key.add_form')
          ->toString(),
      ]));
      return $form;
    }
    $form['consumer_key'] = [
      '#title' => $this
        ->t('Salesforce consumer key'),
      '#type' => 'textfield',
      '#description' => $this
        ->t('Consumer key of the Salesforce remote application you want to grant access to'),
      '#required' => TRUE,
      '#default_value' => $this
        ->getCredentials()
        ->getConsumerKey(),
    ];
    $form['login_user'] = [
      '#title' => $this
        ->t('Salesforce login user'),
      '#type' => 'textfield',
      '#description' => $this
        ->t('User account to issue token to'),
      '#required' => TRUE,
      '#default_value' => $this
        ->getCredentials()
        ->getLoginUser(),
    ];
    $form['login_url'] = [
      '#title' => $this
        ->t('Login URL'),
      '#type' => 'textfield',
      '#default_value' => $this
        ->getCredentials()
        ->getLoginUrl(),
      '#description' => $this
        ->t('Enter a login URL, either https://login.salesforce.com or https://test.salesforce.com.'),
      '#required' => TRUE,
    ];

    // Can't use key-select input type here because its #process method doesn't
    // fire on ajax, so the list is empty. DERP.
    $form['encrypt_key'] = [
      '#title' => 'Private Key',
      '#type' => 'select',
      '#empty_option' => $this
        ->t('- Select -'),
      '#options' => $this->keyRepository
        ->getKeyNamesAsOptions([
        'type' => 'authentication',
      ]),
      '#required' => TRUE,
      '#default_value' => $this
        ->getCredentials()
        ->getKeyId(),
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
    parent::validateConfigurationForm($form, $form_state);
    if (empty($form_state
      ->getValue('provider_settings')) && $form_state
      ->getValue('provider_settings') == self::defaultConfiguration()) {
      $form_state
        ->setError($form, $this
        ->t('Please fill in JWT provider settings.'));
      return;
    }
    $this
      ->setConfiguration($form_state
      ->getValue('provider_settings'));

    // Force new credentials from form input, rather than storage.
    unset($this->credentials);
    try {

      // Bootstrap here by setting ID to provide a key to token storage.
      $this->id = $form_state
        ->getValue('id');
      $this
        ->requestAccessToken($this
        ->generateAssertion());
    } catch (\Exception $e) {
      $form_state
        ->setError($form, $e
        ->getMessage());
    }
  }

  /**
   * Overrides AbstractService::requestAccessToken for jwt-bearer flow.
   *
   * @param string $assertion
   *   The JWT assertion.
   * @param string $state
   *   Not used.
   *
   * @return \OAuth\Common\Token\TokenInterface
   *   Access Token.
   *
   * @throws \OAuth\Common\Http\Exception\TokenResponseException
   */
  public function requestAccessToken($assertion, $state = NULL) {
    $data = [
      'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
      'assertion' => $assertion,
    ];
    $response = $this->httpClient
      ->retrieveResponse(new Uri($this
      ->getLoginUrl() . static::AUTH_TOKEN_PATH), $data, [
      'Content-Type' => 'application/x-www-form-urlencoded',
    ]);
    $token = $this
      ->parseAccessTokenResponse($response);
    $this->storage
      ->storeAccessToken($this
      ->service(), $token);
    $this
      ->refreshIdentity($token);
    return $token;
  }

  /**
   * {@inheritDoc}
   */
  public function refreshAccessToken(TokenInterface $token) {
    $token = $this
      ->requestAccessToken($this
      ->generateAssertion());
    $this
      ->refreshIdentity($token);
    return $token;
  }

  /**
   * Returns a JWT Assertion to authenticate.
   *
   * @return string
   *   JWT Assertion.
   */
  protected function generateAssertion() {
    $key = $this->keyRepository
      ->getKey($this
      ->getCredentials()
      ->getKeyId())
      ->getKeyValue();
    $token = $this
      ->generateAssertionClaim();
    return JWT::encode($token, $key, 'RS256');
  }

  /**
   * Returns a JSON encoded JWT Claim.
   *
   * @return array
   *   The claim array.
   */
  protected function generateAssertionClaim() {
    $cred = $this
      ->getCredentials();
    return [
      'iss' => $cred
        ->getConsumerKey(),
      'sub' => $cred
        ->getLoginUser(),
      'aud' => $cred
        ->getLoginUrl(),
      'exp' => \Drupal::time()
        ->getCurrentTime() + 60,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getPluginDefinition() {
    $definition = parent::getPluginDefinition();
    if ($this->configuration['encrypt_key'] && ($key = $this->keyRepository
      ->getKey($this->configuration['encrypt_key']))) {
      $definition['config_dependencies']['config'][] = $key
        ->getConfigDependencyName();
    }
    return $definition;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
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
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
SalesforceAuthProviderInterface::AUTH_ENDPOINT_PATH constant
SalesforceAuthProviderInterface::AUTH_TOKEN_PATH constant
SalesforceAuthProviderInterface::LATEST_API_VERSION constant
SalesforceAuthProviderInterface::SOAP_CLASS_PATH constant
SalesforceAuthProviderPluginBase::$configuration protected property Configuration.
SalesforceAuthProviderPluginBase::$id protected property Instance id, e.g. "sandbox1" or "production".
SalesforceAuthProviderPluginBase::$pluginDefinition protected property Plugin definition.
SalesforceAuthProviderPluginBase::$pluginId protected property Provider id, e.g. jwt, oauth.
SalesforceAuthProviderPluginBase::$storage protected property Token storage.
SalesforceAuthProviderPluginBase::getAccessToken public function Access token for this plugin. Overrides SalesforceAuthProviderInterface::getAccessToken
SalesforceAuthProviderPluginBase::getAccessTokenEndpoint public function Access token URL for this plugin type. Overrides SalesforceAuthProviderInterface::getAccessTokenEndpoint
SalesforceAuthProviderPluginBase::getApiEndpoint public function API Url for this plugin. Overrides SalesforceAuthProviderInterface::getApiEndpoint
SalesforceAuthProviderPluginBase::getApiVersion public function Get the globally configured API version to use. Overrides SalesforceAuthProviderInterface::getApiVersion
SalesforceAuthProviderPluginBase::getAuthorizationEndpoint public function Authorization URL for this plugin type. Overrides SalesforceAuthProviderInterface::getAuthorizationEndpoint
SalesforceAuthProviderPluginBase::getConfiguration public function
SalesforceAuthProviderPluginBase::getCredentials public function Return the credentials configured for this auth provider instance. Overrides SalesforceAuthProviderInterface::getCredentials 1
SalesforceAuthProviderPluginBase::getIdentity public function Identify for this connection. Overrides SalesforceAuthProviderInterface::getIdentity
SalesforceAuthProviderPluginBase::getInstanceUrl public function Instance URL for this connection. Overrides SalesforceAuthProviderInterface::getInstanceUrl 1
SalesforceAuthProviderPluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
SalesforceAuthProviderPluginBase::getStorage public function Accessor to the storage adapter to be able to retrieve tokens.
SalesforceAuthProviderPluginBase::hasAccessToken public function TRUE if the connection has a token, regardless of validity. Overrides SalesforceAuthProviderInterface::hasAccessToken
SalesforceAuthProviderPluginBase::id public function Id of this service. Overrides SalesforceAuthProviderInterface::id
SalesforceAuthProviderPluginBase::label public function Label of this service. Overrides SalesforceAuthProviderInterface::label
SalesforceAuthProviderPluginBase::refreshIdentity public function Given a token, fetch the SF identity. Overrides SalesforceAuthProviderInterface::refreshIdentity
SalesforceAuthProviderPluginBase::revokeAccessToken public function Clear the access token for this auth provider plugin. Overrides SalesforceAuthProviderInterface::revokeAccessToken
SalesforceAuthProviderPluginBase::save public function Callback for configuration form after saving config entity. Overrides SalesforceAuthProviderInterface::save
SalesforceAuthProviderPluginBase::service public function The auth provider service. Overrides SalesforceAuthProviderInterface::service
SalesforceAuthProviderPluginBase::setConfiguration public function
SalesforceAuthProviderPluginBase::submitConfigurationForm public function Form submission handler. Overrides PluginFormInterface::submitConfigurationForm 1
SalesforceJWTPlugin::$credentials protected property The credentials for this auth plugin. Overrides SalesforceAuthProviderPluginBase::$credentials
SalesforceJWTPlugin::$keyRepository protected property Key repository service.
SalesforceJWTPlugin::buildConfigurationForm public function Form constructor. Overrides PluginFormInterface::buildConfigurationForm
SalesforceJWTPlugin::create public static function Creates an instance of the plugin. Overrides SalesforceAuthProviderPluginBase::create
SalesforceJWTPlugin::defaultConfiguration public static function Default configuration for this plugin type. Overrides SalesforceAuthProviderPluginBase::defaultConfiguration
SalesforceJWTPlugin::generateAssertion protected function Returns a JWT Assertion to authenticate.
SalesforceJWTPlugin::generateAssertionClaim protected function Returns a JSON encoded JWT Claim.
SalesforceJWTPlugin::getLoginUrl public function
SalesforceJWTPlugin::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides SalesforceAuthProviderPluginBase::getPluginDefinition
SalesforceJWTPlugin::refreshAccessToken public function Perform a refresh of the given token. Overrides SalesforceAuthProviderPluginBase::refreshAccessToken
SalesforceJWTPlugin::requestAccessToken public function Overrides AbstractService::requestAccessToken for jwt-bearer flow. Overrides SalesforceAuthProviderPluginBase::requestAccessToken
SalesforceJWTPlugin::validateConfigurationForm public function Form validation handler. Overrides SalesforceAuthProviderPluginBase::validateConfigurationForm
SalesforceJWTPlugin::__construct public function SalesforceAuthServiceBase constructor. Overrides SalesforceAuthProviderPluginBase::__construct
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.