Permission to download webform attachments

Created on 29 September 2023, 9 months ago
Updated 6 October 2023, 9 months ago

Problem/Motivation

A Webform Task allows the assigned user(s) to view the related webform submission. They don't need permission to view the webform submission directly.

However, if the webform has uploaded files and the user clicks the links to download those files, they get "Access Denied" - because the Webform module checks their permissions at that point.

As a workaround, I had to give "View any submissions" permission for that webform to the relevant users... But ideally they would only be able to view submissions and download files relating to tasks that are currently assigned to them.

Steps to reproduce

Untested, but I think:

  • Create a webform with at least one file upload field, linked to a workflow
  • Create a user that doesn't have permission to view the submissions for that webform
  • Create a Webform Task that displays the results of that form, assigned to the unprivileged user
  • Submit the webform to start the workflow, and progress it to that task
  • As the unprivileged user, view the submission and try to click the file download link

Proposed resolution

I dug through the code for a while, and couldn't find a simple solution. I tried implementing hook_webform_submission_access(), but it didn't seem to get called. I was able to get it partly working by adding this function to MaestroWebformHandler:

  public function access(WebformSubmissionInterface $webform_submission, $operation, AccountInterface $account = NULL) {
    if ($operation === 'view' && ...) {
      return AccessResult::allowed();
    }

    return parent::access($webform_submission, $operation, $account);
  }

But I'm not sure how to implement the missing part, which would need to check whether the user has at least one active task that uses that webform submission assigned to them.

Of course this also gives them access to the View Submission page itself - but because of the way Webform permissions are implemented, that's the only option I could see. Something like && Drupal::request()->get('_controller') === '\Drupal\system\FileDownloadController::download' might work, but doesn't feel like a safe solution!

Also, it doesn't do anything like checking tokens (we don't use that functionality). A better solution may be to replace the links in the webform submission output to URLs handled by Maestro...

At this point I decided to stick with the "View any submissions" solution - but thought I'd write this up in case anyone else has a similar issue, or a better idea how to solve it.

Remaining tasks

User interface changes

API changes

Data model changes

✨ Feature request
Status

Active

Version

3.1

Component

Code

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @mi-dave
  • πŸ‡¨πŸ‡¦Canada _randy

    Generally, we'd implement the Webform access rules and webform submission access api. It does feel "clunky" though rather than just a singular hook during submission access to modify.

    Perhaps we just make this generic. We implement the access method in the MaestroWebformHandler which just does a hook invocation.

    This way you can code up any sort of check and return value and we just pass that along as the return from the access method. We'd return Neutral as a default.

Production build 0.69.0 2024