You are here

protected function FileAccessControlHandler::checkAccess in Drupal 10

Same name and namespace in other branches
  1. 8 core/modules/file/src/FileAccessControlHandler.php \Drupal\file\FileAccessControlHandler::checkAccess()
  2. 9 core/modules/file/src/FileAccessControlHandler.php \Drupal\file\FileAccessControlHandler::checkAccess()

Performs access checks.

This method is supposed to be overwritten by extending classes that do their own custom access checking.

Parameters

\Drupal\Core\Entity\EntityInterface $entity: The entity for which to check access.

string $operation: The entity operation. Usually one of 'view', 'view label', 'update' or 'delete'.

\Drupal\Core\Session\AccountInterface $account: The user for which to check access.

Return value

\Drupal\Core\Access\AccessResultInterface The access result.

Overrides EntityAccessControlHandler::checkAccess

File

core/modules/file/src/FileAccessControlHandler.php, line 21

Class

FileAccessControlHandler
Provides a File access control handler.

Namespace

Drupal\file

Code

protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {

  /** @var \Drupal\file\FileInterface $entity */
  if ($operation == 'download' || $operation == 'view') {
    if (\Drupal::service('stream_wrapper_manager')
      ->getScheme($entity
      ->getFileUri()) === 'public') {
      if ($operation === 'download') {
        return AccessResult::allowed();
      }
      else {
        return AccessResult::allowedIfHasPermission($account, 'access content');
      }
    }
    elseif ($references = $this
      ->getFileReferences($entity)) {
      foreach ($references as $field_name => $entity_map) {
        foreach ($entity_map as $referencing_entities) {

          /** @var \Drupal\Core\Entity\EntityInterface $referencing_entity */
          foreach ($referencing_entities as $referencing_entity) {
            $entity_and_field_access = $referencing_entity
              ->access('view', $account, TRUE)
              ->andIf($referencing_entity->{$field_name}
              ->access('view', $account, TRUE));
            if ($entity_and_field_access
              ->isAllowed()) {
              return $entity_and_field_access;
            }
          }
        }
      }
    }
    elseif ($entity
      ->getOwnerId() == $account
      ->id()) {

      // This case handles new nodes, or detached files. The user who uploaded
      // the file can access it even if it's not yet used.
      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',
          ]);
        }
      }
      else {
        return AccessResult::allowed()
          ->addCacheContexts([
          'user',
        ]);
      }
    }
  }
  if ($operation == 'delete' || $operation == 'update') {
    $account = $this
      ->prepareUser($account);
    $file_uid = $entity
      ->get('uid')
      ->getValue();

    // Only the file owner can update or delete the file entity.
    if ($account
      ->id() == $file_uid[0]['target_id']) {
      return AccessResult::allowed();
    }
    return AccessResult::forbidden('Only the file owner can update or delete the file entity.');
  }

  // No opinion.
  return AccessResult::neutral();
}