If you create a menu item for a node (using the menu module), that menu item will always be visible in navigation blocks. If you restrict access to that node, using node access modules such as OG or TAC, then that restriction has no effect on the display of menu items. Users who do not have access to the node are still able to see the menu links, and when they click these links, they receive an 'access denied' error.
The reason for this undesirable situation is the way that the node access system (or should I say, Drupal's access control system) is currently set up. The 'node' menu item is a static, cached item, and all users with the 'access content' permission are able to access it. The 'node/x' menu items, however, are dynamic and non-cached, and Drupal doesn't determine their actual access until a node page is requested, and the whole node access mechanism kicks in.
So in determining the access for display of menu links, Drupal simply looks at the 'access content' permission for the 'node' menu item (which is the 'parent' of all 'node/x' pages), and never gets round to looking at what node_access has to say about it.
This patch presents a complete hack solution which fixes the problem. It looks through the 'menu' table in the DB, to see if there are any user-defined menu items for node pages. For each one that it finds, it defines a cached menu item whose access is determined by the full power of node_access. The menu items must be defined in the cached part of hook_menu(), because if they're in the non-cached part, the custom items have already been loaded from the DB, and it's too late to define their permissions.
I fully admit that this patch is a hack, and that it is not a proper solution, and that it does NOT belong in core. This patch could even be implemented as a separate module, without needing to hack the core node.module. But I posted it here in order to draw people's attention to this issue, and to see if anyone can think of a better and more long-term solution. I understand that REALLY solving this problem could be quite hard, and may involve seriously re-thinking certain aspects of the menu system. But at least this is a start. And for people that need access control to be observed in displaying links to node pages, this is a solution that will work today.
| Comment | File | Size | Author |
|---|---|---|---|
| node_access_menu_items.patch | 1.03 KB | Jaza |
Comments
Comment #1
Jaza commentedI just found http://drupal.org/node/45988, which is a related but slightly different issue. The patch committed in that issue made the situation better than it was before, but it definitely left THIS issue outstanding.
Comment #2
killes@www.drop.org commentedthis looks like ressource intensive. I recommend putting it into a custom module.
Comment #3
chx commentedLet me quote from the linked issue!
Comment #4
decafdennis commentedThe functionality would be great, but it'll be difficult to implement without affecting performance/speed. Currently I'm using a home brewn theme_menu_item solution, and try to minimize the number of nodes in my menu. (No good solution either.)
Comment #5
Jaza commentedTo follow up from the quote that chx posted from the related issue:
This patch takes the first step in "walking the road fully", by gathering all non-cacheable menu items for node pages, and defining cacheable items for them. The most resource-intensive thing about the patch is the DB query: the actual process of defining extra menu items is not as intensive as it looks, because those items would have been defined anyway, when the menu system found them in the DB.
As I said, I did not post this patch with the aim of getting it in core. I posted it in order to show people just how crappy the current option is for defining node menu items properly, and to highlight the need for an improvement to the menu system that may allow for a cleaner and more efficient solution. I haven't thought of such a solution myself, and I'd love to hear if anyone else has some ideas.
Comment #6
killes@www.drop.org commentedsee here:
http://drupal.org/node/16542
Comment #7
killes@www.drop.org commentedsee referenced issue