Skip to content

Commit

Permalink
Added support for os2web_key
Browse files Browse the repository at this point in the history
  • Loading branch information
rimi-itk committed May 1, 2024
1 parent f0a3948 commit 9f70e50
Show file tree
Hide file tree
Showing 10 changed files with 320 additions and 72 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
composer.lock
vendor/
7 changes: 6 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@
"prefer-stable": true,
"license": "EUPL-1.2",
"require": {
"ext-soap": "*"
"ext-soap": "*",
"os2web/os2web_key": "dev-os2web_key"
},
"repositories": {
"os2web/os2web_key": {
"type": "vcs",
"url": "https://github.com/rimi-itk/os2web_key"
},
"drupal": {
"type": "composer",
"url": "https://packages.drupal.org/8"
Expand Down
8 changes: 8 additions & 0 deletions src/Exception/RuntimeException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Drupal\os2web_datalookup\Exception;

class RuntimeException extends \RuntimeException
{

}
93 changes: 90 additions & 3 deletions src/Plugin/os2web/DataLookup/DataLookupBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

namespace Drupal\os2web_datalookup\Plugin\os2web\DataLookup;

use Drupal\Core\File\FileSystem;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\PluginBase;
use Drupal\key\KeyRepositoryInterface;
use Drupal\os2web_datalookup\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Provides a base class for image effects.
Expand All @@ -15,7 +20,19 @@
* @see \Drupal\image\ImageEffectManager
* @see plugin_api
*/
abstract class DataLookupBase extends PluginBase implements DataLookupInterface {
abstract class DataLookupBase extends PluginBase implements ContainerFactoryPluginInterface, DataLookupInterface {
protected const PROVIDER_TYPE_FORM = 'form';
protected const PROVIDER_TYPE_KEY = 'key';

/**
* Local certificate path.
*
* Used to temporarily store a certificate in a file just before calling a webservice.
* For security purposes, the file will be removed right after the webservice calls completes.
*
* @var string
*/
private string $localCertPath;

/**
* Plugin readiness flag.
Expand All @@ -27,12 +44,39 @@ abstract class DataLookupBase extends PluginBase implements DataLookupInterface
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition) {
public function __construct(array $configuration, $plugin_id, $plugin_definition,
protected KeyRepositoryInterface $keyRepository,
protected FileSystem $fileSystem
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->setConfiguration($configuration);
$this->init();
}

public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition)
{
/** @var KeyRepositoryInterface $keyRepository */
$keyRepository = $container->get('key.repository');
/** @var FileSystem $fileSystem */
$fileSystem = $container->get('file_system');

return new static(
$configuration,
$plugin_id,
$plugin_definition,
$keyRepository,
$fileSystem
);
}

/**
* Plugin init method.
*/
protected function init()
{
}

/**
* {@inheritdoc}
*/
public function label() {
Expand All @@ -58,7 +102,10 @@ public function setConfiguration(array $configuration) {
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [];
return [
'certificate_provider' => '',
'certificate_key' => '',
];
}

/**
Expand Down Expand Up @@ -89,4 +136,44 @@ 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;
}

}
106 changes: 93 additions & 13 deletions src/Plugin/os2web/DataLookup/DatafordelerBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,40 @@

namespace Drupal\os2web_datalookup\Plugin\os2web\DataLookup;

use Drupal\Core\File\FileSystem;
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.
*/
abstract class DatafordelerBase extends DataLookupBase {

/**
* Plugin readiness flag.
* The client.
*
* @var bool
* @var 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();
Expand All @@ -40,8 +47,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;
}
Expand Down Expand Up @@ -71,18 +80,53 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
'#default_value' => $this->configuration['webserviceurl_live'],
];

$form['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,
],

'certificate_key' => [
'#type' => 'key_select',
'#key_filters' => [
'type' => 'os2web_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]],
],
],

$form['cert_passphrase_live'] = [
'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;
Expand All @@ -104,4 +148,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);
}
}
8 changes: 3 additions & 5 deletions src/Plugin/os2web/DataLookup/DatafordelerCVR.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ 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' => '',
];
'webserviceurl_live' => 'https://s5-certservices.datafordeler.dk/CVR/HentCVRData/1/REST/',
] + parent::defaultConfiguration();
}

/**
Expand Down Expand Up @@ -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) {
Expand Down
8 changes: 3 additions & 5 deletions src/Plugin/os2web/DataLookup/DatafordelerPNumber.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ 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' => '',
];
'webserviceurl_live' => 'https://s5-certservices.datafordeler.dk/CVR/HentCVRData/1/REST/',
] + parent::defaultConfiguration();
}

/**
Expand Down Expand Up @@ -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) {
Expand Down
Loading

0 comments on commit 9f70e50

Please sign in to comment.