6

I want to implement a custom access check in Drupal 8, where users assigned to the node field node-owner have view/edit and revisions view/edit permissions for this specific node.

I have implemented it for node view/edit using the node access system with hook_node_access_records() and hook_node_grants(). But I cannot find how to implement it for the node revisions, since the access check performed in NodeRevisionAccessCheck takes into account only the 'view revisions' and 'revert revisions' role permissions and I cannot see a relevant hook.

Should I do custom access checking on routes as described here? https://www.drupal.org/docs/8/api/routing-system/access-checking-on-routes

And if yes, how do I implement the route check and fetch the current node?

  • what's exactly url you want check access? – Jonh Jan 22 at 10:41
  • @Jonh /node/%/revisions/%/view – Maria Ioannidou Jan 22 at 10:51
3

As you said, node revision does not have hook implement for check access. So you need other way to resolved your problem. My way is alter existing services. Just following document, there is file my_module/src/MyModuleServiceProvider.php

<?php

namespace Drupal\my_module;

use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Class MyModuleServiceProvider.
 *
 * @package Drupal\mymodule
 */
class MyModuleServiceProvider extends ServiceProviderBase {

  /**
   * {@inheritdoc}
   */
  public function alter(ContainerBuilder $container) {
    $definition = $container->getDefinition('access_check.node.revision');
    $definition->setClass('Drupal\my_module\Access\MyModuleNodeRevisionAccessCheck');
    $definition->setArguments(
      [
        new Reference('entity.manager'),
      ]
    );
  }

}

After alter access_check.node.revision service. I'll define new class check access view node revision with extend class NodeRevisionAccessCheck and override method access like this. File src/Access/MyModuleNodeRevisionAccessCheck

<?php

namespace Drupal\my_module\Access;

use Drupal\Core\Access\AccessResult;
use Drupal\node\Access\NodeRevisionAccessCheck;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
use Symfony\Component\Routing\Route;

/**
 * Provides an access checker for node revisions.
 *
 * @ingroup node_access
 */
class MyModuleNodeRevisionAccessCheck extends NodeRevisionAccessCheck {

  public function access(Route $route, AccountInterface $account, $node_revision = NULL, NodeInterface $node = NULL) {
    if ($node_revision) {
      $node = $this->nodeStorage->loadRevision($node_revision);
    }
    $operation = $route->getRequirement('_access_node_revision');
    // You can override logic check access here or provide a new hook.
  }

}
  • Worked as a charm. Actually I overrid the checkAccess method of the NodeRevisionAccessCheck class. – Maria Ioannidou Jan 23 at 13:00
  • Yes, If you understand about logic of the method checkAcesss, you can override it. If no, better override method acess, just procces logic of you and return before line return AccessResult::allowedIf($node && $this->checkAccess($node, $account, $operation))->cachePerPermissions()->addCacheableDependency($node); – Jonh Jan 24 at 0:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.