Commit 8261521f authored by João Ventura's avatar João Ventura Committed by Joao Ventura
Browse files

Issue #3257640 by jcnventura, hchonov, undertext: Respect is_syncing in hook_install

parent b59f4de5
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -3,9 +3,8 @@ type: module
description: 'Encrypt user email addresses stored into the database for security reasons. This module doesn''t alter user experience'
package: Security
dependencies:
  - drupal:user (>=8.5.0)
  - drupal:user
  - encrypt:encrypt
  - real_aes:real_aes
configure: entity.encryption_profile.collection
core: '8.x'
core_version_requirement: ^8 || ^9
core_version_requirement: ^8.9 || ^9
+68 −39
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ use Drupal\encrypt\Entity\EncryptionProfile;
 * Automatically encrypt all existing user email addresses when the module is
 * installed or enabled.
 */
function dbee_install() {
function dbee_install($is_syncing) {
  // Call dbee module on an ultimate stage to improve compatibility with custom
  // modules : dbee decrypt functions will be call early thanks to the
  // dbee_module_implements_alter() function. Email address will be available
@@ -24,7 +24,7 @@ function dbee_install() {

  // Add configuration data for the dbee module.
  // Check if a key already exists.
  if (_dbee_create_encryption_key(DBEE_DEFAULT_KEY_NAME, DBEE_DEFAULT_KEY_BYTES, DBEE_DEFAULT_KEY_FILENAME) && _dbee_create_encryt_profile(DBEE_ENCRYPT_NAME, DBEE_DEFAULT_KEY_NAME, DBEE_DEFAULT_ENCRYPTION_METHOD)) {
  if (_dbee_create_encryption_key(DBEE_DEFAULT_KEY_NAME, DBEE_DEFAULT_KEY_BYTES, DBEE_DEFAULT_KEY_FILENAME, $is_syncing) && _dbee_create_encryt_profile(DBEE_ENCRYPT_NAME, DBEE_DEFAULT_KEY_NAME, DBEE_DEFAULT_ENCRYPTION_METHOD, $is_syncing)) {
    // Dbee Key and encryption profile exist or have just been created.
    // Edit mail and init storage length.
    // Parameters.
@@ -53,9 +53,9 @@ function dbee_install() {
    dbee_update_crypt_all('encrypt');

    // Enable the dbee extra_field_only on the user view page.
    if ($display = \Drupal::entityTypeManager()
    if (!$is_syncing && ($display = \Drupal::entityTypeManager()
      ->getStorage('entity_view_display')
      ->load('user.user.default')) {
      ->load('user.user.default'))) {
      if ($components = $display->getComponents()) {
        if (empty($components['dbee'])) {
          $options = ['weight' => 15];
@@ -208,13 +208,20 @@ function _dbee_encryption_key_value($bytes = 16) {
 *   The number of bytes for the key. Defaults to 16 (=128bits).
 * @param string $filename
 *   The filename for storing the key. Defaults to 'key.key'.
 * @param bool $is_syncing
 *   TRUE if the module is being installed as part of a configuration import.
 *
 * @return bool
 *   TRUE if the key entity already exists or has been successfully
 *   created, or FALSE if an error has occurred.
 */
function _dbee_create_encryption_key($key_id, $bytes = 16, $filename = 'key.key') {
function _dbee_create_encryption_key($key_id, $bytes = 16, $filename = 'key.key', $is_syncing = FALSE) {
  /** @var \Drupal\key\KeyInterface $key */
  $key = Drupal::service('key.repository')->getKey($key_id);
  if ($is_syncing && $key && ($key->get('key_provider') === 'file')) {
    return _dbee_ensure_encryption_key_exists($bytes, $filename);
  }

  if (!$key) {
    // The Dbee key does not exists, we create it.
    $default_key_datas = [
@@ -231,39 +238,7 @@ function _dbee_create_encryption_key($key_id, $bytes = 16, $filename = 'key.key'
      ],
    ];
    // Manage storage, preferentially in a file.
    $file_succeed = FALSE;
    $private_path = Settings::get('file_private_path');
    // This is a local file system path, set into the settings.php file.
    if (!empty($private_path) && is_dir($private_path)) {
      // Save in a path.
      $dbee_path = $private_path . '/' . $filename;
      if (!file_exists($dbee_path)) {
        $file = fopen($dbee_path, 'w');
        if ($file) {
          // Set dbee key value.
          $dbee_key_value = _dbee_encryption_key_value($bytes);
          if ($dbee_key_value && fwrite($file, $dbee_key_value)) {
            $file_succeed = TRUE;
          }
          elseif (empty($dbee_key_value)) {
            \Drupal::logger('dbee')->critical('An encryption key could not be generated.');
          }
          else {
            \Drupal::logger('dbee')->critical('Writing encryption key to file fails.');
          }
          fclose($file);
        }
      }
      else {
        $file_succeed = TRUE;
        \Drupal::logger('dbee')->info("The %file file already exists, use it.", ['%file' => $filename]);
        // The file already exists, so use it. The encryption profile will
        // detect if the file is not valid.
      }
    }
    else {
      \Drupal::logger('dbee')->notice('Dbee key is going to be stored into database because private location is not available.');
    }
    $file_succeed = _dbee_ensure_encryption_key_exists($bytes, $filename);
    if ($file_succeed) {
      $default_key_datas['key_provider'] = 'file';
      $default_key_datas['key_provider_settings']['file_location'] = 'private://' . $filename;
@@ -300,6 +275,55 @@ function _dbee_create_encryption_key($key_id, $bytes = 16, $filename = 'key.key'
  return FALSE;
}

/**
 * Ensures that an encryption key exists.
 *
 * @param int $bytes
 *   An integer, the number of bytes for the key.
 * @param string $filename
 *   A string, filename to store the key.
 *
 * @return bool
 *   TRUE if the key exists or was succesfully created, FALSE otherwise.
 */
function _dbee_ensure_encryption_key_exists($bytes, $filename) {
  // Manage storage, preferentially in a file.
  $file_succeed = FALSE;
  $private_path = Settings::get('file_private_path');
  // This is a local file system path, set into the settings.php file.
  if (!empty($private_path) && is_dir($private_path)) {
    // Save in a path.
    $dbee_path = $private_path . '/' . $filename;
    if (!file_exists($dbee_path)) {
      $file = fopen($dbee_path, 'w');
      if ($file) {
        // Set dbee key value.
        $dbee_key_value = _dbee_encryption_key_value($bytes);
        if ($dbee_key_value && fwrite($file, $dbee_key_value)) {
          $file_succeed = TRUE;
        }
        elseif (empty($dbee_key_value)) {
          \Drupal::logger('dbee')->critical('An encryption key could not be generated.');
        }
        else {
          \Drupal::logger('dbee')->critical('Writing encryption key to file fails.');
        }
        fclose($file);
      }
    }
    else {
      $file_succeed = TRUE;
      \Drupal::logger('dbee')->info("The %file file already exists, use it.", ['%file' => $filename]);
      // The file already exists, so use it. The encryption profile will
      // detect if the file is not valid.
    }
  }
  else {
    \Drupal::logger('dbee')->notice('Dbee key is going to be stored into database because private location is not available.');
  }
  return $file_succeed;
}

/**
 * Set a dbee encryption profile entity.
 *
@@ -314,12 +338,17 @@ function _dbee_create_encryption_key($key_id, $bytes = 16, $filename = 'key.key'
 * @param string $encryption_method
 *   The encryption method. Defaults to 'real_aes', which corresponds to
 *   the real_aes contrib module.
 * @param bool $is_syncing
 *   TRUE if the module is being installed as part of a configuration import.
 *
 * @return bool
 *   TRUE if the Encryption Profile entity already exists or has been
 *   successfully created, or FALSE if an error has occurred.
 */
function _dbee_create_encryt_profile($encrypt_profile_id, $key_id, $encryption_method = 'real_aes') {
function _dbee_create_encryt_profile($encrypt_profile_id, $key_id, $encryption_method = 'real_aes', $is_syncing = FALSE) {
  if ($is_syncing) {
    return FALSE;
  }
  $encrypt_profile = EncryptionProfile::load($encrypt_profile_id);
  if (!$encrypt_profile) {
    // The Dbee encryption profile does not exist, so create it.