The basic access control system in Drupal almost doesn't exist. So, there are plenty of modules developed, which (mainly partially only) resolve this issue, but in general don't work together (more of them being enabled at the same site) well.

A big problem for people like me comes up every time with a new major version of Drupal, as some developers don't update their modules promptly, or not at all. I am depending on "Node Privacy by Role", which I've found the most suitable for my needs in the past, among the modules I was able to get to work in my system. I was able to get this module working more or less for my 5.1 test site, but see other guys having issues. So, I still feel very uncomfortable to move the production site to 5.1 exactly due to the lack of support for this module (there is a chance everything will break in 5.2 again, or maybe there is something hiding even in my solution - as it is now - and would come out when the system would be more stressed...). I see in issues published for this module, I am not alone having problems due to that...

As for me to have 100% control to any content in my site for each role (a granularity up to the user level for certain exceptions would be even better) is a basic request, I find the idea of "Path Access" module approach the best one, but this module doesn't work for me at all (as it didn't for 4.7 productsion site...). I hope it is due to the PHP version (I see in issues people with PHP 5 complain about that...) which will be resolved soon, but still - I would feel very bad relying on a module, which may or may not be available for next upgrade. Besides, as I was never able to get it working in the past well, I suspect there is some other issue - as it happened to me with some other modules as well (and I need modules I am using, so I don't even go to investigate what is causing this module not be efficient for me...).

So, here is my question - what is the reason Drupal doesn't offer the possibility for a site administrator to control the access to any address (being a node, taxonomy term, a file attachment or whatever else...), per node or, if needed, even for a certain user (to read, edit and/or administer the content being on that address)?

Maybe some voting could be interesting - to ask users how important this feature is and if it wouldn't be worth to have it in Drupal core.

Comments

Xano’s picture

I totally agree with you. On some points Drupal is really grown up but it's just a little baby when you look at access control. I'd like to see the current access control system to be not only available per role, but also per user (in that way it's a lot easier to just mak somebody a moderator for only one vocab without making a new role for every vocab you need a mod for). Next to that it would indeed be a good idea to create a per-node(/vocab/term) access control system.

A few weeks ago I've created an issue about user roles. I though I'd just post a link here. Maybe someone will take a look at it now :p

Crell’s picture

Drupal does have a per-node access control system, the node_access table. It's optimized for read-speed, which means it can be handled with a simple join. What Drupal lacks is a unified way to manipulate that table. That's what (most) of the various node access modules are for. They're different rule-defining mechanisms that share the same backend "engine". That's why mixing and matching them is so difficult.

Now, I fully agree that it's a non-optimal setup. I'd love to have the ability to mix and match access control systems like OG and TAC without things going ape on me. However, doing so without hosing read performance (remember you'd have to account for both node_load() calls and direct calls for Views and taxonomy listings and such) is hard. I can't think of a system for it. If you can, you'll make a lot of people very happy. :-)

LUTi’s picture

I am sorry, but I don't know much about everything "behind" in Drupal. I know a node access table exists, but unfortunately I don't understand how it is filled and used in detail.

In any case, as I look at the access control, it shouldn't be too complicated to decide weather a certain user should have certain access or not. As soon as some content is requested, it should only be decided weather there is any rule (based on path / URL requested, and probably considering the alises or other internal conversions for it...) prohibiting access for that user (explicitely, or through the role). If yes, we have to return the message about, if no, we have to proceed more or less as we do now. Is this really so complicated?

Crell’s picture

Yes, it is that complicated. :-)

Imagine a not untypical page. You have a list of 20 nodes on it, but only showing selected fields from each node. You have a menu that has links to another 15 nodes. In each case, you want to show only those nodes that the user has access to see.

Option 1) For each node, run through a hook that modules implement that return true or false. Skip the nodes that don't all return true (or those that don't return true at least once). That's 35 function calls (one per node) for each module that implements that hook. If you have even two modules, that's 70 function calls. If each of those has to hit the database to get its data (which if it's user configurable then it will have to), that's 70 additional SQL queries on that page. Drupal is already fairly SQL-intensive. Adding 70 queries to that page would be a horrible performance hit. Doing it this way is potentially an NP algorithm (that is, exponential time), which is something to avoid at all costs.

Option 2) For each node in the system, have a table that simply stores access control booleans for each operation. Then when you're pulling the node data out of the database, add a join against that table. Total extra SQL queries: 0 (well, in practice maybe 1 or two, but certainly not an exponential number). For selected rare operations (create, edit, delete), implement the hook method.

Drupal currently implements option 2, for the simple reason that option 1 would be insanely slow. How that table gets populated is up to your node access module, but sharing that table gets messy because, well, it's just one table. Mixing multiple systems together, though, creates collisions between their logic that can do all sorts of weird things. If you want to have your own special rules for node access, you can write your own node access module that fits your business logic.

As I said, if you can find a way to let us have our cake and eat it too, you'd make a lot of people, myself included, very happy. But so far no one has proposed a system to not kill performance in the process.

LUTi’s picture

I see...

But still, as I've stated in my first post, I am almost sure each serious site must have certain access control, so at the end we are not avoiding the performance drop, we just put it on some other's shoulders. I mean, Drupal as it is (core), is more efficient as it would be (in terms of resources spent for processing, less queries etc.), but not very useful for real life applications (no access control).

So, each site (administrator) must decide for some additional module(s), which:
- can or can not be available with a next major version upgrade of Drupal
- can be written well, or more buggy (for sure I expect Drupal to be better tested when released and developed further on)
- can probably be only less integrated and efficient as if it would be a part of the core Drupal release
- can create more problems when used in combination with other modules

