diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d8a7996 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +composer.lock +vendor/ diff --git a/.markdownlintrc b/.markdownlintrc new file mode 100644 index 0000000..be08e16 --- /dev/null +++ b/.markdownlintrc @@ -0,0 +1,19 @@ +{ + // @see https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.jsonc + // https://github.com/DavidAnson/markdownlint/blob/main/doc/md013.md + "MD013": { + // Exclude code blocks + "code_blocks": false, + "line_length": 120 + }, + + // Prevent complaining on duplicated headings in CHANGELOG.md + // https://github.com/DavidAnson/markdownlint/blob/main/doc/md024.md + "MD024": { + "siblings_only": true + } +} + +// Local Variables: +// mode: json +// End: diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..94c2b25 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +* [PR-13](https://github.com/OS2web/os2web_datalookup/pull/13) + Added support for [os2web_key](https://github.com/OS2web/os2web_key) + +[Unreleased]: https://github.com/itk-dev/os2web_datalookup diff --git a/README.md b/README.md index bde9d52..87ccae9 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,26 @@ # OS2Web Data lookup [![Build Status](https://travis-ci.org/OS2web/os2web_datalookup.svg?branch=8.x)](https://travis-ci.org/OS2web/os2web_datalookup) + ## Install OS2Web Data lookup provides integration with Danish data lookup services such as Service platformen or Datafordeler. Module is available to download via composer. -``` + +```shell composer require os2web/os2web_datalookup drush en os2web_datalookup ``` ## Update + Updating process for OS2Web Data lookup module is similar to usual Drupal 8 module. Use Composer's built-in command for listing packages that have updates available: -``` +```shell composer outdated os2web/os2web_datalookup ``` ## Automated testing and code quality + See [OS2Web testing and CI information](https://github.com/OS2Web/docs#testing-and-ci) ## Contribution @@ -28,14 +32,16 @@ For issue description there is expected that you will provide clear and sufficient information about your feature request or bug report. ### Code review policy + See [OS2Web code review policy](https://github.com/OS2Web/docs#code-review) ### Git name convention + See [OS2Web git name convention](https://github.com/OS2Web/docs#git-guideline) ### Using services in other modules -``` +```php // CVR lookup /** @var \Drupal\os2web_datalookup\Plugin\DataLookupManager $pluginManager */ $pluginManager = \Drupal::service('plugin.manager.os2web_datalookup'); @@ -66,7 +72,7 @@ if ($cprPlugin->isReady()) { ## New services/features -### Datafordeler integration (https://datafordeler.dk) +### Datafordeler integration () In scope of os2forms project already implemented light integration with Danmarks Adresseregister (DAR) via fetching data for form elements @@ -76,7 +82,9 @@ As soon as it is clear how the integration is going to be used, then os2forms_dawa will be refactored to OS2Web Data lookup plugin plugin. ## Important notes + ### Serviceplatformen plugins + Settings for CPR and CVR serviceplantormen plugins are storing as configuration in db and will(could) be exported as `yml` file via Drupal configuration management system. And afterwards could be tracked by `git`. @@ -87,3 +95,37 @@ will be exposed for third persons. To avoid/prevent this behavior we recommend use `Config ignore` module, where you can add all settings you do not want to export/import via configuration management system. + +## Coding standards + +Our coding are checked by GitHub Actions (cf. +[.github/workflows/pr.yml](.github/workflows/pr.yml)). Use the commands below to +run the checks locally. + +### PHP + +```shell +docker run --rm --volume ${PWD}:/app --workdir /app itkdev/php8.1-fpm composer install +# Fix (some) coding standards issues +docker run --rm --volume ${PWD}:/app --workdir /app itkdev/php8.1-fpm composer coding-standards-apply +# Check that code adheres to the coding standards +docker run --rm --volume ${PWD}:/app --workdir /app itkdev/php8.1-fpm composer coding-standards-check +``` + +### Markdown + +```shell +docker run --rm --volume $PWD:/md peterdavehello/markdownlint markdownlint --ignore vendor --ignore LICENSE.md '**/*.md' --fix +docker run --rm --volume $PWD:/md peterdavehello/markdownlint markdownlint --ignore vendor --ignore LICENSE.md '**/*.md' +``` + +## Code analysis + +We use [PHPStan](https://phpstan.org/) for static code analysis. + +Running statis code analysis on a standalone Drupal module is a bit tricky, so we use a helper script to run the +analysis: + +```shell +docker run --rm --volume ${PWD}:/app --workdir /app itkdev/php8.1-fpm ./scripts/code-analysis +``` diff --git a/composer.json b/composer.json index bc478a1..e2b087c 100644 --- a/composer.json +++ b/composer.json @@ -1,12 +1,19 @@ { "name": "os2web/os2web_datalookup", - "type": "drupal-module", "description": "Provides integration with Danish data lookup services such as Service platformen or Datafordeler.", - "minimum-stability": "dev", - "prefer-stable": true, "license": "EUPL-1.2", + "type": "drupal-module", "require": { - "ext-soap": "*" + "ext-soap": "*", + "os2web/os2web_key": "^1.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "*", + "drupal/coder": "*", + "ergebnis/composer-normalize": "^2.42", + "mglaman/phpstan-drupal": "*", + "phpstan/extension-installer": "*", + "phpstan/phpstan-deprecation-rules": "*" }, "repositories": { "drupal": { @@ -17,5 +24,33 @@ "type": "composer", "url": "https://asset-packagist.org" } + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "allow-plugins": { + "cweagans/composer-patches": true, + "dealerdirect/phpcodesniffer-composer-installer": true, + "ergebnis/composer-normalize": true, + "phpstan/extension-installer": true, + "simplesamlphp/composer-module-installer": true, + "vaimo/composer-patches": true, + "zaporylie/composer-drupal-optimizations": true + }, + "sort-packages": true + }, + "scripts": { + "coding-standards-apply": [ + "@coding-standards-apply/phpcs" + ], + "coding-standards-apply/phpcs": [ + "phpcbf --standard=phpcs.xml.dist" + ], + "coding-standards-check": [ + "@coding-standards-check/phpcs" + ], + "coding-standards-check/phpcs": [ + "phpcs --standard=phpcs.xml.dist" + ] } } diff --git a/os2web_datalookup.info.yml b/os2web_datalookup.info.yml index 3ee2322..4c3660e 100644 --- a/os2web_datalookup.info.yml +++ b/os2web_datalookup.info.yml @@ -3,3 +3,6 @@ type: module description: 'Provides integration with Danish data lookup services such as Service platformen or Datafordeler.' package: 'OS2web' core_version_requirement: ^8 || ^9 || ^10 + +dependencies: + - os2web_key:os2web_key diff --git a/os2web_datalookup.install b/os2web_datalookup.install index 2ef175e..cebd80a 100755 --- a/os2web_datalookup.install +++ b/os2web_datalookup.install @@ -28,3 +28,12 @@ function os2web_datalookup_update_9003() { $config->set("pnumber_lookup.default_plugin", 'datafordeler_pnumber'); $config->save(); } + +/** + * Implements hook_update_N(). + */ +function os2web_datalookup_update_9004() { + \Drupal::service('module_installer')->install([ + 'os2web_key', + ], TRUE); +} diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..191cd5a --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,22 @@ + + + OS2Forms PHP Code Sniffer configuration + + . + vendor/ + node_modules/ + + + + + + + + + + + + + + + diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..e51b69f --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,13 @@ +parameters: + level: 6 + paths: + - src + + ignoreErrors: + - "#Method [a-zA-Z0-9\\_\\\\:\\(\\)]+ has parameter \\$[a-zA-Z0-9_]+ with no value type specified in iterable type array#" + - "#Method [a-zA-Z0-9\\_\\\\:\\(\\)]+ return type has no value type specified in iterable type array#" + - '#Unsafe usage of new static\(\).#' + +# Local Variables: +# mode: yaml +# End: diff --git a/scripts/code-analysis b/scripts/code-analysis new file mode 100755 index 0000000..73ec750 --- /dev/null +++ b/scripts/code-analysis @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +script_dir=$(pwd) +module_name=$(basename "$script_dir") +drupal_dir=vendor/drupal-module-code-analysis +# Relative to $drupal_dir +module_path=web/modules/contrib/$module_name + +cd "$script_dir" || exit + +drupal_composer() { + composer --working-dir="$drupal_dir" --no-interaction "$@" +} + +# # Create new Drupal 9 project +# if [ ! -f "$drupal_dir/composer.json" ]; then +# composer --no-interaction create-project drupal/recommended-project:^9 "$drupal_dir" +# fi +# # Copy our code into the modules folder + +# # Clean up +# rm -fr "${drupal_dir:?}/$module_path" + +# # https://stackoverflow.com/a/15373763 +# # rsync --archive --compress . --filter=':- .gitignore' --exclude "$drupal_dir" --exclude .git "$drupal_dir/$module_path" + +# # The rsync command in not available in itkdev/php8.1-fpm + +# git config --global --add safe.directory /app +# # Copy module files into module path +# for f in $(git ls-files); do +# mkdir -p "$drupal_dir/$module_path/$(dirname "$f")" +# cp "$f" "$drupal_dir/$module_path/$f" +# done + +# drupal_composer config minimum-stability dev + +# # Allow ALL plugins +# # https://getcomposer.org/doc/06-config.md#allow-plugins +# drupal_composer config --no-plugins allow-plugins true + +# drupal_composer require wikimedia/composer-merge-plugin +# drupal_composer config extra.merge-plugin.include "$module_path/composer.json" +# # https://www.drupal.org/project/drupal/issues/3220043#comment-14845434 +# drupal_composer require --dev symfony/phpunit-bridge + +# Run PHPStan +(cd "$drupal_dir" && vendor/bin/phpstan --configuration="$module_path/phpstan.neon") diff --git a/src/Exception/RuntimeException.php b/src/Exception/RuntimeException.php new file mode 100644 index 0000000..0dd1e03 --- /dev/null +++ b/src/Exception/RuntimeException.php @@ -0,0 +1,10 @@ +setConfiguration($configuration); + $this->init(); + } + + /** + * + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + /** @var \Drupal\key\KeyRepositoryInterface $keyRepository */ + $keyRepository = $container->get('key.repository'); + /** @var \Drupal\Core\File\FileSystem $fileSystem */ + $fileSystem = $container->get('file_system'); + + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $keyRepository, + $fileSystem + ); + } + + /** + * Plugin init method. + */ + protected function init() { } /** @@ -58,7 +106,10 @@ public function setConfiguration(array $configuration) { * {@inheritdoc} */ public function defaultConfiguration() { - return []; + return [ + 'certificate_provider' => '', + 'certificate_key' => '', + ]; } /** @@ -89,4 +140,43 @@ public function isReady() { return $this->isReady; } + /** + * Get certificate. + */ + protected function getCertificate(): string { + return ''; + } + + /** + * Create a temporary file path for a certificate. + * + * Note: We do not want the create a file. Just get a temporary file name. + * + * @return string + * The local certificate path. + */ + protected function createLocalCertPath(): string { + $this->localCertPath = $this->fileSystem->getTempDirectory() . '/' . uniqid('os2web_datalookup_local_cert_'); + + return $this->localCertPath; + } + + /** + * Write certificate to temporary certificate file. + * + * @return string + * The local certificate path. + */ + protected function writeCertificateToFile(): string { + // Write certificate to local_cert location. + $certificate = $this->getCertificate(); + $localCertPath = $this->localCertPath; + $result = $this->fileSystem->saveData($certificate, $localCertPath, FileSystem::EXISTS_REPLACE); + if (!$result) { + return new RuntimeException(sprintf('Error writing certificate to temporary file %s', $localCertPath)); + } + + return $result; + } + } diff --git a/src/Plugin/os2web/DataLookup/DatafordelerBase.php b/src/Plugin/os2web/DataLookup/DatafordelerBase.php index 1e05287..49ec16b 100644 --- a/src/Plugin/os2web/DataLookup/DatafordelerBase.php +++ b/src/Plugin/os2web/DataLookup/DatafordelerBase.php @@ -3,7 +3,9 @@ namespace Drupal\os2web_datalookup\Plugin\os2web\DataLookup; use Drupal\Core\Form\FormStateInterface; +use Drupal\os2web_datalookup\Exception\RuntimeException; use GuzzleHttp\Client; +use Psr\Http\Message\ResponseInterface; /** * Defines base plugin class for Datafordeler lookup plugins. @@ -11,24 +13,27 @@ abstract class DatafordelerBase extends DataLookupBase { /** - * Plugin readiness flag. + * The client. * - * @var bool + * @var \GuzzleHttp\Client */ - protected $httpClient; + private $httpClient; /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->init(); + public function defaultConfiguration() { + return [ + 'cert_path_live' => '', + 'cert_passphrase_live' => '', + ] + parent::defaultConfiguration(); } /** - * Plugin init method. + * {@inheritdoc} */ - private function init() { + protected function init() { + parent::init(); $this->isReady = FALSE; $configuration = $this->getConfiguration(); @@ -40,8 +45,10 @@ private function init() { 'accept' => 'application/json', ], ]; - if ($certPath = $configuration['cert_path_live']) { - $options['cert'] = $certPath; + + if (isset($configuration['cert_path_live']) || isset($configuration['key'])) { + $options['cert'] = $this->createLocalCertPath(); + $this->httpClient = new Client($options); $this->isReady = TRUE; } @@ -71,18 +78,53 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '#default_value' => $this->configuration['webserviceurl_live'], ]; - $form['cert_path_live'] = [ - '#type' => 'textfield', - '#title' => $this->t('Certificate (LIVE)'), - '#description' => $this->t('Path to the certificate'), - '#default_value' => $this->configuration['cert_path_live'], - ]; + $form['certificate'] = [ + '#type' => 'fieldset', + '#title' => $this->t('Certificate'), + + 'certificate_provider' => [ + '#type' => 'select', + '#title' => $this->t('Provider'), + '#options' => [ + self::PROVIDER_TYPE_FORM => $this->t('Form'), + self::PROVIDER_TYPE_KEY => $this->t('Key'), + ], + '#default_value' => $this->configuration['certificate_provider'] ?? self::PROVIDER_TYPE_FORM, + ], - $form['cert_passphrase_live'] = [ - '#type' => 'password', - '#title' => $this->t('Certificate passphrase (LIVE)'), - '#description' => $this->t('leave empty if not used'), - '#default_value' => $this->configuration['cert_passphrase_live'], + 'certificate_key' => [ + '#type' => 'key_select', + '#key_filters' => [ + 'type' => 'os2web_key_certificate', + ], + '#title' => $this->t('Key'), + '#default_value' => $this->configuration['certificate_key'] ?? NULL, + '#states' => [ + 'required' => [':input[name="certificate_provider"]' => ['value' => self::PROVIDER_TYPE_KEY]], + 'visible' => [':input[name="certificate_provider"]' => ['value' => self::PROVIDER_TYPE_KEY]], + ], + ], + + 'cert_path_live' => [ + '#type' => 'textfield', + '#title' => $this->t('Certificate (LIVE)'), + '#description' => $this->t('Path to the certificate'), + '#default_value' => $this->configuration['cert_path_live'], + '#states' => [ + 'required' => [':input[name="certificate_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]], + 'visible' => [':input[name="certificate_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]], + ], + ], + + 'cert_passphrase_live' => [ + '#type' => 'password', + '#title' => $this->t('Certificate passphrase (LIVE)'), + '#description' => $this->t('leave empty if not used'), + '#default_value' => $this->configuration['cert_passphrase_live'], + '#states' => [ + 'visible' => [':input[name="certificate_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]], + ], + ], ]; return $form; @@ -104,4 +146,40 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s $this->setConfiguration($configuration); } + /** + * Get response. + */ + protected function getResponse(string $uri, array $options): ResponseInterface { + try { + $localCertPath = $this->writeCertificateToFile(); + + return $this->httpClient->get($uri, $options); + } finally { + // Remove temporary certificate file. + if (file_exists($localCertPath)) { + unlink($localCertPath); + } + } + } + + /** + * Get certificate. + */ + protected function getCertificate(): string { + $provider = $this->configuration['certificate_provider'] ?? NULL; + if (self::PROVIDER_TYPE_KEY === $provider) { + $keyId = $this->configuration['certificate_key'] ?? ''; + $key = $this->keyRepository->getKey($keyId); + if (NULL === $key) { + throw new RuntimeException(sprintf('Cannot get key %s', $keyId)); + } + + return $key->getKeyValue(); + } + + $filename = $this->configuration['cert_path_live']; + + return file_get_contents($filename); + } + } diff --git a/src/Plugin/os2web/DataLookup/DatafordelerCVR.php b/src/Plugin/os2web/DataLookup/DatafordelerCVR.php index 4b81f52..1fc0198 100644 --- a/src/Plugin/os2web/DataLookup/DatafordelerCVR.php +++ b/src/Plugin/os2web/DataLookup/DatafordelerCVR.php @@ -25,9 +25,7 @@ class DatafordelerCVR extends DatafordelerBase implements DataLookupInterfaceCom public function defaultConfiguration() { return [ 'webserviceurl_live' => 'https://s5-certservices.datafordeler.dk/CVR/HentCVRData/1/REST/', - 'cert_path_live' => '', - 'cert_passphrase_live' => '', - ]; + ] + parent::defaultConfiguration(); } /** @@ -66,7 +64,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s */ public function lookup($cvr) { try { - $response = $this->httpClient->get('hentVirksomhedMedCVRNummer', ['query' => ['pCVRNummer' => $cvr]]); + $response = $this->getResponse('hentVirksomhedMedCVRNummer', ['query' => ['pCVRNummer' => $cvr]]); $result = json_decode((string) $response->getBody()); } catch (ClientException $e) { diff --git a/src/Plugin/os2web/DataLookup/DatafordelerPNumber.php b/src/Plugin/os2web/DataLookup/DatafordelerPNumber.php index 0a8d495..3b078f2 100644 --- a/src/Plugin/os2web/DataLookup/DatafordelerPNumber.php +++ b/src/Plugin/os2web/DataLookup/DatafordelerPNumber.php @@ -25,9 +25,7 @@ class DatafordelerPNumber extends DatafordelerBase implements DataLookupInterfac public function defaultConfiguration() { return [ 'webserviceurl_live' => 'https://s5-certservices.datafordeler.dk/CVR/HentCVRData/1/REST/', - 'cert_path_live' => '', - 'cert_passphrase_live' => '', - ]; + ] + parent::defaultConfiguration(); } /** @@ -66,7 +64,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s */ public function lookup($param) { try { - $response = $this->httpClient->get('hentProduktionsenhedMedPNummer', ['query' => ['ppNummer' => $param]]); + $response = $this->getResponse('hentProduktionsenhedMedPNummer', ['query' => ['ppNummer' => $param]]); $result = json_decode((string) $response->getBody()); } catch (ClientException $e) { diff --git a/src/Plugin/os2web/DataLookup/ServiceplatformenBase.php b/src/Plugin/os2web/DataLookup/ServiceplatformenBase.php index 51c3291..cb48f24 100644 --- a/src/Plugin/os2web/DataLookup/ServiceplatformenBase.php +++ b/src/Plugin/os2web/DataLookup/ServiceplatformenBase.php @@ -3,6 +3,7 @@ namespace Drupal\os2web_datalookup\Plugin\os2web\DataLookup; use Drupal\Core\Form\FormStateInterface; +use Drupal\os2web_datalookup\Exception\RuntimeException; /** * Defines base plugin class for Serviceplatformen plugins. @@ -23,14 +24,6 @@ abstract class ServiceplatformenBase extends DataLookupBase { */ protected $client; - /** - * {@inheritdoc} - */ - public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->init(); - } - /** * {@inheritdoc} */ @@ -48,7 +41,7 @@ public function defaultConfiguration() { 'certfile_passphrase' => '', 'certfile' => '', 'certfile_test' => '', - ]; + ] + parent::defaultConfiguration(); } /** @@ -119,22 +112,61 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '#default_value' => $this->configuration['accountinginfo'], ]; - $form['certfile_passphrase'] = [ - '#type' => 'password', - '#title' => 'Certfile passphrase', - '#default_value' => $this->configuration['certfile_passphrase'], - ]; + $form['certificate'] = [ + '#type' => 'fieldset', + '#title' => $this->t('Certificate'), + + 'certificate_provider' => [ + '#type' => 'select', + '#title' => $this->t('Provider'), + '#options' => [ + self::PROVIDER_TYPE_FORM => $this->t('Form'), + self::PROVIDER_TYPE_KEY => $this->t('Key'), + ], + '#default_value' => $this->configuration['certificate_provider'] ?? self::PROVIDER_TYPE_FORM, + ], - $form['certfile'] = [ - '#type' => 'textfield', - '#title' => 'Certfile (live)', - '#default_value' => $this->configuration['certfile'], - ]; + 'certificate_key' => [ + '#type' => 'key_select', + '#key_filters' => [ + 'type' => 'os2web_key_certificate', + ], + '#title' => $this->t('Key'), + '#default_value' => $this->configuration['certificate_key'] ?? NULL, + '#states' => [ + 'required' => [':input[name="certificate_provider"]' => ['value' => self::PROVIDER_TYPE_KEY]], + 'visible' => [':input[name="certificate_provider"]' => ['value' => self::PROVIDER_TYPE_KEY]], + ], + ], - $form['certfile_test'] = [ - '#type' => 'textfield', - '#title' => 'Certfile (test)', - '#default_value' => $this->configuration['certfile_test'], + 'certfile_passphrase' => [ + '#type' => 'password', + '#title' => 'Certfile passphrase', + '#default_value' => $this->configuration['certfile_passphrase'], + '#states' => [ + 'visible' => [':input[name="certificate_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]], + ], + ], + + 'certfile' => [ + '#type' => 'textfield', + '#title' => 'Certfile (live)', + '#default_value' => $this->configuration['certfile'], + '#states' => [ + 'required' => [':input[name="certificate_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]], + 'visible' => [':input[name="certificate_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]], + ], + ], + + 'certfile_test' => [ + '#type' => 'textfield', + '#title' => 'Certfile (test)', + '#default_value' => $this->configuration['certfile_test'], + '#states' => [ + 'required' => [':input[name="certificate_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]], + 'visible' => [':input[name="certificate_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]], + ], + ], ]; return $form; @@ -164,9 +196,10 @@ public function getStatus() { } /** - * Plugin init method. + * {@inheritdoc} */ - private function init() { + protected function init() { + parent::init(); ini_set('soap.wsdl_cache_enabled', 0); ini_set('soap.wsdl_cache_ttl', 0); $this->status = $this->t('Plugin is ready to work')->__toString(); @@ -202,13 +235,19 @@ private function init() { } } + $provider = $this->configuration['certificate_provider'] ?? NULL; + $passphrase = self::PROVIDER_TYPE_KEY === $provider + // The certificate provider provides a passwordless certificate. + ? '' + : ($this->configuration['certfile_passphrase'] ?? ''); + try { switch ($this->configuration['mode_selector']) { case 0: $ws_config = [ 'location' => $this->configuration['location'], - 'local_cert' => $this->configuration['certfile'], - 'passphrase' => $this->configuration['certfile_passphrase'], + 'local_cert' => $this->createLocalCertPath(), + 'passphrase' => $passphrase, 'trace' => TRUE, ]; break; @@ -216,7 +255,8 @@ private function init() { case 1: $ws_config = [ 'location' => $this->configuration['location_test'], - 'local_cert' => $this->configuration['certfile_test'], + 'local_cert' => $this->createLocalCertPath(), + 'passphrase' => $passphrase, 'trace' => TRUE, ]; break; @@ -289,6 +329,7 @@ protected function query($method, array $request) { } try { + $localCertPath = $this->writeCertificateToFile(); $response = (array) $this->client->$method($request); $response['status'] = TRUE; } @@ -297,9 +338,36 @@ protected function query($method, array $request) { 'status' => FALSE, 'error' => $e->faultstring, ]; + } finally { + // Remove temporary certificate file. + if (file_exists($localCertPath)) { + unlink($localCertPath); + } } return $response; } + /** + * Get certificate. + */ + protected function getCertificate(): string { + $provider = $this->configuration['certificate_provider'] ?? NULL; + if (self::PROVIDER_TYPE_KEY === $provider) { + $keyId = $this->configuration['certificate_key'] ?? ''; + $key = $this->keyRepository->getKey($keyId); + if (NULL === $key) { + throw new RuntimeException(sprintf('Cannot get key %s', $keyId)); + } + + return $key->getKeyValue(); + } + + $filename = 0 === $this->configuration['mode_selector'] + ? $this->configuration['certfile'] + : $this->configuration['certfile_test']; + + return file_get_contents($filename); + } + } diff --git a/src/Plugin/os2web/DataLookup/ServiceplatformenCPR.php b/src/Plugin/os2web/DataLookup/ServiceplatformenCPR.php index b2e0f24..4ae8d6f 100644 --- a/src/Plugin/os2web/DataLookup/ServiceplatformenCPR.php +++ b/src/Plugin/os2web/DataLookup/ServiceplatformenCPR.php @@ -22,9 +22,9 @@ class ServiceplatformenCPR extends ServiceplatformenBase implements DataLookupIn * {@inheritdoc} */ public function defaultConfiguration() { - return array_merge(parent::defaultConfiguration(), [ + return [ 'test_mode_fixed_cpr' => '', - ]); + ] + parent::defaultConfiguration(); } /** diff --git a/src/Plugin/os2web/DataLookup/ServiceplatformenCPRExtended.php b/src/Plugin/os2web/DataLookup/ServiceplatformenCPRExtended.php index d2c7026..afd9a3b 100644 --- a/src/Plugin/os2web/DataLookup/ServiceplatformenCPRExtended.php +++ b/src/Plugin/os2web/DataLookup/ServiceplatformenCPRExtended.php @@ -53,9 +53,9 @@ class ServiceplatformenCPRExtended extends ServiceplatformenBase implements Data * {@inheritdoc} */ public function defaultConfiguration() { - return array_merge(parent::defaultConfiguration(), [ + return [ 'test_mode_fixed_cpr' => '', - ]); + ] + parent::defaultConfiguration(); } /**