Anonymous users are not able to upload files when the upload destination is set to "private files". This problem does not occur with the basic Drupal core file field, only when file_entity is enabled.

I ran into this problem when creating a job application form where anonymous users should submit their CV. After choosing a file, the file is automatically uploaded and gets a file id. Immediately the file field's ReferenceAccess constraint (\Drupal\Core\Entity\Plugin\Validation\Constraint\ReferenceAccessConstraint) kicks in and throws a validation error: You do not have access to the referenced entity (file: 1). The user is not able to submit the form.

Proposed solution: I'm not sure if this is doable, but ideally the ReferenceAccessConstraint would check if the file entity was created by the anonymous user (session) who is creating the reference, and allow the reference to be created.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

marcvangend created an issue. See original summary.

gplante’s picture

I have the exact same problem. I would be happy to find a solution too.

pminf’s picture

Because of this issue we are not able to provide a private upload field in a contact form which is mandatory for sensitive data.

Yete’s picture

I had same issue.
Using "webform module" seems to solve it, so anonymous user can upload files in private folder.

lokeshsn22’s picture

Hi Guys,

Any update on the above issue.

marcvangend’s picture

Hi Lokesh, see https://drupal.stackexchange.com/a/215613/226 for some suggestions on how to solve this by overriding ReferenceAccessConstraintValidator::validate. I remember using this method back in 2016 but unfortunately I do not have access to the repository anymore so I cannot share the final code with you.

PS. Instead of "Hi guys" you may want to choose something more gender neutral. I know some people would appreciate it.

bmathieuh’s picture

Proposed solution: I add this code (copied from the file module) in the FileEntityAccessControlHandler::checkAccess function :

    if ($account->isAnonymous()) {
      // For anonymous users, only the browser session that uploaded the
      // file is positively allowed access to it. See file_save_upload().
      // @todo Implement \Drupal\Core\Entity\EntityHandlerInterface so that
      //   services can be more properly injected.
      $allowed_fids = \Drupal::service('session')->get('anonymous_allowed_file_ids', []);
      if (!empty($allowed_fids[$entity->id()])) {
        return AccessResult::allowed()->addCacheContexts(['session', 'user']);
      }
    }

before checking the ownership of the file :

    $is_owner = $entity->getOwnerId() === $account->id(); 

Thanks for reviewing the path attached.

Ruuds’s picture

@marcvangend your proposed solution helped me out! Thank you.

I've fixed a typo in the patch which renamed the file_entity directory.