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?