In any case, as much as I have experience with MySQL, even about 70 simple queries (just to see if we are among restricted visitors) shouldn't be too much for a today's average system by my opinion. According to my experience, some more complex queries with joins can easily lead to much slower execution times, even if they seems to be simple (MySQL optimizations are sometimes interesting...). But as I am not an expert in this, I believe you know what you are saying.

In any case, considering all delays on Internet, I would sacrifice this additional load (delay) for security (what I am actually doing now, using some module which is doing more or less that, but this module is not maintained and so very insecure today). I believe many other users would as well. For all the rest, probably it would still be possible to make a system where some (for example per role only) or all this processing could be disabled (not in use), making the system as it is now. But, when access control would be enabled, we would have a well tested and integrated solution, not as we do have now (where maybe some decisions could be taken even twice or so, raelly without a need, when combining more such modules - as they are all mainly only partial solutions...).

So, it is obvious that - as a user of Drupal, who doesn't know much about how it works - I can not help much with suggestions about how to do it (technically). But, I know pretty well what I would need (and, I've tried to describe it as good as possible). If I give a feedback to any manufacturer, I (as a noob in this field) don't expect him to request me to provide a solution. But, the clever manufacturer can still consider user opinions, to try to make a product better (more suitable for users needs).

My post was just my opinion. If I would know how to do it, I would probably write my module, which may in the future be included in Drupal core... ;-)

Crell’s picture

Version: 5.1 » 6.x-dev
ifthenelse’s picture

I think a number of good observations have been made here. Clearly, there are certain access control use cases that don't work very well in Drupal because the mechanisms available are either too cumbersome, don't interoperate well, or don't exist.

One of the main reasons I have been looking at Drupal over Joomla is the access control capability. However, once I got deeper into how node level access control works in Drupal, the more I realized that much of what does exist is mostly afterthought, and doesn't work the way I'd hoped it would for the type of site I want to create.

Specifically, what I want to be able to do is have a site for an organization where content owners can update their area of the site - i.e. I can assign permission for a particular user or group member to create, update, or delete content within a given branch within the content taxonomy. Yes, there are capabilities for doing this today, but the way it works is way too cumbersome, and there are cases where the mechanism breaks down.

What is needed, in my opinion, are two things. The first is to have hierarchical node structure represented in the core, with easily definable parent-child node relationships. I believe there are already efforts underway to address this in Drupal 6, so that's a good thing.

The part I haven't seen, and which I believe is essential, is the ability to define inheritance characteristics in the context of node relationships - including access controls.

For example, say I have sections on my site called "membership" and "program". Let's also assume my organization has a membership chairperson and a program chairperson. Under each of those sections is a hierarchy of nodes, and I want the chairpersons to only be able to update their respective portions of the site. The only (semi) effective way to really do this today afaik is via the taxonomy access stuff, and it is frankly a nightmare to configure for more than a small amount of content. Not only is the initial setup a bit more complex than it needs to be, I also have to make sure the categories don't get messed up (and there are bugs in that, btw). Sure, if I'm willing to live with it, I can (mostly) make it all work, but it basically "feels" like something held together with baling wire and scotch tape - somewhat fragile.

The right way to do this, in my opinion, is to include the concept of inheritance to that of a node hierarchy, such that I can do the following:

- Automatically assign a parent-child relationship when creating a node.
- Allow the child node to inherit the categories associated with the parent (i.e. the child's categories could simply be a reference to those of its parent node, unless overridden).
- Define an access control at any level of the hierarchy that can be applied to everything below it in the tree. Again, child nodes could inherit the access controls of their parent nodes, unless overridden.

I also believe there needs to be a concept of node "ownership" which is separate from "author", and which can also be inherited. That way, I can give someone the authority to author new content within part of the tree, but I can maintain ownership for purposes of access control.

With these kinds of capabilities, I could change the access control at any level of the node hierarchy and it could be automagically applied to all nodes below, including new nodes I create. I also could easily delegate edit/create/delete authority anywhere within the content tree.

I should also be able to change attributes of every node within a branch of the content tree with a single action (category, access control, ownership, etc) rather than having to touch each node individually. With the right type of inheritance mechanism coupled with hierarchical node relationships, this becomes a trivial exercise.

I really don't want to get more specific about the actual implementation, other than to say that the capability needs to be part of the core. There are various access control paradigms which could be implemented - to me, the most important thing is that Drupal needs to get its arms around these kinds of use cases. Otherwise it will remain a challenge to use for sites with delegated administration requirements that that contain more than a small amount of content.

My vote would be for Drupal 6 to take some initial steps in this direction, and then hopefully over the next few releases, Drupal can develop an access control capability that rivals anything commercially available.

I don't think the importance of a flexible, delegated node access control capability within the core can be overemphasized. Without it, Drupal is in many ways a CMS with "one arm tied behind its back".

Xano’s picture

The hierarchical structure idea of Ifthenelse is a good idea. It makes sure one doesn't have to edit permissions for each node, but can easily set it for a parent node and the children will follow.

Option 2) For each node in the system, have a table that simply stores access control booleans for each operation. Then when you're pulling the node data out of the database, add a join against that table. Total extra SQL queries: 0 (well, in practice maybe 1 or two, but certainly not an exponential number). For selected rare operations (create, edit, delete), implement the hook method.

Why not save access control data in the node table itself? In that way you still need one query per node and you get the permissions as well. OK, I admit, the DB relativity Drupal uses now won't be as consistent with this implementation as it is now, but I think functionality/performance is more important than the DB structure.

Just for the record: I'm no developer (just know a little PHP and MySQL), I'm just someone who misses some functionality in Drupal and who hates that's missing. I hope the real developers here are able to ad this feature.

Crell’s picture

Status: Active » Closed (duplicate)

I think the best chance for improved node access restrictions is here: http://drupal.org/node/143075 I am therefore marking this as a duplicate.