Skip to content

Commit

Permalink
Merge pull request #97 from itk-dev/feature/webform-encrypt
Browse files Browse the repository at this point in the history
Webform submission encryption
  • Loading branch information
jekuaitk authored May 3, 2024
2 parents 23b9169 + 7c9b5e4 commit e6c37fe
Show file tree
Hide file tree
Showing 13 changed files with 284 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ before starting to add changes. Use example [placed in the end of the page](#exa

## [Unreleased]

- Added webform encryption modules
- Adding Lat and Long fetching to DataAddress
- [#84](https://github.com/OS2Forms/os2forms/pull/84)
Added digital post test command.
Expand Down
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,15 @@
"drupal/simple_ldap": "^1.0@alpha",
"drupal/simplesamlphp_auth": "^3.2",
"drupal/smtp": "^1.0@beta",
"drupal/sodium": "^2.4",
"drupal/switch_page_theme": "^4.0",
"drupal/telephone_validation": "^2.2",
"drupal/token": "^1.5",
"drupal/ultimate_cron": "^2.0.0",
"drupal/user_default_page": "^2.1",
"drupal/webform": "^6.1",
"drupal/webform_composite": "^1.0@RC",
"drupal/webform_encrypt": "^2.0@alpha",
"drupal/webform_migrate": "^1.1",
"drupal/webform_node_element": "^1.2",
"drupal/webform_remote_handlers": "^1.6.0",
Expand Down Expand Up @@ -112,6 +114,9 @@
},
"drupal/dynamic_entity_reference": {
"entityQuery reference JOINs should specify target_type (https://www.drupal.org/project/dynamic_entity_reference/issues/3120952#comment-14141038)": "https://www.drupal.org/files/issues/2021-06-22/entityquery-reference-joins-should-specify-target_type-3120952-24.patch"
},
"drupal/webform_encrypt": {
"Ensure data is base64 encoded (https://www.drupal.org/project/webform_encrypt/issues/3399414)": "https://git.drupalcode.org/project/webform_encrypt/-/merge_requests/4.patch"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
uuid: 98e9a380-a5d6-4d2a-9176-7c50a9ec7c47
langcode: en
status: true
dependencies:
config:
- key.key.webform
module:
- sodium
id: webform
label: Webform
encryption_method: sodium
encryption_method_configuration: { }
encryption_key: webform
17 changes: 17 additions & 0 deletions modules/os2forms_encrypt/config/install/key.key.webform.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
uuid: be3383e8-1b0e-4b50-989f-e132900d02a0
langcode: en
status: true
dependencies: { }
id: webform
label: Webform
description: 'Encrypt webform submissions'
key_type: encryption
key_type_settings:
key_size: 256
key_provider: config
key_provider_settings:
key_value: LWD5+0klWZn48ZVs13UVHaHJYawX62PAMd3sklkKj/w=
base64_encoded: true
key_input: text_field
key_input_settings:
base64_encoded: true
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
enabled: 0
6 changes: 6 additions & 0 deletions modules/os2forms_encrypt/drush.services.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
services:
os2forms_encrypt.commands:
class: Drupal\os2forms_encrypt\Commands\Os2FormsEncryptCommands
arguments: ['@entity_type.manager', '@config.factory']
tags:
- { name: drush.command }
11 changes: 11 additions & 0 deletions modules/os2forms_encrypt/os2forms_encrypt.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: OS2Forms Encrypt
description: Encryption functionality for OS2Forms web-forms
package: OS2Forms
type: module
version: 1.0.0
core_version_requirement: ^8 || ^9 || ^10
dependencies:
- 'drupal:webform_encrypt'
- 'drupal:sodium'

configure: os2forms_encrypt.admin_settings
5 changes: 5 additions & 0 deletions modules/os2forms_encrypt/os2forms_encrypt.links.menu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
os2forms_encrypt.admin_settings:
title: 'OS2Forms Encrypt settings'
parent: system.admin_config_system
description: 'Settings for the OS2Forms Encrypt module'
route_name: os2forms_encrypt.admin_settings
23 changes: 23 additions & 0 deletions modules/os2forms_encrypt/os2forms_encrypt.module
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

/**
* @file
* This module enabled webform submission encryption as a default option.
*/

/**
* Implements hook_webform_element_info_alter().
*
* Add extra processing function to "force" enabled encryption on webform
* elements when they are being saved in the UI.
*/
function os2forms_encrypt_element_info_alter(array &$definitions): void {
foreach ($definitions as $element_id => &$definition) {
if ($element_id === 'webform_element_encrypt') {
$definition['#process'][] = [
'Drupal\os2forms_encrypt\Element\WebformElementEncrypt',
'processWebformElementEncrypt',
];
}
}
}
7 changes: 7 additions & 0 deletions modules/os2forms_encrypt/os2forms_encrypt.routing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
os2forms_encrypt.admin_settings:
path: '/admin/config/os2forms_encrypt/settings'
defaults:
_form: '\Drupal\os2forms_encrypt\Form\SettingsForm'
_title: 'OS2Forms Encrypt settings'
requirements:
_permission: 'administer encrypt'
90 changes: 90 additions & 0 deletions modules/os2forms_encrypt/src/Commands/Os2FormsEncryptCommands.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

namespace Drupal\os2forms_encrypt\Commands;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\os2forms_encrypt\Form\SettingsForm;
use Drush\Commands\DrushCommands;

/**
* A Drush command file.
*
* @package Drupal\os2forms_encrypt\Commands
*/
class Os2FormsEncryptCommands extends DrushCommands {

/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected EntityTypeManagerInterface $entityTypeManager;

/**
* Factory to get module configuration.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected ConfigFactoryInterface $configFactory;

/**
* Class constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* An instance of the entity type manager.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* An instance of the config factory.
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager, ConfigFactoryInterface $configFactory) {
$this->entityTypeManager = $entityTypeManager;
$this->configFactory = $configFactory;
parent::__construct();
}

/**
* Enable encrypt for all existing webform elements.
*
* @command os2forms-encrypt:enable
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function enabledEncrypt(): void {
$config = $this->configFactory->get(SettingsForm::$configName);
if (!$config->get('enabled')) {
$this->output()->writeln('Encrypt has not been enabled.');
return;
}

// Get the storage for Webform entity type.
$webformStorage = $this->entityTypeManager->getStorage('webform');

// Load all webform entities.
$webforms = $webformStorage->loadMultiple();

/** @var \Drupal\webform\Entity\Webform $webform */
foreach ($webforms as $webform) {
$elements = $webform->getElementsDecoded();
$config = $webform->getThirdPartySettings('webform_encrypt');

$changed = FALSE;
foreach ($elements as $key => $element) {
if (!isset($config['element'][$key])) {
$config['element'][$key] = [
'encrypt' => TRUE,
'encrypt_profile' => 'webform',
];
$changed = TRUE;
}
}

// Save the webform entity so the changes persist, if any changes where
// made.
if ($changed) {
$webform->setThirdPartySetting('webform_encrypt', 'element', $config['element']);
$webform->save();
}
}
}

}
30 changes: 30 additions & 0 deletions modules/os2forms_encrypt/src/Element/WebformElementEncrypt.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Drupal\os2forms_encrypt\Element;

use Drupal\Core\Form\FormStateInterface;
use Drupal\os2forms_encrypt\Form\SettingsForm;

/**
* Class WebformElementEncrypt.
*
* This class contains a static method to process element attributes for
* webforms.
*/
class WebformElementEncrypt {

/**
* Processes element attributes.
*
* Enabled encryption as default.
*/
public static function processWebformElementEncrypt(&$element, FormStateInterface $form_state, &$complete_form): array {
$config = \Drupal::config(SettingsForm::$configName);
if ($config->get('enabled')) {
$element['element_encrypt']['encrypt']['#default_value'] = TRUE;
}

return $element;
}

}
75 changes: 75 additions & 0 deletions modules/os2forms_encrypt/src/Form/SettingsForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace Drupal\os2forms_encrypt\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;

/**
* Class SettingsForm.
*
* This is the settings for the module.
*/
class SettingsForm extends ConfigFormBase {

/**
* The name of the configuration setting.
*
* @var string
*/
public static string $configName = 'os2forms_encrypt.settings';

/**
* {@inheritdoc}
*/
protected function getEditableConfigNames(): array {
return [self::$configName];
}

/**
* {@inheritdoc}
*/
public function getFormId(): string {
return 'os2forms_encrypt_admin_form';
}

/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
$config = $this->config('os2forms_encrypt.settings');

$link = Link::createFromRoute($this->t('administration'), 'entity.key.collection');
$form['notice'] = [
'#type' => 'inline_template',
'#template' => '<h3>{{ title|t }}</h3><p>{{ message|t }}</p><p>{{ adminMessage|t }}</p>',
'#context' => [
'title' => 'Please note',
'message' => 'The encryption key that comes with this module should <strong>not</strong> be used and should be changed before encrypting anything.',
'adminMessage' => 'You can modify the key (named "webform") in the keys ' . $link->toString() . ' panel. Additionally, the execution of this command can generate a new 256-bit key for you: <pre>dd if=/dev/urandom bs=32 count=1 | base64 -i -</pre>',
],
];

$form['enabled'] = [
'#type' => 'checkbox',
'#title' => $this->t('Enabled encryption'),
'#description' => $this->t('Enable encryption for all webform fields. Please note that encryption will be applied only to those fields that are modified after enabling this option.'),
'#default_value' => $config->get('enabled'),
];

return parent::buildForm($form, $form_state);
}

/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
parent::submitForm($form, $form_state);

$this->config(self::$configName)
->set('enabled', $form_state->getValue('enabled'))
->save();
}

}

0 comments on commit e6c37fe

Please sign in to comment.