Drupal experience

I work professionally with Drupal and maintain Drupal 11 projects using automated testing.

I am applying for permission to opt projects into Drupal's security advisory coverage policy using the TOPdesk Incidents module.

Project

TOPdesk Incidents integrates Drupal Webform submissions with the TOPdesk incident API.

The module allows administrators to configure reusable TOPdesk teams and create TOPdesk incidents from Webform submissions. It retrieves TOPdesk reference data directly from the API and supports configuration for categories, priorities, operator groups, impact, urgency, caller information, processing status, and other incident properties.

Why this project exists

Webform provides general-purpose integrations and remote handlers, while TOPdesk Incidents provides a dedicated integration with the TOPdesk incident API, including TOPdesk-specific configuration entities, reference-data handling, incident payload construction, and Webform integration.

Project quality

The 1.0.x branch is developed for Drupal 11. The project uses dependency injection and Drupal services and follows Drupal coding standards and APIs.

Drupal GitLab CI is enabled and currently passes:

  • Composer validation
  • CSpell
  • PHPCS with Drupal and DrupalPractice standards
  • PHPStan level 5 with phpstan-drupal and deprecation rules
  • PHPUnit unit tests
  • Secret detection

The project repository contains documentation, configuration schema, automated tests, and no bundled third-party code.

Security considerations

The module communicates with an external TOPdesk API using Drupal's HTTP client. Administrative configuration is protected by Drupal permissions and routing access requirements. User-facing strings use Drupal translation APIs, and submitted Webform data is passed to the TOPdesk API rather than rendered directly as HTML by the module.

I understand that opting into security advisory coverage means working with the Drupal Security Team when security issues are reported and following Drupal's coordinated disclosure process.

Project link
https://www.drupal.org/project/topdesk_incidents

Comments

ahmetburkan created an issue. See original summary.

vishal.kadam’s picture

Issue summary: View changes
avpaderno’s picture

Thank you for applying!

Before giving links helpful to understand how the review process works, what to expect from a review, and what to do to avoid a review takes more time than needed, I would like to thank all the reviewers for the work they do.
These applications are volunters-driven, which also means it is not possible to predict when an application will be marked fixed and the applicant will get the permission to opt projects into security advisory policy. While we aim to make an application as quick as possible, it is also important for us that more people review the project used for an application. In this way, we make sure applications do not miss some important points that should be instead reported.
Applications are not meant to be complete debugging sessions that eliminate every existing bug, though. I apologize if sometimes applications seem to go into too-detailed reviews.

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. FILE: src/Form/TopdeskTeamForm.php

  /**
   * The TOPdesk reference data service.
   *
   * @var \Drupal\topdesk_incidents\Service\TopdeskReferenceData
   */
  protected TopdeskReferenceData $referenceData;

  /**
   * Constructs a TopdeskTeamForm object.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager.
   * @param \Drupal\topdesk_incidents\Service\TopdeskReferenceData $referenceData
   *   The TOPdesk reference data service.
   */
  public function __construct(
    EntityTypeManagerInterface $entityTypeManager,
    TopdeskReferenceData $referenceData,
  ) {
    $this->entityTypeManager = $entityTypeManager;
    $this->referenceData = $referenceData;
  }

Modules which are compatible with Drupal 10 and higher versions are expected to use constructor property promotion.

2. FILE: src/Form/TopdeskIncidentsSettingsForm.php

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.

ahmetburkan’s picture

Status: Needs work » Needs review

Thanks for the review. Both points have been fixed in the 1.0.x branch.

vishal.kadam’s picture

Priority: Normal » Major

I am changing priority as per Issue priorities.

anil_bhutia’s picture

Thanks for the updates. I reviewed the 1.0.x branch (commit 376296e) manually; phpcs is clean and the pipeline for that commit is green.

Previously raised points

  • TopdeskTeamForm: constructor property promotion is in place. Assigning $this->entityTypeManager by hand is correct, because EntityForm declares that property untyped.
  • TopdeskIncidentsSettingsForm: all elements now use #config_target and there is no manual save left. Using a ConfigTarget with ToConfig::NoOp for the token is a nice touch.

Security: I found nothing blocking. The token is never shown back, changing the URL or username requires the token again, HTTPS is enforced in both the form and the client, redirects are disabled, the permission is restricted, and there are no AJAX or proxy routes. One suggestion: by default the application token is saved in active config, so it ends up in config/sync and git after drush cex. The README documents settings.php overrides, which is good; please consider optional Key module support, and '#disabled' => TRUE on the token field when hasOverrides('api.password') is TRUE.

src/Plugin/WebformHandler/TopdeskIncidentsWebformHandler.php

  1. The incident is created in submitForm(). Webform calls handlers' submitForm() for the "Save draft" button and from WebformSubmissionForm::wizardSubmit() on every Next/Previous page, not only on the final submit. Multi-page forms and forms with drafts will therefore create duplicate or half-filled incidents. Please move this to postSave() and only act when $webform_submission->getState() === WebformSubmissionInterface::STATE_COMPLETED, as RemotePostWebformHandler does.
  2. The handler settings (topdesk_team, field_mapping.caller_email) have no schema. Webform looks up webform.handler.[%parent.id], so please add webform.handler.topdesk_incidents to config/schema/topdesk_incidents.schema.yml; otherwise strict config schema checks fail as soon as a webform with this handler is saved in a test.
  3. There is no getSummary() override. The base class returns '#theme' => 'webform_handler_topdesk_incidents_summary', which the module does not define, so the handlers page logs a missing theme hook. Override getSummary(), or add the theme hook in an OOP hook class (#[Hook('theme')]).

src/Form/TopdeskTeamForm.php / src/Service/TopdeskReferenceData.php

  1. If the TOPdesk API is unavailable while a team is edited, every select only has the empty option, and saving overwrites the stored TOPdesk IDs with empty strings. Please keep the stored value as an option and show a warning, or block the save.
  2. Reference data is never cached: each form build makes 11 requests plus up to 100 paginated /operatorgroups requests, and the form is built again on submit. Consider caching the lists in cache.default with a short max-age (or a refresh button), invalidated when the API settings change.
  3. When the API is not configured the form returns early but still shows Save, so a team without values can be saved.

src/Service/TopdeskIncidentManager.php

  1. Lines 46-48: if the team no longer exists, NULL is returned without a log entry. Please log a warning through the module's logger channel so site owners can see why incidents are missing.

Minor

  • TopdeskClient::request() logs the exception message, which includes a summary of the TOPdesk response body and may contain submitted personal data. Consider logging only the status code and URL.
  • IncidentPayloadBuilder sends all submission data, including hidden, private and computed elements. You might let the handler choose which elements to send.
  • Rename topdesk_incidents_data.api.php to topdesk_incidents.api.php.
  • The routes in topdesk_incidents.routing.yml duplicate the entity links; route_provider: ['html' => AdminHtmlRouteProvider::class] would let you drop them.
  • TopdeskIncidentsSettingsForm::submitForm() redirects to the route it is already on; that is not needed.

Tests: the unit coverage is good and the HTTP client is properly mocked. Please consider one Kernel test (install config, save a webform with the handler, which would catch the schema issue) and one Functional test for route access and a multi-page submission.

Setting to Needs work for the duplicate-incident issue and the missing handler schema; the rest are suggestions.

vishal.kadam’s picture

Priority: Major » Normal
Status: Needs review » Needs work