Access rights for all node types come from the
node_access
function in the
node
module. Unfortunately this does not give modules full control on the node types' access permissions, especially on the types provided by the node module itself ("story", "page", and all custom types created in "Administer" / "Content management" / "Content types" / "Add content type").
For the node module's types you can set permissions in the "Access control" screen of Administration. Modules are allowed to implement their own node access control by manipulating the contents of the
node_access
table.
There're two points in the
node_access
function, where an external module can influence the access rights of nodes:
- The provider module of the node type must implement the
hook_access
hook and it can control the access rights of the nodes in the given node type in almost every way it likes. Note that the provider of the default node types ("story", "page") and the customer (user created) node types is the node module itself and its access function (node_content_access()
does not allow further hooks or the like. So you cannot plug in any more control on these types at this point.
- If the provider module did not return any result for the hook call AND the operation is not creation of a new node AND the node is published (!), then the contents of the
node_access
table are evaluated.
(Note: the documentation of
hook_access
tells that
"if this hook is not defined for a node type, all access checks will fail, so only the administrator will be able to see content of that type". However this doesn't seem to be the case. AFAIK
hook_access
is called only in one place:
node_access
. And as it is implemented there, the checks go on if this hook is not implemented in the provider module of the node type ... thus in this case the contents of the
node_access
table tell the permission for the node and the given operation.)
There're some other rules that affect the access rights of a node, but a third party module can plug itself in only at these two points. So if the provider module does not return a definitive right ('allow' or 'deny') for the current user on the given node, then the
node_access
table is only consulted if the node is published!
I had to dig myself into all this, because I had to implement a workflow for a news portal with proper access control. There's already an excellent module for this (guess what ... it's called
Workflow and it has a supplementary module called workflow_access
). But regardless of how (or with which module) I implement the required functionality, I cannot control permissions of unpublished nodes (eg. grant permission to view or edit the node, or just change its workflow state) without giving "administer content" permission, because the node module won't let any third party modules have control over unpublished nodes.
The only way to achieve this through a module would be to create a copy of the node module that would allow creation of custom node types and allow control on unpublished modules too. Of course creating a "copy" in case of the node module is not a five minute job (actually it looks a lot more like 5 days, since you've to copy its functionality), so I opted for patching the
node_access
functionality to remove the restriction.
(Note: thinking about this a bit more ... most probably one could copy the node module by replacing all occurances of the "node" string with the name of the new module and replace "story", "page" and probably a couple of other strings with something else ... but in the end you'd get something that you could not use with any other module in the system. And I'm quite sure that the whole Drupal core depends on "nodes" as they are ... so half of Drupal's built-in functionality should be copied as well. Definitely not a five minute job.
)
To patch the node module, you should look for the following line in
node_access
:
if ($op != 'create' && $node->nid && $node->status) {
and change it into this:
if ($op != 'create' && $node->nid) {
The
$node->status
contains the published/unpublished flag of the node and removing this condition will allow the
node_access
based access control modules to set permissions on unpublished nodes too.
Important: this patch changes the default behaviour of node publishing! The
node_access
table contains one single record by default that allows everybody to view any node in the system. So apply this patch only if you use an access control module and have set the "view" permissions for all roles explicitly. Otherwise all your nodes will be made visible (aka. published) to all visitors (anonymous ones too)!
Recent comments
2 years 25 weeks ago
3 years 47 weeks ago
3 years 47 weeks ago
3 years 49 weeks ago
3 years 50 weeks ago
4 years 4 weeks ago
4 years 4 weeks ago
4 years 4 weeks ago
4 years 5 weeks ago
4 years 5 weeks ago