Description:
Automatically removes sensitive or unwanted metadata from uploaded files to protect privacy and streamline content moderation workflows.

Project link

https://www.drupal.org/project/file_metadata_cleaner

Comments

ahmetburkan created an issue. See original summary.

vishal.kadam’s picture

Title: File Metadata Cleaner [D10], [D11] » [1.0.x] File Metadata Cleaner
Issue summary: View changes
vishal.kadam’s picture

Thank you for applying!

Please read Review process for security advisory coverage: What to expect for more details and Security advisory coverage application checklist to understand what reviewers look for. Tips for ensuring a smooth review gives some hints for a smoother review.

The important notes are the following.

  • If you have not done it yet, you should enable GitLab CI for the project and fix the PHP_CodeSniffer errors/warnings it reports.
  • For the time this application is open, only your commits are allowed.
  • The purpose of this application is giving you a new drupal.org role that allows you to opt projects into security advisory coverage, either projects you already created, or projects you will create. The project status will not be changed by this application; once this application is closed, you will be able to change the project status from Not covered to Opt into security advisory coverage. This is possible only 14 days after the project is created.

    Keep in mind that once the project is opted into security advisory coverage, only Security Team members may change coverage.
  • Only the person who created the application will get the permission to opt projects into security advisory coverage. No other person will get the same permission from the same application; that applies also to co-maintainers/maintainers of the project used for the application.
  • We only accept an application per user. If you change your mind about the project to use for this application, or it is necessary to use a different project for the application, please update the issue summary with the link to the correct project and the issue title with the project name and the branch to review.

To the reviewers

Please read How to review security advisory coverage applications, Application workflow, What to cover in an application review, and Tools to use for reviews.

The important notes are the following.

  • It is preferable to wait for a project moderator before posting the first comment on newly created applications. Project moderators will do some preliminary checks that are necessary before any change on the project files is suggested.
  • Reviewers should show the output of a CLI tool only once per application.
  • It may be best to have the applicant fix things before further review.

For new reviewers, I would also suggest to first read In which way the issue queue for coverage applications is different from other project queues.

vishal.kadam’s picture

Status: Needs review » Needs work

1. master, 0.9.0 and 0.9.x are wrong names for a branch. Release branch names always end with the literal .x as described in Release branches. While it is possible to use a zero as first number (for example 0.1.0) the convention is to start from 1, for example 1.0.0.

2. FILE: README.md

The README file is missing the required sections - Requirements, Installation, and Configuration.

3. FILE: file_metadata_cleaner.install

I noticed the .install file is currently empty. If it's not being used for any install/update hooks at the moment, it might be a good idea to remove it to avoid confusion. It can always be added later when needed.

4. FILE: file_metadata_cleaner.module

/**
 * Implements hook_ENTITY_TYPE_insert().
 */
