diff --git a/README.txt b/README.txt index f689305..7a02f5a 100644 --- a/README.txt +++ b/README.txt @@ -201,6 +201,17 @@ On the client website: (admin/content/entity_share/pull), and select your remote website, the available channels will be listed and when selecting a channel, the entities exposed on this channel will be available to synchronize. + * Optional Key Module Integration + - https://www.drupal.org/project/key + - https://www.drupal.org/docs/8/modules/key/concepts-and-terminology + Credentials used to authorize pulling from remotes may be more securely stored + using the Key module. Additional optional modules allow the storage in an + external key/value storage service. With only the Key module credentials may + be stored in JSON format in files outside the web root. + 1. Configure Keys: Key types for Entity Share are listed in Key config form + (/admin/config/system/keys). Instructions for each type are shown in the form. + 2. Create a remote and select Key module as the credential provider, then + select the appropriate key. TROUBLESHOOTING diff --git a/modules/entity_share_client/config/schema/entity_share_client.schema.yml b/modules/entity_share_client/config/schema/entity_share_client.schema.yml new file mode 100644 index 0000000..bd4bdb1 --- /dev/null +++ b/modules/entity_share_client/config/schema/entity_share_client.schema.yml @@ -0,0 +1,38 @@ +entity_share_client.remote.*: + type: config_entity + label: 'Remote config' + mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' + url: + type: string + label: 'URL' + auth: + type: mapping + mapping: + pid: + label: 'Plugin ID' + type: string + uuid: + label: 'UUID' + type: string + verified: + label: 'Verified' + type: boolean + data: + type: mapping + label: 'Credential data' + mapping: + credential_provider: + type: string + label: 'Credential provider' + storage_key: + type: string + label: 'Storage key' + +key.type.entity_share_basic_auth: + type: sequence diff --git a/modules/entity_share_client/config/schema/remote.schema.yml b/modules/entity_share_client/config/schema/remote.schema.yml deleted file mode 100644 index cd30b16..0000000 --- a/modules/entity_share_client/config/schema/remote.schema.yml +++ /dev/null @@ -1,19 +0,0 @@ -entity_share_client.remote.*: - type: config_entity - label: 'Remote config' - mapping: - id: - type: string - label: 'ID' - label: - type: label - label: 'Label' - url: - type: string - label: 'URL' - basic_auth_username: - type: string - label: 'Basic auth username' - basic_auth_password: - type: string - label: 'Basic auth password' diff --git a/modules/entity_share_client/entity_share_client.install b/modules/entity_share_client/entity_share_client.install index 242ec0b..ff0fab1 100644 --- a/modules/entity_share_client/entity_share_client.install +++ b/modules/entity_share_client/entity_share_client.install @@ -40,3 +40,34 @@ function entity_share_client_update_8302() { ], ])); } + +/** + * Move any basic auth credentials stored in configuration into the new plugin. + */ +function entity_share_client_update_8303() { + /** @var \Drupal\entity_share_client\Plugin\ClientAuthorizationManager $manager */ + $manager = \Drupal::service('plugin.manager.entity_share_auth'); + $state = \Drupal::state(); + // Iterate remotes. + /** @var \Drupal\entity_share_client\Entity\Remote[] $remotes */ + $remotes = Remote::loadMultiple(); + foreach ($remotes as $remote) { + /** @var \Drupal\entity_share_client\Plugin\ClientAuthorization\BasicAuth $plugin */ + $plugin = $manager->createInstance('basic_auth'); + $configuration = $plugin->getConfiguration(); + $credentials = []; + $credentials['username'] = $remote->get('basic_auth_username'); + $credentials['password'] = $remote->get('basic_auth_password'); + unset($remote->basic_auth_username); + unset($remote->basic_auth_password); + $state->set($configuration['uuid'], $credentials); + $key = $configuration['uuid']; + $configuration['data'] = [ + 'credential_provider' => 'entity_share', + 'storage_key' => $key, + ]; + $plugin->setConfiguration($configuration); + $remote->mergePluginConfig($plugin); + $remote->save(); + } +} diff --git a/modules/entity_share_client/entity_share_client.services.yml b/modules/entity_share_client/entity_share_client.services.yml index 2fb5a23..d4cd492 100644 --- a/modules/entity_share_client/entity_share_client.services.yml +++ b/modules/entity_share_client/entity_share_client.services.yml @@ -18,7 +18,6 @@ services: entity_share_client.remote_manager: class: Drupal\entity_share_client\Service\RemoteManager arguments: - - '@http_client_factory' - '@logger.channel.entity_share_client' entity_share_client.import_service: @@ -67,3 +66,13 @@ services: arguments: - '@string_translation' - '@entity_share_client.import_service' + + entity_share_client.key_provider: + class: Drupal\entity_share_client\Service\KeyProvider + arguments: ['@state'] + calls: + - [setKeyRepository, ['@?key.repository']] + + plugin.manager.entity_share_auth: + class: Drupal\entity_share_client\Plugin\ClientAuthorizationManager + parent: default_plugin_manager diff --git a/modules/entity_share_client/src/Annotation/ClientAuthorization.php b/modules/entity_share_client/src/Annotation/ClientAuthorization.php new file mode 100644 index 0000000..8a8a5b2 --- /dev/null +++ b/modules/entity_share_client/src/Annotation/ClientAuthorization.php @@ -0,0 +1,41 @@ +auth; + if (!empty($pluginData['pid'])) { + // DI not available in entities: + // https://www.drupal.org/project/drupal/issues/2142515. + /** @var \Drupal\entity_share_client\Plugin\ClientAuthorizationManager $manager */ + $manager = \Drupal::service('plugin.manager.entity_share_auth'); + $pluginId = $pluginData['pid']; + unset($pluginData['pid']); + return $manager->createInstance($pluginId, $pluginData); + } + return NULL; + } + + /** + * {@inheritdoc} + */ + public function mergePluginConfig(ClientAuthorizationInterface $plugin) { + $auth = ['pid' => $plugin->getPluginId()] + + $plugin->getConfiguration(); + $this->auth = $auth; + } + + /** + * {@inheritdoc} + */ + public function getHttpClient(bool $json) { + $plugin = $this->getAuthPlugin(); + if ($json) { + return $plugin->getJsonApiClient($this->url); + } + return $plugin->getClient($this->url); + } + } diff --git a/modules/entity_share_client/src/Entity/RemoteInterface.php b/modules/entity_share_client/src/Entity/RemoteInterface.php index 77d1147..e667f5f 100644 --- a/modules/entity_share_client/src/Entity/RemoteInterface.php +++ b/modules/entity_share_client/src/Entity/RemoteInterface.php @@ -5,11 +5,40 @@ declare(strict_types = 1); namespace Drupal\entity_share_client\Entity; use Drupal\Core\Config\Entity\ConfigEntityInterface; +use Drupal\entity_share_client\Plugin\ClientAuthorizationInterface; /** * Provides an interface for defining Remote entities. */ interface RemoteInterface extends ConfigEntityInterface { - // Add get/set methods for your configuration properties here. + /** + * Copies plugin specific data into the Remote. + * + * @param \Drupal\entity_share_client\Plugin\ClientAuthorizationInterface $plugin + * The authorization plugin to merge. + */ + public function mergePluginConfig(ClientAuthorizationInterface $plugin); + + /** + * Helper method to instantiate auth plugin from this entity. + * + * @return \Drupal\entity_share_client\Plugin\ClientAuthorizationInterface|null + * The plugin if it is defined. + * + * @throws \Drupal\Component\Plugin\Exception\PluginException + */ + public function getAuthPlugin(); + + /** + * Prepares a client object with options pulled from the auth plugin. + * + * @param bool $json + * Is this client for JSON operations? + * + * @return \GuzzleHttp\Client + * The configured client. + */ + public function getHttpClient(bool $json); + } diff --git a/modules/entity_share_client/src/Form/RemoteForm.php b/modules/entity_share_client/src/Form/RemoteForm.php index 397077b..14077d1 100644 --- a/modules/entity_share_client/src/Form/RemoteForm.php +++ b/modules/entity_share_client/src/Form/RemoteForm.php @@ -7,6 +7,9 @@ namespace Drupal\entity_share_client\Form; use Drupal\Component\Utility\UrlHelper; use Drupal\Core\Entity\EntityForm; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Form\SubformState; +use Drupal\entity_share_client\Plugin\ClientAuthorizationInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Class RemoteForm. @@ -15,6 +18,29 @@ use Drupal\Core\Form\FormStateInterface; */ class RemoteForm extends EntityForm { + /** + * Injected plugin service. + * + * @var \Drupal\entity_share_client\Plugin\ClientAuthorizationManager + */ + protected $authPluginManager; + + /** + * The currently configured auth plugin. + * + * @var \Drupal\entity_share_client\Plugin\ClientAuthorizationInterface + */ + protected $authPlugin; + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + $instance = parent::create($container); + $instance->authPluginManager = $container->get('plugin.manager.entity_share_auth'); + return $instance; + } + /** * {@inheritdoc} */ @@ -36,6 +62,7 @@ class RemoteForm extends EntityForm { '#type' => 'machine_name', '#default_value' => $remote->id(), '#machine_name' => [ + 'source' => ['label'], 'exists' => '\Drupal\entity_share_client\Entity\Remote::load', ], '#disabled' => !$remote->isNew(), @@ -50,23 +77,7 @@ class RemoteForm extends EntityForm { '#required' => TRUE, ]; - $form['basic_auth'] = [ - '#type' => 'fieldset', - '#title' => $this->t('Basic Auth'), - ]; - - $form['basic_auth']['basic_auth_username'] = [ - '#type' => 'textfield', - '#title' => $this->t('Username'), - '#default_value' => $remote->get('basic_auth_username'), - '#required' => TRUE, - ]; - - $form['basic_auth']['basic_auth_password'] = [ - '#type' => 'password', - '#title' => $this->t('Password'), - '#required' => TRUE, - ]; + $this->addAuthOptions($form, $form_state); return $form; } @@ -79,6 +90,22 @@ class RemoteForm extends EntityForm { if (!UrlHelper::isValid($form_state->getValue('url'), TRUE)) { $form_state->setError($form['url'], $this->t('Invalid URL.')); } + $selectedPlugin = $this->getSelectedPlugin($form, $form_state); + $subformState = SubformState::createForSubform($form['auth']['data'], $form, $form_state); + $selectedPlugin->validateConfigurationForm($form['auth']['data'], $subformState); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + parent::submitForm( + $form, + $form_state + ); + $selectedPlugin = $this->getSelectedPlugin($form, $form_state); + $subformState = SubformState::createForSubform($form['auth']['data'], $form, $form_state); + $selectedPlugin->submitConfigurationForm($form['auth']['data'], $subformState); } /** @@ -87,6 +114,12 @@ class RemoteForm extends EntityForm { public function save(array $form, FormStateInterface $form_state) { /** @var \Drupal\entity_share_client\Entity\RemoteInterface $remote */ $remote = $this->entity; + + if (!empty($form['auth']['#plugins'])) { + $selectedPlugin = $this->getSelectedPlugin($form, $form_state); + $remote->mergePluginConfig($selectedPlugin); + } + $status = $remote->save(); switch ($status) { @@ -104,4 +137,91 @@ class RemoteForm extends EntityForm { $form_state->setRedirectUrl($remote->toUrl('collection')); } + /** + * Helper function to build the authorization options in the form. + * + * @param array $form + * The form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current form state. + * + * @throws \Drupal\Component\Plugin\Exception\PluginException + */ + protected function addAuthOptions(array &$form, FormStateInterface $form_state) { + $options = []; + $plugins = []; + if ($this->getAuthPlugin()) { + $options[$this->authPlugin->getPluginId()] = $this->authPlugin->getLabel(); + $plugins[$this->authPlugin->getPluginId()] = $this->authPlugin; + } + $availableTypes = $this->authPluginManager->getDefinitions(); + foreach ($availableTypes as $definition) { + if (empty($options[$definition['id']])) { + // This plugin type was not previously set as an option. + /** @var \Drupal\entity_share_client\Plugin\ClientAuthorizationInterface $plugin */ + $plugin = $this->authPluginManager->createInstance($definition['id']); + $plugins[$plugin->getPluginId()] = $plugin; + $options[$plugin->getPluginId()] = $plugin->getLabel(); + } + } + // If we still don't have an auth plugin, use the first option. + if (empty($this->authPlugin)) { + $this->authPlugin = reset($plugins); + } + $form['auth'] = [ + '#type' => 'container', + '#plugins' => $plugins, + 'pid' => [ + '#type' => 'radios', + '#title' => $this->t('Authorization methods'), + '#options' => $options, + '#default_value' => $this->authPlugin->getPluginId(), + ], + 'data' => [], + ]; + $subformState = SubformState::createForSubform($form['auth']['data'], $form, $form_state); + $form['auth']['data'] = $this->authPlugin->buildConfigurationForm($form['auth']['data'], $subformState); + $form['auth']['data']['#tree'] = TRUE; + } + + /** + * Helper method to instantiate plugin from this entity. + * + * @return bool + * The Remote entity has a plugin. + * + * @throws \Drupal\Component\Plugin\Exception\PluginException + */ + protected function getAuthPlugin() { + /** @var \Drupal\entity_share_client\Entity\RemoteInterface $remote */ + $remote = $this->entity; + $plugin = $remote->getAuthPlugin(); + if ($plugin instanceof ClientAuthorizationInterface) { + $this->authPlugin = $plugin; + return TRUE; + } + return FALSE; + } + + /** + * Helper method to get selected plugin from the form. + * + * @param array $form + * The form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current form state. + * + * @return \Drupal\entity_share_client\Plugin\ClientAuthorizationInterface + * The selected plugin. + */ + protected function getSelectedPlugin( + array &$form, + FormStateInterface $form_state) { + $authPluginId = $form_state->getValue('pid'); + $plugins = $form['auth']['#plugins']; + /** @var \Drupal\entity_share_client\Plugin\ClientAuthorizationInterface $selectedPlugin */ + $selectedPlugin = $plugins[$authPluginId]; + return $selectedPlugin; + } + } diff --git a/modules/entity_share_client/src/Plugin/ClientAuthorization/BasicAuth.php b/modules/entity_share_client/src/Plugin/ClientAuthorization/BasicAuth.php new file mode 100644 index 0000000..a3da4e7 --- /dev/null +++ b/modules/entity_share_client/src/Plugin/ClientAuthorization/BasicAuth.php @@ -0,0 +1,95 @@ +keyService->getCredentials($this); + $http_client = $this->httpClientFactory->fromOptions([ + 'base_uri' => $url . '/', + 'cookies' => TRUE, + 'allow_redirects' => TRUE, + ]); + + $http_client->post('/user/login', [ + 'form_params' => [ + 'name' => $credentials['username'], + 'pass' => $credentials['password'], + 'form_id' => 'user_login_form', + ], + ]); + + return $http_client; + } + + /** + * {@inheritdoc} + */ + public function getJsonApiClient($url) { + $credentials = $this->keyService->getCredentials($this); + return $this->httpClientFactory->fromOptions([ + 'base_uri' => $url . '/', + 'auth' => [ + $credentials['username'], + $credentials['password'], + ], + 'headers' => [ + 'Content-type' => 'application/vnd.api+json', + ], + ]); + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm( + array $form, + FormStateInterface $form_state + ) { + $form = parent::buildConfigurationForm($form, $form_state); + + $credentials = $this->keyService->getCredentials($this); + $form['entity_share']['username'] = [ + '#type' => 'textfield', + '#required' => FALSE, + '#title' => $this->t('Username'), + '#default_value' => isset($credentials['username']) ? $credentials['username'] : '', + ]; + + $form['entity_share']['password'] = [ + '#type' => 'textfield', + '#required' => FALSE, + '#title' => $this->t('Password'), + '#default_value' => isset($credentials['password']) ? $credentials['password'] : '', + ]; + if ($this->keyService->additionalProviders()) { + $this->expandedProviderOptions($form); + $form['key']['id']['#key_filters'] = ['type' => 'entity_share_basic_auth']; + $form['key']['id']['#description'] = $this->t('Select the key you have configured to hold the Basic Auth credentials.'); + } + return $form; + } + +} diff --git a/modules/entity_share_client/src/Plugin/ClientAuthorizationBase.php b/modules/entity_share_client/src/Plugin/ClientAuthorizationBase.php new file mode 100644 index 0000000..ca62331 --- /dev/null +++ b/modules/entity_share_client/src/Plugin/ClientAuthorizationBase.php @@ -0,0 +1,275 @@ +keyService = $keyProvider; + $this->state = $state; + $this->uuid = $uuid; + $this->httpClientFactory = $clientFactory; + $this->setConfiguration($configuration); + } + + /** + * {@inheritdoc} + */ + public static function create( + ContainerInterface $container, + array $configuration, + $plugin_id, + $plugin_definition + ) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('entity_share_client.key_provider'), + $container->get('state'), + $container->get('uuid'), + $container->get('http_client_factory') + ); + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return [ + 'uuid' => $this->uuid->generate(), + 'verified' => FALSE, + 'data' => [], + ]; + } + + /** + * {@inheritdoc} + */ + public function getConfiguration() { + return $this->configuration; + } + + /** + * {@inheritdoc} + */ + public function setConfiguration(array $configuration) { + $this->configuration = NestedArray::mergeDeep( + $this->defaultConfiguration(), + $configuration + ); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCredentialProvider() { + $configuration = $this->getConfiguration(); + return $configuration['data']['credential_provider'] ?? NULL; + } + + /** + * {@inheritdoc} + */ + public function getStorageKey() { + $configuration = $this->getConfiguration(); + return $configuration['data']['storage_key'] ?? NULL; + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm( + array $form, + FormStateInterface $form_state + ) { + return $form + [ + 'credential_provider' => [ + '#type' => 'hidden', + '#value' => 'entity_share', + ], + 'entity_share' => [ + '#type' => 'fieldset', + '#title' => $this->t('Stored in local State'), + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function getLabel() { + return $this->pluginDefinition['label']; + } + + /** + * Helper method to build the credential provider elements of the form. + * + * @param array $form + * The configuration form. + */ + protected function expandedProviderOptions(array &$form) { + $provider = $this->getCredentialProvider(); + // Provide selectors for the api key credential provider. + $form['credential_provider'] = [ + '#type' => 'select', + '#title' => $this->t('Credential provider'), + '#default_value' => empty($provider) ? 'entity_share' : $provider, + '#options' => [ + 'entity_share' => 'Local Storage', + 'key' => 'Key Module', + ], + '#attributes' => [ + 'data-states-selector' => 'provider', + ], + '#weight' => -99, + ]; + $form['entity_share']['#states'] = [ + 'required' => [ + ':input[data-states-selector="provider"]' => ['value' => 'entity_share'], + ], + 'visible' => [ + ':input[data-states-selector="provider"]' => ['value' => 'entity_share'], + ], + 'enabled' => [ + ':input[data-states-selector="provider"]' => ['value' => 'entity_share'], + ], + ]; + $key_id = $provider == 'key' ? $this->getStorageKey() : ''; + $form['key'] = [ + '#type' => 'fieldset', + '#title' => $this->t('Managed by Key module'), + '#states' => [ + 'required' => [ + ':input[data-states-selector="provider"]' => ['value' => 'key'], + ], + 'visible' => [ + ':input[data-states-selector="provider"]' => ['value' => 'key'], + ], + 'enabled' => [ + ':input[data-states-selector="provider"]' => ['value' => 'key'], + ], + ], + ]; + $form['key']['id'] = [ + '#type' => 'key_select', + '#title' => $this->t('Select a Stored Key'), + '#default_value' => $key_id, + '#empty_option' => $this->t('- Please select -'), + ]; + } + + /** + * {@inheritdoc} + */ + public function validateConfigurationForm( + array &$form, + FormStateInterface $form_state + ) { + $values = $form_state->getValues(); + if (empty($values['credential_provider'])) { + $form_state->setError( + $form['credential_provider'], + 'A credential provider is required.' + ); + } + else { + $provider = $values['credential_provider']; + foreach ($values[$provider] as $key => $value) { + if (empty($value)) { + $form_state->setError( + $form[$provider][$key], + 'All credential values are required.' + ); + } + } + } + + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm( + array &$form, + FormStateInterface $form_state + ) { + $key = NULL; + $values = $form_state->getValues(); + $configuration = $this->getConfiguration(); + $provider = $values['credential_provider']; + $credentials = $values[$provider]; + switch ($provider) { + case 'entity_share': + $this->state->set($configuration['uuid'], $credentials); + $key = $configuration['uuid']; + break; + + case 'key': + $this->state->delete($configuration['uuid']); + $key = $credentials['id']; + break; + + } + $configuration['data'] = [ + 'credential_provider' => $provider, + 'storage_key' => $key, + ]; + $this->setConfiguration($configuration); + } + +} diff --git a/modules/entity_share_client/src/Plugin/ClientAuthorizationInterface.php b/modules/entity_share_client/src/Plugin/ClientAuthorizationInterface.php new file mode 100644 index 0000000..4c7ed5e --- /dev/null +++ b/modules/entity_share_client/src/Plugin/ClientAuthorizationInterface.php @@ -0,0 +1,70 @@ +alterInfo('entity_share_client_entity_share_auth_info'); + $this->setCacheBackend($cache_backend, 'entity_share_client_entity_share_auth_plugins'); + } + +} diff --git a/modules/entity_share_client/src/Plugin/KeyType/EntityShareBasicAuth.php b/modules/entity_share_client/src/Plugin/KeyType/EntityShareBasicAuth.php new file mode 100644 index 0000000..02017e4 --- /dev/null +++ b/modules/entity_share_client/src/Plugin/KeyType/EntityShareBasicAuth.php @@ -0,0 +1,29 @@ +
{
"username": "username value",
"password": "password value"
}
"), + * group = "authentication", + * key_value = { + * "plugin" = "textarea_field" + * }, + * multivalue = { + * "enabled" = true, + * "fields" = { + * "username" = @Translation("Username"), + * "password" = @Translation("Password") + * } + * } + * ) + */ +class EntityShareBasicAuth extends AuthenticationMultivalueKeyType { + +} diff --git a/modules/entity_share_client/src/Service/KeyProvider.php b/modules/entity_share_client/src/Service/KeyProvider.php new file mode 100644 index 0000000..b0bf7c5 --- /dev/null +++ b/modules/entity_share_client/src/Service/KeyProvider.php @@ -0,0 +1,94 @@ +state = $state; + } + + /** + * Provides a means to our services.yml file to conditionally inject service. + * + * @param \Drupal\key\KeyRepositoryInterface $repository + * The injected service, if it exists. + * + * @see maw_luminate.services.yml + */ + public function setKeyRepository(KeyRepositoryInterface $repository) { + $this->keyRepository = $repository; + } + + /** + * Detects if key module service was injected. + * + * @return bool + * True if the KeyRepository is present. + */ + public function additionalProviders() { + return $this->keyRepository instanceof KeyRepositoryInterface; + } + + /** + * Get the provided credentials. + * + * @param \Drupal\entity_share_client\Plugin\ClientAuthorizationInterface $plugin + * An authorization plugin. + * + * @return array|string + * The value of the configured key. + */ + public function getCredentials(ClientAuthorizationInterface $plugin) { + $provider = $plugin->getCredentialProvider(); + $credentials = []; + if (empty($provider)) { + return $credentials; + } + switch ($provider) { + case 'key': + $keyEntity = $this->keyRepository->getKey($plugin->getStorageKey()); + if ($keyEntity instanceof Key) { + // A key was found in the repository. + $credentials = $keyEntity->getKeyValues(); + } + break; + + default: + $credentials = $this->state->get($plugin->getStorageKey()); + } + + return $credentials; + } + +} diff --git a/modules/entity_share_client/src/Service/RemoteManager.php b/modules/entity_share_client/src/Service/RemoteManager.php index 8c21bda..f91868c 100644 --- a/modules/entity_share_client/src/Service/RemoteManager.php +++ b/modules/entity_share_client/src/Service/RemoteManager.php @@ -5,7 +5,6 @@ declare(strict_types = 1); namespace Drupal\entity_share_client\Service; use Drupal\Component\Serialization\Json; -use Drupal\Core\Http\ClientFactory; use Drupal\entity_share_client\Entity\RemoteInterface; use GuzzleHttp\ClientInterface; use GuzzleHttp\Exception\ClientException; @@ -21,11 +20,18 @@ use Psr\Log\LoggerInterface; class RemoteManager implements RemoteManagerInterface { /** - * The HTTP client factory. + * A constant to document the call for a standard client. * - * @var \Drupal\Core\Http\ClientFactory + * @var bool */ - protected $httpClientFactory; + const STANDARD_CLIENT = FALSE; + + /** + * A constant to document the call for a JSON:API client. + * + * @var bool + */ + const JSON_API_CLIENT = TRUE; /** * Logger. @@ -58,16 +64,10 @@ class RemoteManager implements RemoteManagerInterface { /** * RemoteManager constructor. * - * @param \Drupal\Core\Http\ClientFactory $http_client_factory - * The HTTP client factory. * @param \Psr\Log\LoggerInterface $logger * The logger service. */ - public function __construct( - ClientFactory $http_client_factory, - LoggerInterface $logger - ) { - $this->httpClientFactory = $http_client_factory; + public function __construct(LoggerInterface $logger) { $this->logger = $logger; } @@ -129,21 +129,7 @@ class RemoteManager implements RemoteManagerInterface { protected function getHttpClient(RemoteInterface $remote) { $remote_id = $remote->id(); if (!isset($this->httpClients[$remote_id])) { - $http_client = $this->httpClientFactory->fromOptions([ - 'base_uri' => $remote->get('url') . '/', - 'cookies' => TRUE, - 'allow_redirects' => TRUE, - ]); - - $http_client->post('user/login', [ - 'form_params' => [ - 'name' => $remote->get('basic_auth_username'), - 'pass' => $remote->get('basic_auth_password'), - 'form_id' => 'user_login_form', - ], - ]); - - $this->httpClients[$remote_id] = $http_client; + $this->httpClients[$remote_id] = $remote->getHttpClient(self::STANDARD_CLIENT); } return $this->httpClients[$remote_id]; @@ -155,16 +141,7 @@ class RemoteManager implements RemoteManagerInterface { protected function getJsonApiHttpClient(RemoteInterface $remote) { $remote_id = $remote->id(); if (!isset($this->jsonApiHttpClients[$remote_id])) { - $this->jsonApiHttpClients[$remote_id] = $this->httpClientFactory->fromOptions([ - 'base_uri' => $remote->get('url') . '/', - 'auth' => [ - $remote->get('basic_auth_username'), - $remote->get('basic_auth_password'), - ], - 'headers' => [ - 'Content-type' => 'application/vnd.api+json', - ], - ]); + $this->jsonApiHttpClients[$remote_id] = $remote->getHttpClient(self::JSON_API_CLIENT); } return $this->jsonApiHttpClients[$remote_id];