Limpieza de datos de usuarios en Drupal

index.png
Solucionex
07
Mayo 21

Cuando se importa una base de datos, por ejemplo en el entorno de desarrollo local o preproducción, es útil eliminar los datos personales de los usuarios, tanto por tema de protección de datos como por evitar la posibilidad de que en algún proyecto se envíe algún email a una dirección de correo a donde no se deba.

Para ello, drush cuenta con la herramienta sql:sanitize (alias sqlsan). Ejemplo básico de uso:

drush sqlsan

Por defecto ejecuta las siguientes acciones:

  • Eliminar nombres y direcciones de correo de los comentarios
  • Vaciar la tabla de sesiones
  • Modificar los campos de texto de los usuarios (menos el nombre de usuario)
  • Modificar contraseñas de manera aleatoria
  • Modificar direcciones de correo de los usuarios (por defecto el patrón es user+[uid]@localhost.localdomain, pero puede cambiarse)

Opciones permitidas

  • --allowlist-fields[=ALLOWLIST-FIELDS]. Campos que no se quieren sanitizar (separados por comas).
  • --sanitize-email[=SANITIZE-EMAIL]. El patrón a seguir para modificar las direcciones de correo. Pueden usarse reemplazos como %uid, %mail or %name. [por defecto: user+%uid@localhost.localdomain]
  • --sanitize-password[=SANITIZE-PASSWORD]. Por defecto, las contraseñas se modifican de manera aleatoria. Si se pasa “no“, no se modificarán. Si se especifica cualquier otra cadena de texto, TODAS las contraseñas de todos los usuarios todas se cambiarán por esa.

DDEV

Usando DDEV se puede automatizar la sanitización de la base de datos, ejecutándolo como post hook del comando “import-db“. Ejemplo que sanitiza la base de datos y produce un enlace de autenticación automática como admin (.ddev/config.yaml):

hooks:
  post-import-db:
    - exec: "drush sqlsan"
    - exec: "drush uli"

Hooks

Los módulos, tanto contribuidos como personalizados pueden engancharse a esta funcionalidad creando un servicio etiquetado como comando de drush. Por ejemplo, si está instalado el módulo Webform, se vaciarán también los datos de formularios enviados. Ejemplo:

[RAÍZ MÓDULO]/drush.services.yml

services:
  [NOMBRE_MÓDULO].sanitize.sanitize_test.commands:
    class: \Drupal\[NOMBRE_MÓDULO]\Commands\SanitizeTestSanitizeCommands
    arguments: ['@database']
    tags:
      - { name: drush.command }

En este archivo se define un servicio etiquetado como comando de drush que recibe como argumento la conexión con la base de datos.

[RAÍZ MÓDULO]/src/Commands/SanitizeTestSanitizeCommands.php

namespace Drupal\[NOMBRE_MÓDULO]\Commands;

use Consolidation\AnnotatedCommand\CommandData;
use Drupal\Core\Database\Connection;
use Drush\Commands\DrushCommands;
use Drush\Drupal\Commands\sql\SanitizePluginInterface;
use Symfony\Component\Console\Input\InputInterface;

/**
 * Drush sql-sanitize plugin for sanitizing a test table.
 *
 * @see \Drush\Drupal\Commands\sql\SanitizeSessionsCommands
 */
class SanitizeTestSanitizeCommands extends DrushCommands implements SanitizePluginInterface {

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * SanitizeTestSanitizeCommands constructor.
   *
   * @param \Drupal\Core\Database\Connection $database
   *   The database.
   */
  public function __construct(Connection $database) {
    parent::__construct();
    $this->database = $database;
  }
  
  /**
   * @hook on-event sql-sanitize-confirms
   *
   * {@inheritdoc}
   */
  public function messages(&$messages, InputInterface $input) {
    $messages[] = dt('Truncate test table');
  }

  /**
   * @hook post-command sql-sanitize
   *
   * {@inheritdoc}
   */
  public function sanitize($result, CommandData $command_data) {
    $this->database->truncate('prueba')->execute();
    $this->logger()->success(dt('Truncated test table'));
  }

}

En la clase del servicio se definen dos funciones:

  • messages: Donde se definen los mensajes que se añaden al mensaje de información de drush
  • sanitize: Donde se ejecuta la limpieza o modificación de tablas de la bd