From 50e574bc1587dba9e052d7ff4bc969215bd975df Mon Sep 17 00:00:00 2001
From: jidrone <jidrone@1769194.no-reply.drupal.org>
Date: Mon, 27 Sep 2021 12:36:57 -0400
Subject: [PATCH] Issue #3057022 by jidrone: Support for Gov Cloud

---
 .../src/Consumer/JWTGovCloudCredentials.php   | 55 ++++++++++++
 .../SalesforceJWTGovCloudPlugin.php           | 87 +++++++++++++++++++
 2 files changed, 142 insertions(+)
 create mode 100644 modules/salesforce_jwt/src/Consumer/JWTGovCloudCredentials.php
 create mode 100644 modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTGovCloudPlugin.php

diff --git a/modules/salesforce_jwt/src/Consumer/JWTGovCloudCredentials.php b/modules/salesforce_jwt/src/Consumer/JWTGovCloudCredentials.php
new file mode 100644
index 00000000..42f09066
--- /dev/null
+++ b/modules/salesforce_jwt/src/Consumer/JWTGovCloudCredentials.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Drupal\salesforce_jwt\Consumer;
+
+/**
+ * JWT Gov Cloud credentials.
+ */
+class JWTGovCloudCredentials extends JWTCredentials {
+
+  /**
+   * Token URL for JWT OAuth authentication.
+   *
+   * @var string
+   */
+  protected $tokenUrl;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct($consumerKey, $loginUrl, $loginUser, $keyId, $tokenUrl) {
+    parent::__construct($consumerKey, $loginUrl, $loginUser, $keyId);
+    $this->tokenUrl = $tokenUrl;
+  }
+
+  /**
+   * Constructor helper.
+   *
+   * @param array $configuration
+   *   Plugin configuration.
+   *
+   * @return \Drupal\salesforce_jwt\Consumer\JWTGovCloudCredentials
+   *   Credentials, valid or not.
+   */
+  public static function create(array $configuration) {
+    return new static($configuration['consumer_key'], $configuration['login_url'], $configuration['login_user'], $configuration['encrypt_key'], $configuration['token_url']);
+  }
+
+  /**
+   * Token url getter.
+   *
+   * @return string
+   *   The token url.
+   */
+  public function getTokenUrl() {
+    return $this->tokenUrl;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isValid() {
+    return !empty($this->loginUser) && !empty($this->consumerId) && !empty($this->keyId) && !empty($this->tokenUrl);
+  }
+
+}
diff --git a/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTGovCloudPlugin.php b/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTGovCloudPlugin.php
new file mode 100644
index 00000000..c08f0bc5
--- /dev/null
+++ b/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTGovCloudPlugin.php
@@ -0,0 +1,87 @@
+<?php
+
+namespace Drupal\salesforce_jwt\Plugin\SalesforceAuthProvider;
+
+use Drupal\Core\Form\FormStateInterface;
+use OAuth\Common\Http\Uri\Uri;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * JWT Oauth plugin.
+ *
+ * @Plugin(
+ *   id = "jwt_govcloud",
+ *   label = @Translation("Salesforce JWT OAuth for GovCloud"),
+ *   credentials_class = "\Drupal\salesforce_jwt\Consumer\JWTGovCloudCredentials"
+ * )
+ */
+class SalesforceJWTGovCloudPlugin extends SalesforceJWTPlugin {
+
+  /**
+   * {@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, [
+      'token_url' => '',
+    ]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTokenUrl() {
+    return $this->getCredentials()->getTokenUrl();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildConfigurationForm($form, $form_state);
+    $form['token_url'] = [
+      '#title' => t('Token URL'),
+      '#type' => 'textfield',
+      '#default_value' => $this->getCredentials()->getTokenUrl(),
+      '#description' => t('Enter a token URL, like https://yourcompany.my.salesforce.com'),
+      '#required' => TRUE,
+    ];
+
+    return $form;
+  }
+
+  /**
+   * Overrides AbstractService::requestAccessToken for jwt-bearer flow.
+   *
+   * This is only intended to use the token url instead of login url.
+   *
+   * @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->getTokenUrl() . static::AUTH_TOKEN_PATH), $data, ['Content-Type' => 'application/x-www-form-urlencoded']);
+    $token = $this->parseAccessTokenResponse($response);
+    $this->storage->storeAccessToken($this->service(), $token);
+    return $token;
+  }
+
+}
-- 
GitLab