function file_metadata_cleaner_file_insert(File $file): void {

The description for that hook should also say for which entity type that hook is implemented.

5. FILE: src/Form/FileProcessorSettingsForm.php

  /**
   * Constructs the form.
   */
  public function __construct(FileProcessorPluginManager $pluginManager, RouteMatchInterface $routeMatch) {

The documentation comment for constructors is not mandatory anymore, If it is given, the description must be “Constructs a new [class name] object”, where [class name] includes the class namespace.

ahmetburkan’s picture

Status: Needs work » Needs review

Thank you very much for reviewing my module and taking the time to provide this detailed feedback. I really appreciate it!

  1. Partial fix: I understand the naming conventions for release branches. However, I cannot delete the 0.9.x branch at the moment because it is connected to an existing release on Drupal.org. I will make sure future branches follow the recommended naming conventions.
  2. Fixed the missing Requirements, Installation, and Configuration sections in the README.md.
  3. Removed the empty .install file to avoid confusion, as it is not currently used.
  4. Updated the documentation comment for hook_ENTITY_TYPE_insert() in file_metadata_cleaner.module to specify the entity type implemented.
  5. Adjusted the constructor docblock in src/Form/FileProcessorSettingsForm.php to follow the current standard:
    “Constructs a new [class name] object.”

Updating status back to "Needs review".

vishal.kadam’s picture

Status: Needs review » Reviewed & tested by the community

Rest looks fine to me.

Let’s wait for a Code Review Administrator to take a look and if everything goes fine, you will get the role.

bigbabert’s picture

issues that i see:

bigbabert’s picture

Status: Reviewed & tested by the community » Needs work
avpaderno’s picture

Status: Needs work » Needs review

The following code is correct. It is similar to the constructor code used by any plugin manager implemented by Drupal core.

  /**
   * Constructs a new FileProcessorPluginManager object.
   *
   * @param \Traversable $namespaces
   *   An object that implements \Traversable which contains the root paths
   *   keyed by the corresponding namespace to look for plugin implementations.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
   *   The cache backend instance to use.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler instance.
   */
  public function __construct(
    \Traversable $namespaces,
    CacheBackendInterface $cache_backend,
    ModuleHandlerInterface $module_handler,
  ) {
    parent::__construct(
      'Plugin/FileProcessor',
      $namespaces,
      $module_handler,
      'Drupal\file_metadata_cleaner\Plugin\FileProcessor\FileProcessorInterface',
      'Drupal\file_metadata_cleaner\Annotation\FileProcessor'
    );

See for example DefaultPluginManager::__construct().

public function __construct($subdir, \Traversable $namespaces, ModuleHandlerInterface $module_handler, $plugin_interface = NULL, ?string $plugin_definition_attribute_name = NULL, string|array|null $plugin_definition_annotation_name = NULL, array $additional_annotation_namespaces = []) {
  $this->subdir = $subdir;
  $this->namespaces = $namespaces;
  $this->moduleHandler = $module_handler;
  $this->pluginInterface = $plugin_interface;
  if (is_subclass_of($plugin_definition_attribute_name, AttributeInterface::class)) {
    $this->pluginDefinitionAttributeName = $plugin_definition_attribute_name;
    $this->pluginDefinitionAnnotationName = $plugin_definition_annotation_name;
    $this->additionalAnnotationNamespaces = $additional_annotation_namespaces;
  }
  else {
    // Backward compatibility.
    $this->pluginDefinitionAnnotationName = $plugin_definition_attribute_name ?? 'Drupal\\Component\\Annotation\\Plugin';
    $this->additionalAnnotationNamespaces = $plugin_definition_annotation_name ?? [];
    if ($plugin_definition_attribute_name) {
      @trigger_error('Not supporting attribute discovery in ' . __CLASS__ . ' is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Provide an Attribute class and an Annotation class for BC. See https://www.drupal.org/node/3395582', E_USER_DEPRECATED);
    }
  }
}

I cannot find any $this->exiftoolPath = $kernel->getAppRoot() . '/../vendor/ahmetburkan/exiftool-binary/exiftool'; line in the project code.

ahmetburkan’s picture

Status: Needs review » Reviewed & tested by the community

Updating issue status back to RTBC.

bbu23’s picture

Status: Reviewed & tested by the community » Needs review

Only reviewers can change the status to RTBC.
Reverting to previous state.

avpaderno’s picture

Status: Needs review » Needs work
  • The following points are just a start and don't necessarily encompass all of the changes that may be necessary
  • A specific point may just be an example and may apply in other places
  • A review is about code that does not follow the coding standards, contains possible security issue, or does not correctly use the Drupal API
  • The single review points are not ordered, not even by importance

src/Controller/ProcessorOverviewController.php

Since that class does not use methods from the parent class, it does not need to use ControllerBase as parent class. Controllers do not need to have a parent class; as long as they implement \Drupal\Core\DependencyInjection\ContainerInjectionInterface, they are fine.

src/Controller/ReadMetadataController.php

    $cleaned = "File hasn't been cleaned by File Metadata Cleaner yet.";

    if ($file->get('metadata_cleaned')->value) {
      $cleaned = "File has already been cleaned by File Metadata Cleaner.";
    }
    return [
      'actions' => [
        '#type' => 'container',
        'clean' => [
          '#type' => 'link',
          '#title' => $this->t('Clean Metadata'),
          '#url' => Url::fromRoute('file_metadata_cleaner.clean_metadata', ['file' => $file->id()]),
          '#attributes' => ['class' => ['button', 'button--primary']],
        ],
        'status' => [
          '#markup' => '<p><b>' . $cleaned . '</b></p>',
        ],
      ],
      'metadata' => [
        '#type' => 'table',
        '#header' => [
          $this->t('Field'),
          $this->t('Value'),
        ],
        '#rows' => $rows,
      ],
    ];

Strings shown in the user interface must be translatable.

src/Form/FileMetadataCleanerSettingsForm.php

The constructor of the parent class needs to be called. Since its parameters changed in Drupal 10.2, the project cannot be compatible with all the Drupal 10 releases and Drupal 11; it requires at least Drupal 10.2.

With Drupal 10 and Drupal 11, there is no longer need to use #default_value for each form element, when the parent class is ConfigFormBase: It is sufficient to use #config_target, as in the following code.

    $form['image_toolkit'] = [
      '#type' => 'radios',
      '#title' => $this->t('Select an image processing toolkit'),
      '#config_target' => 'system.image:toolkit',
      '#options' => [],
    ];

Using that code, it is no longer needed to save the configuration values in the form submission handler: The parent class will take care of that.

    $cleanOnUpload = $form_state->getValue('clean_on_upload');
    $this->configFactory->getEditable('file_metadata_cleaner.settings')
      ->set('clean_on_upload', $cleanOnUpload)
      ->save();

    parent::submitForm($form, $form_state);

This code is not necessary as per my previous point. Instead of $this->configFactory->getEditable() needs to call $this->config().

src/Form/FileProcessorSettingsForm.php

A class that extends ConfigFormBase should not be used to change values for a plugin. Plugins implement their own configuration form via a method, not an external class.

  public function __construct(FileProcessorPluginManager $pluginManager, RouteMatchInterface $routeMatch) {
    $this->pluginManager = $pluginManager;
    $this->routeMatch = $routeMatch;
  }

The parent class's constructor needs to be called.

    if (empty($metadata)) {
      $form['description'] = [
        '#markup' => $this->t('Metadata config is empty for plugin : @plugin', ['@plugin' => $this->pluginId]),
      ];
      return parent::buildForm($form, $form_state);
    }

If no form element is shown, there is no need to call the parent class's method.

src/Hooks/FileEntity.php

For a new module that aims to be compatible with Drupal 10 and Drupal 11, I would rather implement hooks as class methods as described in Support for object oriented hook implementations using autowired services.

vishal.kadam’s picture

Priority: Normal » Minor

I am changing priority as per Issue priorities.

avpaderno’s picture

This thread has been idle, in the needs work state with no activity for some months.

May you confirm you are still pursuing this application? If this is the case, and you made commits basing on what previously reported, or you can answer the questions previously asked, please change the status to Needs review.

avpaderno’s picture

Status: Needs work » Closed (won't fix)

This thread has been idle, in the Needs work state with no activity for about six months or more; the application has been created about 11 months ago or more. Therefore, I marked it as Closed (won't fix).

If this is incorrect, and you are still pursuing this application, please feel free to re-open it and set the issue status to Needs work or Needs review, depending on the current status of your code.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.