entity_jsonapi_entity_filter_access provides insufficient AccessResults

Created on 22 March 2023, almost 2 years ago

Problem/Motivation

entity_jsonapi_entity_filter_access does not provide accurate/sufficient AccessResults. We are considering the main logic:

  elseif ($conditions->count() === 1 || $conditions->getConjunction() === 'OR') {
    $published_key = $entity_type->getKey('published');
    $owner_key = $entity_type->getKey('owner');
    foreach ($conditions->getConditions() as $condition) {
      if (!($condition instanceof Condition)) {
        // Nested condition groups imply logic that is too complex to be mapped.
        return [];
      }

      if ($published_key && $condition->getField() === $published_key && $condition->getOperator() === '=' && (string) $condition->getValue() === '1') {
        $result[JSONAPI_FILTER_AMONG_PUBLISHED] = $allowed;
      }
      elseif ($owner_key && $condition->getField() === $owner_key && $condition->getOperator() === '=' && $condition->getValue() === $account->id()) {
        $result[JSONAPI_FILTER_AMONG_OWN] = $allowed;
      }
      else {
        // Unsupported condition, no access can be granted.
        return [];
      }
    }
  }

There are two problems, both centered around if (!($condition instanceof Condition)), and a third in the return in the final else branch.

Problem 1 - The early return
This condition is being checked in the context of an OR group, per elseif ($conditions->count() === 1 || $conditions->getConjunction() === 'OR'). The early return in the condition essentially turns it into an AND group by preventing checks on any standard conditions that appear the given condition and dropping any AccessResults added to $result for prior $conditions in the loop.

Problem 2 - Lack of handling for the view own unpublished permission
The assumption that "Nested condition groups imply logic that is too complex to be mapped." is flawed in this case. This permission results in a condition group containing exactly 2 conditions that check the owner and publish state. These are known cases and can be handled explicitly.

Problem 3 - Unsupported condition, no access can be granted.
This is similar to problem 1. By returning here, we are turning this into an AND group and discarding any previously determined AccessResults.

Steps to reproduce

  1. Ensure that the authenticated role does not have the "view own unpublished $entity_type" permission, and request a published entity of that type. The request will succeed and return data about the entity.
  2. Grant the authenticated user role the "view own unpublished $entity_type" permission and request the same entity as before. The response will be an empty 204 response.

Proposed resolution

  1. Remove both instances of return [] instances, allowing us to gracefully loop over all conditions and return all $results afterward.
  2. Add handling specifically for the view own unpublished permission.
πŸ› Bug report
Status

Needs review

Version

1.0

Component

Core integration

Created by

πŸ‡ΊπŸ‡ΈUnited States mrweiner

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

Comments & Activities

Production build 0.71.5 2024