function FileAccessControlHandler::checkAccess

Same name and namespace in other branches
  1. 9 core/modules/file/src/FileAccessControlHandler.php \Drupal\file\FileAccessControlHandler::checkAccess()
  2. 8.9.x core/modules/file/src/FileAccessControlHandler.php \Drupal\file\FileAccessControlHandler::checkAccess()
  3. 11.x 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

1 method overrides FileAccessControlHandler::checkAccess()
FileTestAccessControlHandler::checkAccess in core/modules/file/tests/file_test/src/FileTestAccessControlHandler.php
Performs access checks.

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',
        ]);
      }
    }
  }
  elseif ($operation == 'update') {
    $account = $this->prepareUser($account);
    $file_uid = $entity->get('uid')
      ->getValue();
    // Only the file owner can update the file entity.
    if (isset($file_uid[0]['target_id']) && $account->id() == $file_uid[0]['target_id']) {
      return AccessResult::allowed();
    }
    return AccessResult::forbidden('Only the file owner can update the file entity.');
  }
  elseif ($operation == 'delete') {
    $access = AccessResult::allowedIfHasPermission($account, 'delete any file');
    if (!$access->isAllowed() && $account->hasPermission('delete own files')) {
      $access = $access->orIf(AccessResult::allowedIf($account->id() == $entity->getOwnerId()))
        ->cachePerUser()
        ->addCacheableDependency($entity);
    }
    return $access;
  }
  // No opinion.
  return AccessResult::neutral();
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.