Node Access by Menu Position -- Does this exist, or should we build it (and can it be built)?

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
webchick's picture

A client of ours -- a university -- has quite an extensive hierarchical menu structure. They want the ability to take a top-level menu item, such as "Current Students" and control which roles can manage (create/edit/delete, based on their role's permissions under admin/user/permissions) and view the content under that section. Permissions should cascade down to sub-items in the tree unless explicitly overridden. They also need to then restrict access to adding new pages underneath menu items they do not have access to.

Here's a mock-up that describes what we're after, since it's easier than me explaining. :) Also, I should point out that this is for Drupal 6.

Menu-level access control

I know of Menu Sub-tree Permissions which should be able to handle the limiting of placing things in the menu on node addition, and Menu Per Role which restricts access of viewing. Anyone know of one that does it for create/edit/delete? Is this worth rolling into one of the above modules (once they're ported to D6), or as a separate project, or am I missing a big, blinking cluestick of a module that does this already?

Thanks for any assistance!

AttachmentSize
menu-access.png189.71 KB

Comments

Monster Menus at Amherst

johnbarclay's picture

Monster Menus at Amherst looks for a similar goal in a university environment.

http://groups.drupal.org/node/10231

organic groups access control

moshe weitzman's picture

Yeah, you definately want to read about monster menus. But ultimately that approach is very costly since it does not play nice with node access and thus you can't get your Views to respect its access control. Perhaps Views can be plugged so that it understands monster menus notion of access control. I suspect not, since it is't a pure SQL system.

You are still missing a major piece of the puzzle. Namely, the nodes themselves are not protected. If I understand it right, Menu Per Role just protects menu callbacks. Your search, notifications, etc. will not know who has access to what.

I don't know of a perfect, available solution here. To me, the closest fit is OG and its access control. You could use hook_user() to sync users into the right groups based on their roles. Even better, you could help me enhance OG so that group membership can be swappable for any given content type. These "role based membership groups" would dynamically determine their member list based on the users_roles table. In addition to roles, this swappability would be interesting for user profile fields (e.g. users in the Marketing department automatically are members of the marketing group.)

I don't know that you need it here, but the OG Subgroups module is actually quite elegant in D6. That might confuse more than help so just ignore that if needed.

Hm...

webchick's picture

Well I was thinking this would be a node access module based on the menu system. So gid would be equivalent to.. hm. mlid? Or maybe the node's path?

The disadvantage obviously is that this would only work for nodes, and other things such as views or module-exposed menu items wouldn't work in the same system. Unless maybe we did some funkyiness with hook_menu_alter() too. Hm...

We can use OG, and we're prepared to do that, but it's pretty heavy. We shouldn't need an entire group to just hold a map of the campus so that 3 people can edit it, ya know? :)

I've downloaded a copy of menu monster and will take a more thorough look through it tomorrow. But there seems to be lots of unrelated code there (which, to the author's credit, he warned about) as well as scary bitwise operator stuff that I don't quite understand. ;)

Anyway, thanks for your thoughts!

Oh, wait. I see.

webchick's picture

So one OG per "Role" or "Department" (like Admissions, IT, etc.) and put the individual pages (Prospective Students, Undergrad Programs, etc.) into the group(s) that has the access that we want. The users' group assignments get synched when the user is edited and their roles change, via hook_user(). Yeah, that could work. Then maybe just add a UI on top of it so that it matches the user expectations.

Do you have a link to an issue about the group membership abstraction? That might come in handy indeed.

Beware, the group membership

moshe weitzman's picture

Beware, the group membership issue has some ancient baggage in it. I am very willing to use an OO based solution now that we are on all on PHP5 and the DB system has gone that way. I was thinking that this might be an interesting use case for handlers (code). That is, each content type or perhaps each group has its membership managed by a 'handler'

please work on an existing project

christefano's picture

My hope is that you will work towards updating an existing project. A good candidate is the Remove Nonviewable Menu Items module. From the project description:

This module searches through the {menu} table, looks for nodes, and checks to see which nodes the user is unable to view. Those nodes are added to the the menu tree with the access attribute set to FALSE, ensuring they do not appear in menus.

Another module that's Drupal 6-challenged is Menu per Role, which can be applied to all types of menu items (custom, node, views, etc.).

taxonomy?

YesCT's picture

Maybe I'm not understanding exactly, but if the menu is hierarchical... a taxonomy can replicate the same structure (and maybe the menu can be generated from the taxonomy). And access by taxonomy is well fleshed out, no?

-Cathy (a newbie)
Cathy Theys
http://YesTrainingAndEducation.com

Cathy Theys

Yeah, I considered that...

webchick's picture

Taxonomy has a nice advantage where you can setup your site's navigation ahead of time and not do it slowly and painfully on a page by page basis. In Drupal 5 and below, you used to be able to sketch out your menu structure, but in D6 it won't let you do that until a page exists at that URL. Ugh. So taxonomy would be great because it would let you add pages individually when you needed them and then choose which section they belong to.

The disadvantage of taxonomy is that it's intended to generate a list of pages with the same term. In the case of site structure, you only ever want a 1:1 term:node mapping. So you're already in a place where you need to begin by working around taxonomy's default behaviour. Also, the Taxonomy Menu module seems to stick the vocabulary name in as the top-level menu item with all of its terms below it. For example, instead of me getting Current Students, Prospective Students, etc. I get "Site section" in primary links. There's not a way that I can see to say "Make this entire vocabulary the primary links." That would probably be pretty easy to add though. But true enough that Taxonomy Access / Tac Lite would let you perform this sort of access control.

Hm.. books?

webchick's picture

Book / Book Access actually gets /very/ close.

The hierarchy is built in. You get a nice built-in sidebar block with:

  • Top-level
    • Sub-page
    • Sub-page
  • Top-level
    • Sub-page
    • Sub-page

In Drupal 6, you can specify that different node types (e.g. "Page") are the ones that get added to the outline, and remove the confusing "Book page" type. The outline is also menu-based (although that doesn't seem to be reflected in the UI anywhere).

Book Access module provides a very similar interface to what we're looking for:

Book Access Module

Disadvantages:
- Still tedious to build out site structure on a page-by-page basis.
- Book Access doesn't support overriding sub-pages.
- No indication on the main admin/content/book page of what the access permissions are.

Seems like these last two could be worked around as patches to Book Access.

Still a concern?

Harry Slaughter's picture

1) yes managing hierarchical content is tedious, but only a mind reading robot could automate that

2) no, book_access does not let you enable access to a single page in a book and not others. for that type of functionality, i'd probably point users to content_access.module, but now you'd have to manage all the pages individually. Or you could use book_access to set role level permissions, then use content_access to fine tune individual nodes (which i think is the best use of content_access anyway). however, i'd need to enable a configurable grant priority so that book_access could be given lower priority than content_access. but that should work. i would implement that if there were a need.

