You are here

protected static function TemporaryQueryGuard::getAccessCondition in JSON:API 8

Same name and namespace in other branches
  1. 8.2 src/Access/TemporaryQueryGuard.php \Drupal\jsonapi\Access\TemporaryQueryGuard::getAccessCondition()

Gets an EntityConditionGroup that filters out inaccessible entities.

Parameters

string $entity_type_id: The entity type ID for which to get an EntityConditionGroup.

\Drupal\Core\Cache\CacheableMetadata $cacheability: Collects cacheability for the query.

Return value

\Drupal\jsonapi\Query\EntityConditionGroup|null An EntityConditionGroup or NULL if no conditions need to be applied to secure an entity query.

2 calls to TemporaryQueryGuard::getAccessCondition()
TemporaryQueryGuard::applyAccessConditions in src/Access/TemporaryQueryGuard.php
Applies access conditions to ensure 'view' access is respected.
TemporaryQueryGuard::getCommentAccessCondition in src/Access/TemporaryQueryGuard.php
Gets an access condition for a comment entity.

File

src/Access/TemporaryQueryGuard.php, line 228

Class

TemporaryQueryGuard
Adds sufficient access control to collection queries.

Namespace

Drupal\jsonapi\Access

Code

protected static function getAccessCondition($entity_type_id, CacheableMetadata $cacheability) {
  $current_user = \Drupal::currentUser();
  $entity_type = \Drupal::entityTypeManager()
    ->getDefinition($entity_type_id);

  // Get the condition that handles generic restrictions, such as published
  // and owner.
  $generic_condition = static::getAccessConditionForKnownSubsets($entity_type, $current_user, $cacheability);

  // Some entity types require additional conditions. We don't know what
  // contrib entity types require, so they are responsible for implementing
  // hook_query_ENTITY_TYPE_access_alter(). Some core entity types have
  // logic in their access control handler that isn't mirrored in
  // hook_query_ENTITY_TYPE_access_alter(), so we duplicate that here until
  // that's resolved.
  $specific_condition = NULL;
  switch ($entity_type_id) {
    case 'block_content':

      // Allow access only to reusable blocks.
      // @see \Drupal\block_content\BlockContentAccessControlHandler::checkAccess()
      if (isset(static::$fieldManager
        ->getBaseFieldDefinitions($entity_type_id)['reusable'])) {
        $specific_condition = new EntityCondition('reusable', 1);
        $cacheability
          ->addCacheTags($entity_type
          ->getListCacheTags());
      }
      break;
    case 'comment':

      // @see \Drupal\comment\CommentAccessControlHandler::checkAccess()
      $specific_condition = static::getCommentAccessCondition($entity_type, $current_user, $cacheability);
      break;
    case 'entity_test':

      // This case is only necessary for testing comment access controls.
      // @see \Drupal\jsonapi\Tests\Functional\CommentTest::testCollectionFilterAccess()
      $blacklist = \Drupal::state()
        ->get('jsonapi__entity_test_filter_access_blacklist', []);
      $cacheability
        ->addCacheTags([
        'state:jsonapi__entity_test_filter_access_blacklist',
      ]);
      $specific_conditions = [];
      foreach ($blacklist as $id) {
        $specific_conditions[] = new EntityCondition('id', $id, '<>');
      }
      if ($specific_conditions) {
        $specific_condition = new EntityConditionGroup('AND', $specific_conditions);
      }
      break;
    case 'file':

      // Allow access only to public files and files uploaded by the current
      // user.
      // @see \Drupal\file\FileAccessControlHandler::checkAccess()
      $specific_condition = new EntityConditionGroup('OR', [
        new EntityCondition('uri', 'public://', 'STARTS_WITH'),
        new EntityCondition('uid', $current_user
          ->id()),
      ]);
      $cacheability
        ->addCacheTags($entity_type
        ->getListCacheTags());
      break;
    case 'shortcut':

      // Unless the user can administer shortcuts, allow access only to the
      // user's currently displayed shortcut set.
      // @see \Drupal\shortcut\ShortcutAccessControlHandler::checkAccess()
      if (!$current_user
        ->hasPermission('administer shortcuts')) {
        $specific_condition = new EntityCondition('shortcut_set', shortcut_current_displayed_set()
          ->id());
        $cacheability
          ->addCacheContexts([
          'user',
        ]);
        $cacheability
          ->addCacheTags($entity_type
          ->getListCacheTags());
      }
      break;
    case 'user':

      // Disallow querying values of the anonymous user.
      // @see \Drupal\user\UserAccessControlHandler::checkAccess()
      $specific_condition = new EntityCondition('uid', '0', '!=');
      break;
    case 'workspace':

      // The default workspace is always viewable, no matter what, so if
      // the generic condition prevents that, add an OR.
      // @see \Drupal\workspaces\WorkspaceAccessControlHandler::checkAccess()
      if ($generic_condition) {
        $specific_condition = new EntityConditionGroup('OR', [
          $generic_condition,
          new EntityCondition('id', WorkspaceInterface::DEFAULT_WORKSPACE),
        ]);

        // The generic condition is now part of the specific condition.
        $generic_condition = NULL;
      }
      break;
  }

  // Return a combined condition.
  if ($generic_condition && $specific_condition) {
    return new EntityConditionGroup('AND', [
      $generic_condition,
      $specific_condition,
    ]);
  }
  elseif ($generic_condition) {
    return $generic_condition instanceof EntityConditionGroup ? $generic_condition : new EntityConditionGroup('AND', [
      $generic_condition,
    ]);
  }
  elseif ($specific_condition) {
    return $specific_condition instanceof EntityConditionGroup ? $specific_condition : new EntityConditionGroup('AND', [
      $specific_condition,
    ]);
  }
  return NULL;
}