Problem/Motivation
The module uses hook_node_access() to enforce per-node role-based view access. This approach checks access after entities are loaded into memory, which means listing pages: Views, JSON:API, entity reference widgets, must load and discard nodes the user cannot see. This causes wasted entity loads, incorrect pager counts, and performance degradation that scales with the percentage of restricted nodes.
Steps to reproduce
Enable VAPN on a content type with many nodes.
View a listing page as a user without that role.
The page may show fewer items than the configured pager limit, and entity load count is higher than expected.
Proposed resolution
Replace hook_node_access() with hook_node_grants() and hook_node_access_records(). This moves access filtering to the database query level via a JOIN on the node_access table, so inaccessible nodes are excluded before entity loading. Pagers, counts, and LIMIT clauses work correctly. Caching is also improved: core automatically manages the user.node_grants:view cache context instead of relying on manually attached cache metadata.
Remaining tasks
Verify that node_access_rebuild() completes correctly on sites with existing VAPN data.
Confirm no regressions with the "bypass vapn" permission.
API changes
- hook_node_access() implementation removed.
- hook_node_grants() and hook_node_access_records() implementations added.
Access denial is now cooperative (OR across node access modules) rather than absolute (forbidden() override). If another node access module grants view access to a node, that grant will take effect even if VAPN's grants do not match.
Data model changes
Grant records are written to the core node_access table. Each VAPN-enabled node gets one vapn_bypass row and one vapn_{role_id} row per selected role. Requires node_access_rebuild() on update, handled by vapn_update_9001().
Issue fork vapn-3575428
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
themic8 commentedComment #5
reinchekComment #7
reinchekThe MR has been successfully merged into the 3.0.x branch (commit 952828ac, squashed).
Auto-merge was enabled and completed without issues. The source branch has been kept for traceability.
All reviewed changes, including the migration to hook_node_grants() and hook_node_access_records(), are now part of the target branch.
Thanks