diff --git a/modules/salesforce_encrypt/config/schema/salesforce_encrypt.schema.yml b/modules/salesforce_encrypt/config/schema/salesforce_encrypt.schema.yml deleted file mode 100644 index 5fdb2e46ce00e0ecd5943dd6e1b05f2c13b92c5f..0000000000000000000000000000000000000000 --- a/modules/salesforce_encrypt/config/schema/salesforce_encrypt.schema.yml +++ /dev/null @@ -1,16 +0,0 @@ -salesforce.auth_provider_settings.oauth_encrypt: - type: mapping - label: 'Salesforce OAuth, Encrypted, Provider Settings' - mapping: - consumer_key: - type: string - label: 'Consumer Key' - consumer_secret: - type: string - label: 'Consumer Secret' - login_url: - type: uri - label: 'Login URL' - encryption_profile: - type: encrypt.profile.[%key] - label: 'Encryption Profile ID' diff --git a/modules/salesforce_encrypt/salesforce_encrypt.info.yml b/modules/salesforce_encrypt/salesforce_encrypt.info.yml index 521059d445a8a40a84db344f4da71a4c2a8cbcac..9842d1a743194e519b14a1e87ba03f5b7ec39995 100644 --- a/modules/salesforce_encrypt/salesforce_encrypt.info.yml +++ b/modules/salesforce_encrypt/salesforce_encrypt.info.yml @@ -4,5 +4,6 @@ description: Adds encryption support for auth providers. package: Salesforce core: 8.x dependencies: + - key:key - encrypt:encrypt - salesforce:salesforce diff --git a/modules/salesforce_encrypt/salesforce_encrypt.install b/modules/salesforce_encrypt/salesforce_encrypt.install new file mode 100644 index 0000000000000000000000000000000000000000..9f84836ed48954bc00196b295aac1c462e72410b --- /dev/null +++ b/modules/salesforce_encrypt/salesforce_encrypt.install @@ -0,0 +1,54 @@ +<?php + +/** + * @file + * Requirements and uninstall hooks. + */ + +use Drupal\Core\Url; +use Drupal\salesforce\EntityNotFoundException; + +/** + * Throw a runtime error if Salesforce encryption profile is not selected. + * + * Implements hook_requirements(). + */ +function salesforce_encrypt_requirements($phase) { + $requirements = []; + if ($phase == 'runtime') { + $profile_id = NULL; + try { + $profile = \Drupal::service('salesforce.client')->getEncryptionProfile(); + } + catch (EntityNotFoundException $e) { + // Noop. + } + $requirements['salesforce_encrypt'] = [ + 'title' => t('Salesforce Encrypt'), + 'value' => t('Encryption Profile'), + ]; + if (empty($profile)) { + $requirements['salesforce_encrypt'] += [ + 'severity' => REQUIREMENT_ERROR, + 'description' => t('You need to <a href="@url">select an encryption profile</a> in order to fully enable Salesforce Encrypt and protect sensitive information.', ['@url' => Url::fromRoute('salesforce_encrypt.settings')->toString()]), + ]; + } + else { + $requirements['salesforce_encrypt'] += [ + 'severity' => REQUIREMENT_OK, + 'description' => t('Profile id: <a href=":url">%profile</a>', ['%profile' => $profile->id(), ':url' => $profile->url()]), + ]; + } + } + return $requirements; +} + +/** + * Implements hook_uninstall(). + * + * Decrypt and purge our data. + */ +function salesforce_encrypt_uninstall() { + \Drupal::service('salesforce.client')->disableEncryption(); + \Drupal::state()->delete('salesforce_encrypt.profile'); +} diff --git a/modules/salesforce_encrypt/salesforce_encrypt.links.menu.yml b/modules/salesforce_encrypt/salesforce_encrypt.links.menu.yml new file mode 100644 index 0000000000000000000000000000000000000000..7825f4241c443285956314e6c9a5f494e33ee884 --- /dev/null +++ b/modules/salesforce_encrypt/salesforce_encrypt.links.menu.yml @@ -0,0 +1,6 @@ +salesforce_encrypt.settings: + route_name: salesforce_encrypt.settings + parent: salesforce.admin_config_salesforce + title: Salesforce Encrypt + description: 'Encrypt sensitive Salesforce OAuth credentials and identity.' + weight: 10 diff --git a/modules/salesforce_encrypt/salesforce_encrypt.module b/modules/salesforce_encrypt/salesforce_encrypt.module index dd18117fefd1794dcdb72fc0ad4310b2641123d4..96658c1fb3a7da24a9bb6c4e700f167be33d0ffa 100644 --- a/modules/salesforce_encrypt/salesforce_encrypt.module +++ b/modules/salesforce_encrypt/salesforce_encrypt.module @@ -6,12 +6,80 @@ */ use Drupal\encrypt\EncryptionProfileInterface; +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Render\Element; +use Drupal\Core\Entity\EntityInterface; /** * Implements hook_encryption_profile_predelete(). * * If the assigned Encryption profile gets deleted, reset encryption settings. */ -function salesforce_encryption_profile_predelete(EncryptionProfileInterface $entity) { +function salesforce_encrypt_encryption_profile_predelete(EncryptionProfileInterface $entity) { \Drupal::service('salesforce.client')->hookEncryptionProfileDelete($entity); } + +/** + * Implements hook_form_alter(). + */ +function salesforce_encrypt_form_salesforce_auth_form_alter(&$form, FormStateInterface $form_state, $form_id) { + /** @var \Drupal\Core\Config\ImmutableConfig $config */ + $config = $form_state->getBuildInfo()['auth_config']; + if (!$config->hasOverrides('provider_settings')) { + return; + } + + foreach (Element::children($form['settings']['provider_settings']) as $key) { + if ($config->hasOverrides("provider_settings.$key")) { + $value = &$form['settings']['provider_settings'][$key]; + $value['#disabled'] = TRUE; + $value['#title'] .= ' <em>' . t('(Overridden)') . '</em>'; + $value['#description'] .= '<br /><strong>' . t('This value is overridden, you cannot edit it here.') . '</strong>'; + } + } +} + +/** + * Implements hook_entity_type_alter(). + */ +function salesforce_encrypt_entity_type_alter(array &$entity_types) { + /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */ + $entity_type = &$entity_types['salesforce_auth']; + $entity_type->setLinkTemplate('encryption', + "/admin/config/salesforce/authorize/encryption/{salesforce_auth}"); + $handlers = $entity_type->getHandlerClasses(); + $handlers['form']['encryption'] = 'Drupal\salesforce_encrypt\Form\SalesforceAuthEncryptForm'; + $entity_type->setHandlerClass('form', $handlers['form']); +} + +/** + * Implements hook_local_tasks_alter(). + */ +function salesforce_encrypt_local_tasks_alter(&$local_tasks) { + // Clone an existing salesforce_auth local task to create our new tab. + $local_tasks['entity.salesforce_auth.encryption'] = + array_merge($local_tasks['entity.salesforce_auth.revoke'], [ + 'route_name' => 'entity.salesforce_auth.encryption', + 'title' => t('Encryption'), + 'base_route' => 'entity.salesforce_auth.edit_form', + 'provider' => 'salesforce_encrypt', + 'id' => 'entity.salesforce_auth.encryption', + ]); + + +} + +/** + * Implements hook_entity_operation(). + */ +function salesforce_encrypt_entity_operation(EntityInterface $entity) { + $operations = []; + if ($entity->getEntityTypeId() == 'salesforce_auth') { + $operations['encryption'] = [ + 'title' => t('Encryption'), + 'weight' => 200, + 'url' => $entity->toUrl('encryption'), + ]; + } + return $operations; +} diff --git a/modules/salesforce_encrypt/salesforce_encrypt.routing.yml b/modules/salesforce_encrypt/salesforce_encrypt.routing.yml new file mode 100644 index 0000000000000000000000000000000000000000..695a223e0e7b08417a818f3817b76eff990d6ae5 --- /dev/null +++ b/modules/salesforce_encrypt/salesforce_encrypt.routing.yml @@ -0,0 +1,17 @@ +salesforce_encrypt.settings: + path: '/admin/config/salesforce/encrypt' + defaults: + _form: '\Drupal\salesforce_encrypt\Form\SettingsForm' + _title: 'Salesforce Encryption' + _description: 'Encrypt sensitive Salesforce OAuth credentials and identity.' + requirements: + _permission: 'administer salesforce encryption' + +entity.salesforce_auth.encryption: + path: '/admin/config/salesforce/authorize/encryption/{salesforce_auth}' + defaults: + _entity_form: 'salesforce_auth.encryption' + requirements: + _permission: 'administer salesforce encryption' + options: + no_cache: TRUE diff --git a/modules/salesforce_encrypt/salesforce_encrypt.services.yml b/modules/salesforce_encrypt/salesforce_encrypt.services.yml new file mode 100644 index 0000000000000000000000000000000000000000..e39a84aa6714857ea45580e4291312bf03274600 --- /dev/null +++ b/modules/salesforce_encrypt/salesforce_encrypt.services.yml @@ -0,0 +1,4 @@ +services: + salesforce_encrypt.service: + class: Drupal\salesforce_encrypt\SalesforceEncrypt + arguments: ['@encrypt.encryption_profile.manager', '@key.config_override', '@config.factory', '@state'] diff --git a/modules/salesforce_encrypt/src/Consumer/OAuthEncryptedCredentials.php b/modules/salesforce_encrypt/src/Consumer/OAuthEncryptedCredentials.php deleted file mode 100644 index 5c0fbded9fb7bc7af2bcf5bb4c1b12bbe7e3fed5..0000000000000000000000000000000000000000 --- a/modules/salesforce_encrypt/src/Consumer/OAuthEncryptedCredentials.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php - -namespace Drupal\salesforce_encrypt\Consumer; - -use Drupal\salesforce\Consumer\SalesforceCredentials; - -/** - * OAuth encrypted creds. - */ -class OAuthEncryptedCredentials extends SalesforceCredentials { - - /** - * Encryption profile id. - * - * @var string - */ - protected $encryptionProfileId; - - /** - * {@inheritdoc} - */ - public function __construct($consumerKey, $loginUrl, $consumerSecret, $encryptionProfileId) { - parent::__construct($consumerKey, $loginUrl, $consumerSecret); - $this->encryptionProfileId = $encryptionProfileId; - } - - /** - * Getter. - * - * @return string - * The encryption profile id. - */ - public function getEncryptionProfileId() { - return $this->encryptionProfileId; - } - -} diff --git a/modules/salesforce_encrypt/src/Form/SalesforceAuthEncryptForm.php b/modules/salesforce_encrypt/src/Form/SalesforceAuthEncryptForm.php new file mode 100644 index 0000000000000000000000000000000000000000..eeae3aec92d937b4528688c82c2d415520d3c77f --- /dev/null +++ b/modules/salesforce_encrypt/src/Form/SalesforceAuthEncryptForm.php @@ -0,0 +1,58 @@ +<?php + +namespace Drupal\salesforce_encrypt\Form; + +use Drupal\Core\Entity\EntityConfirmFormBase; +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; +use Drupal\salesforce\Entity\SalesforceAuthConfig; +use Drupal\salesforce_encrypt\SalesforceEncryptTrait; + +class SalesforceAuthEncryptForm extends EntityConfirmFormBase { + + /** + * {@inheritdoc} + */ + public function getQuestion() { + return $this->t('Encrypt / decrypt Auth Config %name?', ['%name' => $this->entity->label()]); + } + + /** + * {@inheritdoc} + */ + public function getDescription() { + return $this->t('Encryption is currently %status for Auth Config %name.'); + } + + /** + * {@inheritdoc} + */ + public function getCancelUrl() { + return $this->entity->toUrl('collection'); + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return $this->t('Revoke Auth Token'); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + if (!$this->entity instanceof SalesforceAuthConfig) { + return; + } + $this->entity->getPlugin()->revokeAccessToken(); + + // Set a message that the entity was deleted. + $this->messenger()->addStatus($this->t('Auth token for %label was revoked.', [ + '%label' => $this->entity->label(), + ])); + + $form_state->setRedirectUrl($this->getCancelUrl()); + } + +} \ No newline at end of file diff --git a/modules/salesforce_encrypt/src/Form/SettingsForm.php b/modules/salesforce_encrypt/src/Form/SettingsForm.php new file mode 100644 index 0000000000000000000000000000000000000000..4d4d223213b1c32f7b05780e8460fd76b55a1882 --- /dev/null +++ b/modules/salesforce_encrypt/src/Form/SettingsForm.php @@ -0,0 +1,170 @@ +<?php + +namespace Drupal\salesforce_encrypt\Form; + +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Form\FormBase; +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Messenger\MessengerTrait; +use Drupal\Core\State\StateInterface; +use Drupal\encrypt\EncryptionProfileManagerInterface; +use Drupal\salesforce\EntityNotFoundException; +use Drupal\salesforce\Storage\SalesforceAuthTokenStorage; +use Drupal\salesforce_encrypt\SalesforceEncrypt; +use Drupal\salesforce_encrypt\SalesforceEncryptTrait; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Core\Url; + +/** + * Base form for key add and edit forms. + */ +class SettingsForm extends FormBase { + + use MessengerTrait; + + /** + * Profile manager. + * + * @var \Drupal\encrypt\EncryptionProfileManagerInterface + */ + protected $encryptionProfileManager; + + /** + * State service. + * + * @var \Drupal\Core\State\StateInterface + */ + protected $state; + + /** + * Auth token storage service. + * + * @var \Drupal\salesforce\Storage\SalesforceAuthTokenStorage + */ + protected $authTokenStorage; + + /** + * Auth config storage. + * + * @var \Drupal\salesforce_encrypt\Storage\SalesforceEncryptedAuthStorage + */ + protected $authConfigStorage; + + /** + * Salesforce encrypt service. + * + * @var \Drupal\salesforce_encrypt\SalesforceEncrypt + */ + protected $salesforceEncrypt; + + /** + * SettingsForm constructor. + * + * @param \Drupal\Core\State\StateInterface $state + * State service. + * @param \Drupal\encrypt\EncryptionProfileManagerInterface $encryptionProfileManager + * Encryption profile manager service. + */ + public function __construct(StateInterface $state, EncryptionProfileManagerInterface $encryptionProfileManager, SalesforceAuthTokenStorage $authTokenStorage, EntityTypeManagerInterface $etm, SalesforceEncrypt $salesforceEncrypt) { + $this->encryptionProfileManager = $encryptionProfileManager; + $this->state = $state; + $this->authTokenStorage = $authTokenStorage; + $this->authConfigStoage = $etm->getStorage('salesforce_auth'); + $this->salesforceEncrypt = $salesforceEncrypt; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('state'), + $container->get('encrypt.encryption_profile.manager'), + $container->get('salesforce.auth_token_storage'), + $container->get('entity_type.manager'), + $container->get('salesforce_encrypt.service') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'salesforce_encrypt_config'; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $options = $this + ->encryptionProfileManager + ->getEncryptionProfileNamesAsOptions(); + $default = NULL; + try { + /** @var \Drupal\encrypt\EncryptionProfileInterface $profile */ + $profile = $this->salesforceEncrypt->getProfile('salesforce_encrypt.profile'); + if (!empty($profile)) { + $default = $profile->id(); + } + } + catch (EntityNotFoundException $e) { + $this->messenger()->addError($e->getFormattableMessage()); + $this->messenger()->addError($this->t('Error while loading encryption profile. You will need to <a href=":encrypt">assign a new encryption profile</a>, then <a href=":oauth">re-authenticate to Salesforce</a>.', [':encrypt' => Url::fromRoute('salesforce_encrypt.settings')->toString(), ':oauth' => Url::fromRoute('salesforce.authorize')->toString()])); + } + + $form['profile'] = [ + '#type' => 'select', + '#title' => $this->t('Encryption Profile'), + '#description' => $this->t('Choose an encryption profile with which to encrypt Salesforce information.'), + '#options' => $options, + '#default_value' => $default, + '#empty_option' => $this->t('Do not use encryption'), + ]; + + $form['actions']['#type'] = 'actions'; + $form['actions']['submit'] = [ + '#type' => 'submit', + '#value' => $this->t('Save configuration'), + '#button_type' => 'primary', + ]; + + // By default, render the form using system-config-form.html.twig. + $form['#theme'] = 'system_config_form'; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $old_profile_id = $this->state->get('salesforce_encrypt.profile'); + $profile_id = $form_state->getValue('profile'); + + if ($old_profile_id == $profile_id) { + // No change to encryption profile. Do nothing. + return; + } + + $profile = $this + ->encryptionProfileManager + ->getEncryptionProfile($profile_id); + if (empty($profile_id)) { + // New profile id empty: disable encryption. + $this->client->disableEncryption(); + } + elseif (empty($old_profile_id)) { + // Old profile id empty: enable encryption anew. + $this->client->enableEncryption($profile); + } + else { + // Changing encryption profiles: disable, then re-enable. + $this->client->disableEncryption(); + $this->client->enableEncryption($profile); + } + $this->state->resetCache(); + drupal_set_message($this->t('The configuration options have been saved.')); + } + +} diff --git a/modules/salesforce_encrypt/src/Plugin/SalesforceAuthProvider/SalesforceEncryptedOAuthPlugin.php b/modules/salesforce_encrypt/src/Plugin/SalesforceAuthProvider/SalesforceEncryptedOAuthPlugin.php deleted file mode 100644 index 4869e2bfe1f6ee138de1382820830fb8aa2a7f19..0000000000000000000000000000000000000000 --- a/modules/salesforce_encrypt/src/Plugin/SalesforceAuthProvider/SalesforceEncryptedOAuthPlugin.php +++ /dev/null @@ -1,293 +0,0 @@ -<?php - -namespace Drupal\salesforce_encrypt\Plugin\SalesforceAuthProvider; - -use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Routing\TrustedRedirectResponse; -use Drupal\Core\Url; -use Drupal\encrypt\EncryptionProfileInterface; -use Drupal\encrypt\EncryptionProfileManagerInterface; -use Drupal\encrypt\EncryptServiceInterface; -use Drupal\salesforce\EntityNotFoundException; -use Drupal\salesforce\SalesforceAuthProviderPluginBase; -use Drupal\salesforce\SalesforceAuthProviderInterface; -use Drupal\salesforce_encrypt\Consumer\OAuthEncryptedCredentials; -use Drupal\salesforce_encrypt\SalesforceEncryptedAuthTokenStorageInterface; -use OAuth\Common\Http\Client\ClientInterface; -use OAuth\Common\Http\Uri\Uri; -use Symfony\Component\DependencyInjection\ContainerInterface; - -/** - * OAuth provider with encrypted credentials. - * - * @Plugin( - * id = "oauth_encrypted", - * label = @Translation("Salesforce OAuth User-Agent, Encrypted") - * ) - */ -class SalesforceEncryptedOAuthPlugin extends SalesforceAuthProviderPluginBase { - - /** - * OAuth credentials. - * - * @var \Drupal\salesforce\Consumer\SalesforceCredentials - */ - protected $credentials; - - /** - * Encryption profile manager. - * - * @var \Drupal\encrypt\EncryptionProfileManagerInterface - */ - protected $encryptionProfileManager; - - /** - * Encryption service. - * - * @var \Drupal\encrypt\EncryptServiceInterface - */ - protected $encryption; - - /** - * Encryption profile. - * - * @var \Drupal\encrypt\EncryptionProfileInterface - */ - protected $encryptionProfile; - - /** - * Encryption profile id. - * - * @var string - */ - protected $encryptionProfileId; - - /** - * {@inheritdoc} - */ - const SERVICE_TYPE = 'oauth_encrypted'; - - /** - * {@inheritdoc} - */ - const LABEL = 'OAuth Encrypted'; - - /** - * Token storage;. - * - * @var \Drupal\salesforce_encrypt\SalesforceEncryptedAuthTokenStorageInterface - */ - protected $storage; - - /** - * {@inheritdoc} - */ - public function __construct($id, OAuthEncryptedCredentials $credentials, ClientInterface $httpClient, SalesforceEncryptedAuthTokenStorageInterface $storage, EncryptionProfileManagerInterface $encryptionProfileManager, EncryptServiceInterface $encrypt) { - parent::__construct($credentials, $httpClient, $storage, [], new Uri($credentials->getLoginUrl())); - $this->id = $id; - $this->encryptionProfileManager = $encryptionProfileManager; - $this->encryption = $encrypt; - $this->encryptionProfileId = $credentials->getEncryptionProfileId(); - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - $configuration = array_merge(self::defaultConfiguration(), $configuration); - $storage = $container->get('salesforce.auth_token_storage'); - /** @var \Drupal\encrypt\EncryptServiceInterface $encrypt */ - $encrypt = $container->get('encryption'); - $encryptProfileMan = $container->get('encrypt.encryption_profile.manager'); - if ($configuration['encryption_profile']) { - try { - $profile = $encryptProfileMan->getEncryptionProfile($configuration['encryption_profile']); - $configuration['consumer_key'] = $encrypt->decrypt($configuration['consumer_key'], $profile); - $configuration['consumer_secret'] = $encrypt->decrypt($configuration['consumer_secret'], $profile); - } - catch (\Exception $e) { - // Any exception here may cause WSOD, don't allow that to happen. - watchdog_exception('SFOAuthEncrypted', $e); - } - } - $cred = new OAuthEncryptedCredentials($configuration['consumer_key'], $configuration['login_url'], $configuration['consumer_secret'], $configuration['encryption_profile']); - return new static($configuration['id'], $cred, $container->get('salesforce.http_client_wrapper'), $storage, $encryptProfileMan, $encrypt); - } - - /** - * {@inheritdoc} - */ - public static function defaultConfiguration() { - $defaults = parent::defaultConfiguration(); - return array_merge($defaults, [ - 'encryption_profile' => NULL, - ]); - } - - /** - * {@inheritdoc} - */ - public function hookEncryptionProfileDelete(EncryptionProfileInterface $profile) { - if ($this->encryptionProfile()->id() == $profile->id()) { - // @todo decrypt identity, access token, refresh token, consumer secret, consumer key and re-save - } - } - - /** - * {@inheritdoc} - */ - public function encryptionProfile() { - if ($this->encryptionProfile) { - return $this->encryptionProfile; - } - elseif (empty($this->encryptionProfileId)) { - return NULL; - } - else { - $this->encryptionProfile = $this->encryptionProfileManager - ->getEncryptionProfile($this->encryptionProfileId); - if (empty($this->encryptionProfile)) { - throw new EntityNotFoundException(['id' => $this->encryptionProfileId], 'encryption_profile'); - } - return $this->encryptionProfile; - } - } - - /** - * {@inheritdoc} - */ - public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - $options = $this - ->encryptionProfileManager - ->getEncryptionProfileNamesAsOptions(); - $default = NULL; - try { - $profile = $this->encryptionProfile(); - if (!empty($profile)) { - $default = $profile->id(); - } - } - catch (EntityNotFoundException $e) { - $this->messenger()->addError($e->getFormattableMessage()); - $this->messenger()->addError($this->t('Error while loading encryption profile. You will need to assign a new encryption profile and re-authenticate to Salesforce.')); - } - - if (empty($options)) { - $this->messenger()->addError($this->t('Please <a href="@href">create an encryption profile</a> before adding an OAuth Encrypted provider.', ['@href' => Url::fromRoute('entity.encryption_profile.add_form')->toString()])); - } - - $form['consumer_key'] = [ - '#title' => t('Salesforce consumer key'), - '#type' => 'textfield', - '#description' => t('Consumer key of the Salesforce remote application you want to grant access to. VALUE WILL BE ENCRYPTED ON FORM SUBMISSION.'), - '#required' => TRUE, - '#default_value' => $this->credentials->getConsumerKey(), - ]; - - $form['consumer_secret'] = [ - '#title' => $this->t('Salesforce consumer secret'), - '#type' => 'textfield', - '#description' => $this->t('Consumer secret of the Salesforce remote application. VALUE WILL BE ENCRYPTED ON FORM SUBMISSION.'), - '#required' => TRUE, - '#default_value' => $this->credentials->getConsumerSecret(), - ]; - - $form['login_url'] = [ - '#title' => t('Login URL'), - '#type' => 'textfield', - '#default_value' => $this->credentials->getLoginUrl(), - '#description' => t('Enter a login URL, either https://login.salesforce.com or https://test.salesforce.com.'), - '#required' => TRUE, - ]; - $form['encryption_profile'] = [ - '#type' => 'select', - '#title' => $this->t('Encryption Profile'), - '#description' => $this->t('Choose an encryption profile with which to encrypt Salesforce information.'), - '#options' => $options, - '#default_value' => $default, - '#required' => TRUE, - ]; - return $form; - } - - /** - * {@inheritdoc} - */ - public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { - $this->setConfiguration($form_state->getValues()); - $settings = $form_state->getValue('provider_settings'); - $this->encryptionProfileId = $settings['encryption_profile']; - $consumer_key = $settings['consumer_key']; - $settings['consumer_key'] = $this->encrypt($settings['consumer_key']); - $settings['consumer_secret'] = $this->encrypt($settings['consumer_secret']); - $form_state->setValue('provider_settings', $settings); - parent::submitConfigurationForm($form, $form_state); - - // Write the config id to private temp store, so that we can use the same - // callback URL for all OAuth applications in Salesforce. - /** @var \Drupal\Core\TempStore\PrivateTempStore $tempstore */ - $tempstore = \Drupal::service('user.private_tempstore')->get('salesforce_oauth'); - $tempstore->set('config_id', $form_state->getValue('id')); - - try { - $path = $this->getAuthorizationEndpoint(); - $query = [ - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'response_type' => 'code', - 'client_id' => $consumer_key, - ]; - - // Send the user along to the Salesforce OAuth login form. If successful, - // the user will be redirected to {redirect_uri} to complete the OAuth - // handshake, and thence to the entity listing. Upon failure, the user - // redirect URI will send the user back to the edit form. - $response = new TrustedRedirectResponse($path . '?' . http_build_query($query), 302); - $response->send(); - return; - } - catch (\Exception $e) { - $this->messenger()->addError(t("Error during authorization: %message", ['%message' => $e->getMessage()])); - } - } - - /** - * {@inheritdoc} - */ - public function decrypt($value) { - return $this->encryption->decrypt($value, $this->encryptionProfile()); - } - - /** - * {@inheritdoc} - */ - public function encrypt($value) { - return $this->encryption->encrypt($value, $this->encryptionProfile()); - } - - /** - * {@inheritdoc} - */ - public function getConsumerSecret() { - return $this->credentials->getConsumerSecret(); - } - - /** - * {@inheritdoc} - */ - public function finalizeOauth() { - $this->requestAccessToken(\Drupal::request()->get('code')); - $token = $this->getAccessToken(); - - // Initialize identity. - $headers = [ - 'Authorization' => 'OAuth ' . $token->getAccessToken(), - 'Content-type' => 'application/json', - ]; - $data = $token->getExtraParams(); - $response = $this->httpClient->retrieveResponse(new Uri($data['id']), [], $headers); - $identity = $this->parseIdentityResponse($response); - $this->storage->storeIdentity($this->service(), $identity); - return TRUE; - } - -} diff --git a/modules/salesforce_encrypt/src/SalesforceEncrypt.php b/modules/salesforce_encrypt/src/SalesforceEncrypt.php new file mode 100644 index 0000000000000000000000000000000000000000..fb468e940d96397bab94ddd5112326992c3c6891 --- /dev/null +++ b/modules/salesforce_encrypt/src/SalesforceEncrypt.php @@ -0,0 +1,64 @@ +<?php + +namespace Drupal\salesforce_encrypt; + +use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\State\StateInterface; +use Drupal\encrypt\EncryptionProfileManagerInterface; +use Drupal\key\KeyConfigOverrides; +use Drupal\salesforce\Entity\SalesforceAuthConfig; + +class SalesforceEncrypt { + + + + public function __construct(EncryptionProfileManagerInterface $encryptionProfileManager, KeyConfigOverrides $keyConfigOverrides, ConfigFactoryInterface $configFactory, StateInterface $state) { + $this->encryptionProfileManager = $encryptionProfileManager; + $this->keyConfigOverrides = $keyConfigOverrides; + $this->configFactory = $configFactory; + $this->state = $state; + } + + /** + * TRUE if the given authconfig is overridden with encrypted values. + * + * @param \Drupal\salesforce\Entity\SalesforceAuthConfig $authConfig + * The given auth config. + * + * @return bool + * TRUE if the given authconfig is overridden with encrypted values. + */ + public function isEncrypted(SalesforceAuthConfig $auth) { + $config = $this->configFactory->get($auth->getConfigDependencyName()); + // If it's not overridden, we know it's not encrypted. + if (!$config->hasOverrides()) { + return FALSE; + } + // If it's overridden, see if it's an encrypted config. + // @TODO write me + $this->keyConfigOverrides->loadOverrides() + } + + /** + * Get the assigned encryption profile, or NULL. + * + * @return \Drupal\encrypt\EncryptionProfileInterface|NULL + * The assigned encryption profile, or NULL. + */ + public function getProfile() { + $profileId = $this->getProfileId(); + return $this->encryptionProfileManager->getEncryptionProfile($profileId); + } + + /** + * Get the assigned encryption profile id, or NULL. + * + * @return string|NULL + * The assigned encryption profile id, or NULL. + */ + public function getProfileId() { + return $this->state->get('salesforce_encrypt.profile'); + } + + +} \ No newline at end of file diff --git a/modules/salesforce_encrypt/src/SalesforceEncryptServiceProvider.php b/modules/salesforce_encrypt/src/SalesforceEncryptServiceProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..e75e85b08b4d92b5476cbdab97e1ab84a43d3936 --- /dev/null +++ b/modules/salesforce_encrypt/src/SalesforceEncryptServiceProvider.php @@ -0,0 +1,27 @@ +<?php + +namespace Drupal\salesforce_encrypt; + +use Drupal\Core\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Alter the container to include our own storage providers. + */ +class SalesforceEncryptServiceProvider { + + /** + * {@inheritdoc} + */ + public function alter(ContainerBuilder $container) { + // Add a normalizer service for file entities. + $service_definition = new Definition('Drupal\salesforce_encrypt\Storage\SalesforceEncryptedAuthTokenStorage', array( + new Reference('state'), + new Reference('encryption'), + new Reference('encrypt.encryption_profile.manager'), + )); + $container->setDefinition('salesforce.auth_token_storage', $service_definition); + } + +} diff --git a/modules/salesforce_encrypt/src/SalesforceEncryptedAuthTokenStorageInterface.php b/modules/salesforce_encrypt/src/SalesforceEncryptedAuthTokenStorageInterface.php deleted file mode 100644 index 6ff4be197a6c375408d9161a9976cbe9d19d51f2..0000000000000000000000000000000000000000 --- a/modules/salesforce_encrypt/src/SalesforceEncryptedAuthTokenStorageInterface.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php - -namespace Drupal\salesforce_encrypt; - -use Drupal\salesforce\Storage\SalesforceAuthTokenStorageInterface; - -/** - * Encrypted token storage interface. - */ -interface SalesforceEncryptedAuthTokenStorageInterface extends SalesforceAuthTokenStorageInterface { - -} diff --git a/modules/salesforce_encrypt/src/SalesforceEncryptedOAuthPluginInterface.php b/modules/salesforce_encrypt/src/SalesforceEncryptedOAuthPluginInterface.php deleted file mode 100644 index 27a94f22ca80fdde2fd123674b14f3a7c4595b4b..0000000000000000000000000000000000000000 --- a/modules/salesforce_encrypt/src/SalesforceEncryptedOAuthPluginInterface.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php - -namespace Drupal\salesforce_encrypt; - -use Drupal\encrypt\EncryptionProfileInterface; -use Drupal\salesforce\SalesforceOAuthPluginInterface; - -/** - * Encrypted oauth provider interface. - */ -interface SalesforceEncryptedOAuthPluginInterface extends SalesforceOAuthPluginInterface { - - /** - * Callback for hook_encryption_profile_predelete(). - * - * @param \Drupal\encrypt\EncryptionProfileInterface $profile - * The encryption profile being deleted. - */ - public function hookEncryptionProfileDelete(EncryptionProfileInterface $profile); - - /** - * Get the encryption profile assigned to this auth plugin. - * - * @return \Drupal\encrypt\EncryptionProfileInterface|null - * Profile. - */ - public function encryptionProfile(); - - /** - * Decrypt a given value, using the assigned encryption profile. - * - * @param string $value - * The encrypted value. - * - * @return string - * The plain text value. - * - * @throws \Drupal\encrypt\Exception\EncryptException - * On decryption error. - */ - public function decrypt($value); - - /** - * Encrypt a value, using the assigned encryption profile. - * - * @param string $value - * The plain text value. - * - * @return string - * The encrypted value. - * - * @throws \Drupal\encrypt\Exception\EncryptException - * On error. - */ - public function encrypt($value); - -} diff --git a/modules/salesforce_encrypt/src/Storage/SalesforceEncryptedAuthStorage.php b/modules/salesforce_encrypt/src/Storage/SalesforceEncryptedAuthStorage.php new file mode 100644 index 0000000000000000000000000000000000000000..e712e436064685d861804a8b6b4a3fcfa47c2da4 --- /dev/null +++ b/modules/salesforce_encrypt/src/Storage/SalesforceEncryptedAuthStorage.php @@ -0,0 +1,29 @@ +<?php + +namespace Drupal\salesforce_encrypt\Storage; + +use Drupal\Core\Config\Entity\ConfigEntityStorage; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityMalformedException; + +class SalesforceEncryptedAuthStorage extends ConfigEntityStorage { + + /** + * Implements Drupal\Core\Entity\EntityStorageInterface::save(). + * + * @throws EntityMalformedException + * When attempting to save a configuration entity that has no ID. + */ + public function save(EntityInterface $entity) { + // Encrypt the sensitive values and hand off to parent. + return parent::save($entity); + } + + protected function doLoadMultiple(array $ids = NULL) { + $entities = parent::doLoadMultiple($ids); + // Decrypt the sensitive values and return + return $entities; + } + + +} \ No newline at end of file diff --git a/modules/salesforce_encrypt/src/SalesforceEncryptedAuthTokenStorage.php b/modules/salesforce_encrypt/src/Storage/SalesforceEncryptedAuthTokenStorage.php similarity index 72% rename from modules/salesforce_encrypt/src/SalesforceEncryptedAuthTokenStorage.php rename to modules/salesforce_encrypt/src/Storage/SalesforceEncryptedAuthTokenStorage.php index 53252719adc918ff7dfd6e44b19e9cf9565b78c8..7b4bef26c65f307ac7c95a577077c50c891f8b87 100644 --- a/modules/salesforce_encrypt/src/SalesforceEncryptedAuthTokenStorage.php +++ b/modules/salesforce_encrypt/src/Storage/SalesforceEncryptedAuthTokenStorage.php @@ -1,16 +1,14 @@ <?php -namespace Drupal\salesforce_encrypt; +namespace Drupal\salesforce_encrypt\Storage; -use Drupal\salesforce\Entity\SalesforceAuthConfig; use Drupal\salesforce\Storage\SalesforceAuthTokenStorage; -use Drupal\salesforce_encrypt\Plugin\SalesforceAuthProvider\SalesforceEncryptedOAuthPlugin; use OAuth\Common\Token\TokenInterface; /** * Auth token storage, using encryption. */ -class SalesforceEncryptedAuthTokenStorage extends SalesforceAuthTokenStorage implements SalesforceEncryptedAuthTokenStorageInterface { +class SalesforceEncryptedAuthTokenStorage extends SalesforceAuthTokenStorage { /** * Auth plugin manager. @@ -19,23 +17,6 @@ class SalesforceEncryptedAuthTokenStorage extends SalesforceAuthTokenStorage imp */ protected $authPluginManager; - /** - * Given a service id, return the instantiated auth provider plugin. - * - * @param string $service_id - * The service id. - * - * @return \Drupal\salesforce\SalesforceAuthProviderInterface - * The plugin. - */ - protected function service($service_id) { - if (!$this->authPluginManager) { - $this->authPluginManager = \Drupal::service('plugin.manager.salesforce.auth_providers'); - } - $auth = SalesforceAuthConfig::load($service_id); - return $auth->getPlugin(); - } - /** * {@inheritdoc} */ @@ -88,4 +69,8 @@ class SalesforceEncryptedAuthTokenStorage extends SalesforceAuthTokenStorage imp return $identity; } + public function storeAuthorizationState($service, $state) { + return parent::storeAuthorizationState($service, $state); // TODO: Change the autogenerated stub + } + } diff --git a/modules/salesforce_jwt/salesforce_jwt.info.yml b/modules/salesforce_jwt/salesforce_jwt.info.yml index 040a7403776d9e8109fe4d06e7a6f16f3095f976..d5a85f8f7c46d7c7ed514fb1d6a3523616089dd3 100644 --- a/modules/salesforce_jwt/salesforce_jwt.info.yml +++ b/modules/salesforce_jwt/salesforce_jwt.info.yml @@ -4,5 +4,5 @@ description: Provides key-based Salesforce authentication. core: 8.x package: Salesforce dependencies: - - salesforce - - key + - salesforce:salesforce + - key:key diff --git a/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php b/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php index 24f5f6884a925272855a602613144455439c18d8..6e75639b4f654bb6acd43d7af7502b16d5559e84 100644 --- a/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php +++ b/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php @@ -60,11 +60,6 @@ class SalesforceJWTPlugin extends SalesforceAuthProviderPluginBase { $this->id = $id; } - public function getConsumerSecret() { - return parent::getConsumerSecret(); // TODO: Change the autogenerated stub - } - - /** * {@inheritdoc} */ @@ -284,4 +279,11 @@ class SalesforceJWTPlugin extends SalesforceAuthProviderPluginBase { ]; } + /** + * {@inheritdoc} + */ + public function finalizeOauth() { + // Not used. Implemented for interface compatibility only. + } + } diff --git a/modules/salesforce_oauth/src/Plugin/SalesforceAuthProvider/SalesforceOAuthPlugin.php b/modules/salesforce_oauth/src/Plugin/SalesforceAuthProvider/SalesforceOAuthPlugin.php index b6f67cfae320550e4f5c82c38dcbdc4e1f0230a1..dbe6bae8b7543cf383781d2929270e8214496cde 100644 --- a/modules/salesforce_oauth/src/Plugin/SalesforceAuthProvider/SalesforceOAuthPlugin.php +++ b/modules/salesforce_oauth/src/Plugin/SalesforceAuthProvider/SalesforceOAuthPlugin.php @@ -19,8 +19,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * id = "oauth", * label = @Translation("Salesforce OAuth User-Agent") * ) - * - * @deprecated BC legacy auth scheme only. will be removed in 8.x-4.0. */ class SalesforceOAuthPlugin extends SalesforceAuthProviderPluginBase implements SalesforceAuthProviderInterface { diff --git a/salesforce.info.yml b/salesforce.info.yml index c6a3d3f05d2a9799f1d1c2ada1ec48bb183082cc..5efe50b742413824805020456f8bea99d8c9b251 100644 --- a/salesforce.info.yml +++ b/salesforce.info.yml @@ -4,3 +4,5 @@ description: Modules to integrate Drupal and Salesforce package: Salesforce core: 8.x configure: salesforce.admin_config_salesforce +dependencies: + typed_data:typed_data \ No newline at end of file diff --git a/salesforce.install b/salesforce.install index 46da9e73e5121bdb84e8ca777ab42395b20fc4ed..87afd6702c4584fe584dbed7a97794faa573f1ab 100644 --- a/salesforce.install +++ b/salesforce.install @@ -69,13 +69,13 @@ function salesforce_get_auth_provider_requirements() { if (!$authMan->hasProviders()) { $requirements += [ 'description' => t('No auth providers have been created. Please <a href="@href">create an auth provider</a> to connect to Salesforce.', ['@href' => Url::fromRoute('entity.salesforce_auth.add_form')]), - 'severity' => REQUIREMENT_WARNING, + 'severity' => REQUIREMENT_ERROR, ]; } elseif (!$authMan->getConfig()) { $requirements += [ 'description' => t('Default auth provider has not been set. Please <a href="@href">choose an auth provider</a> to connect to Salesforce.', ['@href' => Url::fromRoute('salesforce.auth_config')->toString()]), - 'severity' => REQUIREMENT_WARNING, + 'severity' => REQUIREMENT_ERROR, ]; } else { @@ -84,14 +84,14 @@ function salesforce_get_auth_provider_requirements() { if (!$authMan->getToken()) { $requirements += [ 'description' => $failMessage, - 'severity' => REQUIREMENT_WARNING, + 'severity' => REQUIREMENT_ERROR, ]; } } catch (Exception $e) { $requirements += [ 'description' => $failMessage, - 'severity' => REQUIREMENT_WARNING, + 'severity' => REQUIREMENT_ERROR, ]; } } diff --git a/salesforce.links.action.yml b/salesforce.links.action.yml index f9d6829e9934c6ed3cdccecc7fbc10cc43f545a4..30ba3189d150880043c31c362557f37a0779a675 100644 --- a/salesforce.links.action.yml +++ b/salesforce.links.action.yml @@ -5,10 +5,3 @@ salesforce_auth.add_action: - entity.salesforce_auth.collection - entity.salesforce_auth.edit_form - salesforce.auth_config - -salesforce_auth.list_action: - route_name: entity.salesforce_auth.collection - title: 'Salesforce Auth Provider List' - appears_on: - - entity.salesforce_auth.add_form - - entity.salesforce_auth.edit_form diff --git a/salesforce.links.task.yml b/salesforce.links.task.yml index f2715a9190f5ba9da1b07ccb11ee906f7c18baf0..bcbe6f27eed9b18669ae6af97ed3822570bd0441 100644 --- a/salesforce.links.task.yml +++ b/salesforce.links.task.yml @@ -7,3 +7,18 @@ entity.salesforce_auth.collection: route_name: entity.salesforce_auth.collection base_route: salesforce.auth_config title: 'Providers' + +entity.salesforce_auth.edit_form: + route_name: entity.salesforce_auth.edit_form + base_route: entity.salesforce_auth.edit_form + title: 'Edit' + +entity.salesforce_auth.revoke: + route_name: entity.salesforce_auth.revoke + base_route: entity.salesforce_auth.edit_form + title: 'Revoke' + +entity.salesforce_auth.delete_form: + route_name: entity.salesforce_auth.delete_form + base_route: entity.salesforce_auth.edit_form + title: 'Delete' diff --git a/src/Controller/SalesforceAuthListBuilder.php b/src/Controller/SalesforceAuthListBuilder.php index 0937ebe7643f6b3f0cd4d842910c48810c32c3ad..f40c45f7b3b83142fc98d97e41da0a7072c35b64 100644 --- a/src/Controller/SalesforceAuthListBuilder.php +++ b/src/Controller/SalesforceAuthListBuilder.php @@ -4,6 +4,8 @@ namespace Drupal\salesforce\Controller; use Drupal\Core\Config\Entity\ConfigEntityListBuilder; use Drupal\Core\Entity\EntityInterface; +use Drupal\salesforce\Entity\SalesforceAuthConfig; +use Drupal\salesforce\SalesforceAuthProviderInterface; /** * List builder for salesforce_auth. @@ -20,9 +22,30 @@ class SalesforceAuthListBuilder extends ConfigEntityListBuilder { $row['url'] = $plugin->getLoginUrl(); $row['key'] = substr($plugin->getConsumerKey(), 0, 16) . '...'; $row['type'] = $plugin->label(); + $row['status'] = $plugin->hasAccessToken() ? 'Authorized' : 'Missing'; return $row + parent::buildRow($entity); } + /** + * {@inheritdoc} + */ + public function getDefaultOperations(EntityInterface $entity) { + $operations = parent::getDefaultOperations($entity); + $operations['edit']['title'] = t('Edit / Re-auth'); + if (!$entity instanceof SalesforceAuthConfig + || !$entity->getPlugin()->hasAccessToken() + || !$entity->hasLinkTemplate('revoke')) { + return $operations; + } + // Add a "revoke" action if we have a token. + $operations['revoke'] = [ + 'title' => t('Revoke'), + 'weight' => 20, + 'url' => $this->ensureDestination($entity->toUrl('revoke')), + ]; + return $operations; + } + /** * {@inheritdoc} */ @@ -39,6 +62,9 @@ class SalesforceAuthListBuilder extends ConfigEntityListBuilder { $header['type'] = [ 'data' => $this->t('Auth Type'), ]; + $header['status'] = [ + 'data' => $this->t('Token Status'), + ]; return $header + parent::buildHeader(); } diff --git a/src/Form/SalesforceAuthForm.php b/src/Form/SalesforceAuthForm.php index 21eb56104a391737373ac8b56b5d54f49133bdb3..42bc8fe4e2dc6c3a97d79958a17e20c7f376300f 100644 --- a/src/Form/SalesforceAuthForm.php +++ b/src/Form/SalesforceAuthForm.php @@ -19,11 +19,15 @@ class SalesforceAuthForm extends EntityForm { */ protected $entity; + + /** * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { $auth = $this->entity; + $form_state->setBuildInfo($form_state->getBuildInfo() + + ['auth_config' => $this->config($auth->getConfigDependencyName())]); $form['label'] = [ '#title' => $this->t('Label'), '#type' => 'textfield', diff --git a/src/Form/SalesforceAuthRevokeForm.php b/src/Form/SalesforceAuthRevokeForm.php index a69b21c5086a7fa9fee8c2f0dadb6ef7952960b7..4463ba9a135be0ac8233d2b6c7ba104ca11ed728 100644 --- a/src/Form/SalesforceAuthRevokeForm.php +++ b/src/Form/SalesforceAuthRevokeForm.php @@ -5,13 +5,14 @@ namespace Drupal\salesforce\Form; use Drupal\Core\Entity\EntityConfirmFormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; +use Drupal\salesforce\Entity\SalesforceAuthConfig; -class AuthConfigDeleteForm extends EntityConfirmFormBase { +class SalesforceAuthRevokeForm extends EntityConfirmFormBase { /** * {@inheritdoc} */ public function getQuestion() { - return $this->t('Are you sure you want to delete the Auth Config %name?', ['%name' => $this->entity->label()]); + return $this->t('Are you sure you want to revoke authorization for Auth Config %name?', ['%name' => $this->entity->label()]); } /** @@ -25,17 +26,20 @@ class AuthConfigDeleteForm extends EntityConfirmFormBase { * {@inheritdoc} */ public function getConfirmText() { - return $this->t('Delete'); + return $this->t('Revoke Auth Token'); } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { - $this->entity->delete(); + if (!$this->entity instanceof SalesforceAuthConfig) { + return; + } + $this->entity->getPlugin()->revokeAccessToken(); // Set a message that the entity was deleted. - $this->messenger()->addStatus($this->t('Auth Config %label was deleted.', [ + $this->messenger()->addStatus($this->t('Auth token for %label was revoked.', [ '%label' => $this->entity->label(), ])); diff --git a/src/Rest/RestClient.php b/src/Rest/RestClient.php index c9df7ec1af6cff83f244bf3d707542c010cda5b6..a07f6d41718f7c625446f1a7c6fae598d2b25b16 100644 --- a/src/Rest/RestClient.php +++ b/src/Rest/RestClient.php @@ -217,7 +217,7 @@ class RestClient implements RestClientInterface { * @throws \GuzzleHttp\Exception\RequestException */ protected function apiHttpRequest($url, array $params, $method) { - if (!$this->authManager->getToken()) { + if (!$this->authToken) { throw new \Exception('Missing OAuth Token'); } diff --git a/src/SalesforceAuthProviderInterface.php b/src/SalesforceAuthProviderInterface.php index aee8ea850900a5363e1333613d54999a568305a4..1de98b87ca3180b2e01efce1b0320ad348df98bf 100644 --- a/src/SalesforceAuthProviderInterface.php +++ b/src/SalesforceAuthProviderInterface.php @@ -107,6 +107,13 @@ interface SalesforceAuthProviderInterface extends ServiceInterface, PluginFormIn */ public function hasAccessToken(); + /** + * Clear the access token for this auth provider plugin. + * + * @return $this + */ + public function revokeAccessToken(); + /** * Default configuration for this plugin type. * diff --git a/src/SalesforceAuthProviderPluginBase.php b/src/SalesforceAuthProviderPluginBase.php index a0580ac90b07e29274f152d77442b0bb4930148c..f1d7f4ac9d73494a64f886efa3b3089c973b82bc 100644 --- a/src/SalesforceAuthProviderPluginBase.php +++ b/src/SalesforceAuthProviderPluginBase.php @@ -3,12 +3,14 @@ namespace Drupal\salesforce; use Drupal\Core\DependencyInjection\DependencySerializationTrait; +use Drupal\Core\Form\ConfigFormBaseTrait; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerTrait; use Drupal\Core\StringTranslation\StringTranslationTrait; use OAuth\Common\Http\Exception\TokenResponseException; use OAuth\Common\Http\Uri\Uri; use OAuth\OAuth2\Service\Salesforce; +use Symfony\Component\DependencyInjection\Loader\Configurator\Traits\FactoryTrait; /** * Shared methods for auth providers. @@ -179,6 +181,13 @@ abstract class SalesforceAuthProviderPluginBase extends Salesforce implements Sa return $this->storage->retrieveAccessToken($this->id()); } + /** + * {@inheritdoc} + */ + public function revokeAccessToken() { + return $this->storage->clearToken($this->id()); + } + /** * {@inheritdoc} */