3) since it's not meant for highly granular (ie user based) permissions, i didn't think there was a real need for an additional tab. but now that you mention it, it might be a good idea to display the roles that have access to a book in the book itself (to those with 'administer node' perms or whatever of course).

--
Drupal tips, tricks and services
http://devbee.com/ - Effective Drupal

--
Drupal tips, tricks and services
http://devbee.net/ - Effective Drupal

Alternative

agentrickard's picture

We may be faced with a similar client issue, and I tend to think that Node Access is not the right way to go here, since these are exceptional rules for only a few users, you don't want to introduce the overhead of the Node Access system.

One option works cleanly IFF, other users still have the ability to create and edit content, and that is to use hook_form_alter() (or possibly hook_menu_alter()) to enforce your business logic.

With hook_menu_alter(), you could introduce a different access callback for node editing pages. With hook_form_alter(), you could restrict certain settings or actions based on the business logic.

--
http://ken.therickards.com/

any solution?

wdennen's picture

Just wondering if you found a solution for this?

One clarification

Gribnif's picture

I'm coming late to this discussion, having only just recently found out about it. As the primary author of Monster Menus, I feel I have to comment on one thing Moshe said:

Yeah, you definately want to read about monster menus. But ultimately that approach is very costly since it does not play nice with node access and thus you can't get your Views to respect its access control.

The only aspect of node access that does not work as expected regards the use of node_access to determine whether or not a particular link (usually edit or delete) should be displayed to the user. Without a patch to core, which was discussed in another thread, the user gets links to functions they aren't actually allowed to perform. Authorization itself is handled during hook_nodeapi(), and is quite effective and robust.

