Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sanitize user names on sql-sanitize #4609

Open
andriokha opened this issue Dec 17, 2020 · 5 comments · May be fixed by #6057
Open

Sanitize user names on sql-sanitize #4609

andriokha opened this issue Dec 17, 2020 · 5 comments · May be fixed by #6057

Comments

@andriokha
Copy link
Contributor

andriokha commented Dec 17, 2020

Is your feature request related to a problem? Please describe.
Currently it's possible for users to use their real names as a username and it isn't sanitized by sql-sanitize.

Describe the solution you'd like
We could set it to a pattern in a similar way to how email addresses are currently sanitized.

Describe alternatives you've considered
I can provide my own post-command sql-sanitize to do this, I'm just wondering if there'd be interest in moving it into drush proper?

@weitzman
Copy link
Member

Lets keep this out of Drush core. If you contribute your code, please send us a link here. Thanks.

@andriokha
Copy link
Contributor Author

Thanks @weitzman! It's currently mixed in with some custom code, but I'll post a snippet here if that's not too ugly in case it's of help to someone:

  /**
   * Updates user names to the pattern user_%uid.
   *
   * It's only been tested on MySQL.
   */
  protected function sanitizeUserNames(): void {
    try {
      [$name_table, $name_column] = $this->getFieldTableDetails('user', 'name');
      [$uid_table, $uid_column] = $this->getFieldTableDetails('user', 'uid');
      assert($uid_table === $name_table);
      $this->database->update($name_table)
        ->condition($uid_column, 0, '>')
        ->expression($name_column, "CONCAT('user_', $uid_column)")
        ->execute();
      $this->logger()->success(dt("User names sanitized."));
    }
    catch (\Exception $e) {
      $context = ['@message' => $e->getMessage()];
      $this->logger()->error(dt("Unable to sanitize user names: @message.", $context));
    }
  }

  /**
   * Gets database details for a given field.
   *
   * It returns the field table name and main property column name.
   *
   * @param string $entity_type_id
   *   The entity type ID the field's attached to.
   * @param string $field_name
   *   The field name.
   *
   * @return array
   *   An indexed array, containing:
   *   - the table name;
   *   - the column name.
   */
  protected function getFieldTableDetails(string $entity_type_id, string $field_name): array {
    $storage = $this->entityTypeManager->getStorage($entity_type_id);
    if (!$storage instanceof SqlEntityStorageInterface) {
      $context = ['!entity_type_id' => $entity_type_id];
      throw new \Exception(dt("Unable to get !entity_type_id table mapping details, its storage doesn't implement \Drupal\Core\Entity\Sql\SqlEntityStorageInterface.", $context));
    }
    $mapping = $storage->getTableMapping();
    $table = $mapping->getFieldTableName($field_name);
    $columns = $mapping->getColumnNames($field_name);
    $definitions = $this->entityFieldManager->getFieldStorageDefinitions($entity_type_id);
    $main_property = $definitions[$field_name]->getMainPropertyName();

    return [$table, $columns[$main_property]];
  }

@weitzman
Copy link
Member

I've used this on mass.gov. Thanks for contributing it. I would welcome this in Drush if someone is up for making a PR.

@weitzman weitzman reopened this Oct 31, 2023
@frob
Copy link
Contributor

frob commented Dec 9, 2023

What would be required in getting the PR started? Is it just adding a class to the Drush\Drupal\Commands\sql namespace and adding the appropriate attributes?

@primsi primsi linked a pull request Jul 9, 2024 that will close this issue
@primsi
Copy link

primsi commented Jul 9, 2024

Opened a PR for this. I used the snippet from #4609 (comment) . Used SanitizeUserTableCommands for this.

It's explicit opt-in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants