I have installed this module and selected the content types that it needs to be applied. I edited an existing node and set the permission to Authenticated for easy testing. I then selected the the permission management within the view to be the VAPN module which I then applied the the roles of Anonymous and Authenticated within the view.

When I am viewing the page as an anonymous user the node is listed that should only be available for Authenticated users. Access is denied when trying to visit but I had expected the node to not be shown in the list. I had hoped that this module would not allow the node to be shown in views for those roles which are not allowed access.

Comments

JoshuaBud created an issue. See original summary.

rafuel92’s picture

Hello, thanks for the issue, this module uses standard hook_node_access (See here) so it should work, anyway i'll check this issue as soon as i can and let you know.

ash2303’s picture

Views does not follow view option of `hook_node_access`. Use `Nodeaccess` module if you want to control nodes listing in views as well. You can also use something as below for quick fix with VAPN:

/**
 * Implements hook_views_pre_render().
 */
function example_views_pre_render(ViewExecutable $view) {
  $user = \Drupal::currentUser();
  $vapn_config = \Drupal::service('config.factory')->get('vapn.vapnconfig');
  $vapn_node_types = $vapn_config->get('vapn_node_list');

  foreach ($view->result as $key => $row) {
    if ($row->_entity) {
      $is_vapn_bundle = FALSE;
      if ($bundle = $row->_entity->bundle()) {
        $is_vapn_bundle = in_array($bundle, $vapn_node_types);
      }

      if (!$row->_entity->access('view', $user) && !$view->query->options['disable_sql_rewrite'] && $is_vapn_bundle) {
        unset($view->result[$key]);
      }
    }
  }
}

It will automatically apply access to the views containing VAPN nodes. If you want to show all nodes in a view irrespective of VAPN permissions, just use `Disable Sql Rewrite` in Query settings.

rafuel92’s picture

Category: Support request » Feature request
Status: Active » Needs work

we may provide a configuration option into the vapn configuration to integrate the logic implemented in the pre render hook provided by @ash2303

HerrSerker’s picture

#3 did it for me

greggmarshall’s picture

Actually hook_node_access() is skipped by Views, and other lists, by design Node access rights

In node listings (lists of nodes generated from a select query, such as the default home page at path 'node', an RSS feed, a recent content block, etc.), the process above is followed except that hook_ENTITY_TYPE_access() is not called on each node for performance reasons and for proper functioning of the pager system.

Dajka’s picture

Update: This is still an issue. Also I tried to implement #3 and it gives an unexpected error by now.

Update#2: Found the issue! you have to include the following line before the code for #3 to work.

use \Drupal\views\ViewExecutable;

(Hopefully this saves some time for people like me :) )

tostinni’s picture

The solution proposed in #3 is fine but it has a problem regarding the fact that it arrives after the query has been run and thus can lead to incomplete pages of your view.
Let's supposed you have a 10 items pager, if vapn needs to exclude 2 of them you will have 8 items in your page and 2 empty spots that would be visible if you have a grid display.

So here is a solution altering the view query by adding a relationship with the vapn table and checking if the node vapn configuration match the current user or if it's null.

function MODULE_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  // Restrict this to your views machine_name
  if (in_array($view->id(), ['view_1', 'view_2'])) {
    $definition = [
      'table' => 'vapn',
      'field' => 'nid',
      'left_table' => 'node_field_data',
      'left_field' => 'nid',
    ];
    $join = \Drupal::service('plugin.manager.views.join')
      ->createInstance('standard', $definition);
    // Add relationship to vapn table.
    $query->addRelationship('vapn', $join, 'node_field_data');

    // Retrieve current user roles 
    $current_user_roles = \Drupal::currentUser()->getRoles();

    $group_id = $query->setWhereGroup('OR');
    $query->addWhere($group_id, 'vapn.rid', $current_user_roles, 'IN');
    $query->addWhere($group_id, 'vapn.rid', NULL, 'IS NULL');

    // Add a DISTINCT to avoid duplicates in case a node has more than 1 vapn
    $query->distinct = TRUE;
  }
}
jjmackow’s picture

*3 is causing 500 errors with PHP 8.1 and 8.2. It had been working fine in PHP 7.4. What seems to be at issue is the if clause ...

if (!$row->_entity->access('view', $user) && !$view->query->options['disable_sql_rewrite'] && $is_vapn_bundle) 

and in particular, the first part ...

!$row->_entity->access('view', $user)

This issue comes when a user has 2 or more roles.

When the HTTP ERROR 500 occurs, this is written to the error log:

PHP Fatal error:  Nesting level too deep - recursive dependency? in /var/www/files/php/twig/6388e906aa0fb_views-view-unformatted--a_jLVibPFK0d3xzDm5DZP6k59bM/9pwwIlKt9nsA35FdDvIicERdAn-E2fIQPU3OhbsBZKQ.php on line 53 

that particular line within the file is:
if (($context["row"] != twig_last($this->env, ($context["rows"] ?? null)))) {