We use MM with Views, without any changes to Views' code. I recently wrote a Views plugin for MM to correctly display edit/delete/revisions links only for the nodes upon which the user has permission to perform these actions.

It is fair to say, however, that it is not easy to write a view that omits rows for which users do not have read (or write) access in MM. Because permissions are hierarchical, there is no single table join that can be added to a SQL statement in order to calculate this.

This situation can often be worked around by limiting your views to segments of the site where you know in advance that the user most likely has a particular set of permissions for all of the nodes. For example, at our college, we put the course catalog editing process into Views and CCK. We created a particular part of the menu tree where only people who can edit the catalog have read permission, and used views to show them tables of the courses in a given year and subject area. Because all of the users who can get there in the first place have the ability to read every course, it doesn't matter that these tables contain all of the courses.

Update

agentrickard's picture

This module is now possible, using the Menu Node API. http://drupal.org/project/menu_node

A slight variant on the approach is available as Menu Node Edit, which only deals with editing access and is not a node access module.

http://drupal.org/project/menu_node_edit

--
http://ken.therickards.com/

Thanks

Gribnif's picture

Just a quick note of thanks to Ken (agentrickard). Your work on the menu_node module gave me an idea for a way to get rid of the one place where we had to modify core for Monster Menus. Assuming testing goes as anticipated, we'll be 100% core-mod free.

Monster Menu Update?

seworthi's picture

Gribnif: Are you going to post/make available a new version of monster menu once you have finished testing? I think your module would be very useful in our university site I'm building. Thanks, Scott

http://drupal.org/project/men

keesje's picture

http://drupal.org/project/menu_node_edit is indeed a great tip, seems to do the trick nicely, thanks!

johnbarclay's picture

We're in the architecting stage of a migration of the American Libraries Association sites to Drupal (from serena collage). Monster menus seems like a nice match for the site security because of its delegation, inheritance, and performance functionality, but hasn't been released yet. Any other solutions approaching the initial functionality webchick pointed out?

Haven't yet heard of anything

alexharries's picture

Haven't yet heard of anything approaching Monster Menus' functionality. I did this in a very hacky way (but using Node Access) using CCK to show a permissions fieldset on the node edit page, and tying all nodes into the primary links menu to make sure that all nodes had an MLID (those which didn't were simply ignored by this module); when a node was created or saved which had a menu link in the primary links menu, the permissions were recalculated from the node downwards through any children.

If my description sounds fuzzy, that's because it was a huge amount of work and was very much an experimental work-in-progress.

I intend to resurrect the code one day, but it would require a huge amount of work to make it simple and foolproof to release into the wild and I certainly doubt I have the skills to accomplish it all myself.

So, in a nutshell, Monster Menus has an awful lot to offer, and it would be amazing to see a release candidate for it (even if it had to be rolled into a custom Drupal install, much like Pressflow).

Al

A different starting point

DanielWashbrook's picture

We had a very similar request. To provide node edit/create access by section of site via the menu system.

I started with the Menu Access module as it gave us a menu based interface for controlling permissions by user and role. It also stored that information in a usable table.

Then I changed the node_access callback to add an access "check" of my own based on the Menu Access table.

But then it got dicey. Working down the hierarchy of the menu to allow "inheritance" of permissions became problematic. It worked most of the time but it lost its elegance.

Any suggestions on a different approach would be great!

thanks,
daniel

Monster Menus availability

Gribnif's picture

Just a note for anyone reading this old topic: Monster Menus now has a project page, where you can find both D6 and D7 versions: http://drupal.org/project/monster_menus

[edit: updated to final, non-sandbox URL]

A lightweight solution for hierarchically restrict access

asiby's picture

I know that this is a very old topic by I need the same feature as the one originally posted by webchick. Today, I have discovered a module named Context Restrict Roles (still sandboxed, but reportedly heavily used) that lets you restrict access based on user role using a context. You simply define whatever condition you need, and set the reaction to "Restrict Roles" and voilà.

In my case the condition is super simple ... I just needed a menu condition. That will activate the context of the restricted area no matter how complexe the tree is.

IMHO, OG is super heavy for such task from the end user's point of view. The end users will get completely lost (we have seen it happening with another client) in the logic used by OG when all they really needed was something intuitive and simple to use. Most of them were discovering Drupal for the first time when we started the project.

Access Control

Group organizers

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds:

Hot content this week