permissions_by_term_node_access should return a value

Created on 18 July 2024, 7 months ago

Problem/Motivation

I am in a strange situation where i have a node set as language independent (UND), while my access terms are set as EN. This way, when
dispatchDeniedEventOnRestricedAccess is called, it doesn't dispatch any access error, as the permissions are not checked, because being the two languages different, then it never gets into that if:

if ($termInfo instanceof Term && $termInfo->get('langcode')->getLangcode() == $langcode) {
        if (!$this->isAnyPermissionSetForTerm($term->tid, $termInfo->get('langcode')->getLangcode())) {
          continue;
        }
        $access_allowed = $this->isAccessAllowedByDatabase($term->tid, $uid, $termInfo->get('langcode')->getLangcode());
        if (!$access_allowed && $requireAllTermsGranted) {
          return $access_allowed;
        }

        if ($access_allowed && !$requireAllTermsGranted) {
          return $access_allowed;
        }
      }

So out of this, the hook gives an access neutral. But then following the request down the route, web/core/lib/Drupal/Core/Routing/AccessAwareRouter.php has this:

if (!$access_result->isAllowed()) {
      if ($access_result instanceof CacheableDependencyInterface && $request->isMethodCacheable()) {
        throw new CacheableAccessDeniedHttpException($access_result, $access_result instanceof AccessResultReasonInterface ? $access_result->getReason() : '');
      }
      else {
        throw new AccessDeniedHttpException($access_result instanceof AccessResultReasonInterface ? $access_result->getReason() : '');
      }
    }

and being the neutral access not explicitly allowed, then i get a 403.

Steps to reproduce

Give a node the UND language, and use EN as the language for your access terms.

Proposed resolution

Return something from the hook:

function permissions_by_term_node_access(NodeInterface $node, $op, AccountInterface $account) {
  /** @var \Drupal\permissions_by_term\Service\AccessCheck $accessCheck */
  $accessCheck = \Drupal::service('permissions_by_term.access_check');
  $langcode = $node->language()->getId();
  $check = \Drupal\Core\Access\AccessResult::allowed();
  if (!$accessCheck->canUserAccessByNode($node, $account->id(), $langcode)) {
    $accessCheck->dispatchDeniedEventOnRestricedAccess($node, $account->id(), $langcode);
    $check = \Drupal\Core\Access\AccessResult::forbidden();
  }
  return $check;
}

Does this make any sense for you?

🐛 Bug report
Status

Needs review

Version

3.1

Component

Code

Created by

🇫🇮Finland joey-santiago

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

Merge Requests

Comments & Activities

Production build 0.71.5 2024