why use ACL module?
1) If you have the need to have very finegrained access permissions and the roles does not fit the bill (for example you want to disable and enable the view permission depending on user references
2) If you do not want to get alot of other clutter and you just want a working solution that is general but still fits the bill for your personal project (because nodes can be very different!)
3) You want to get control over what is happening to your access rights.
How to get started with Access control lists (ACL module)
1) Download content access module and set all rights to administrator only for the content type that you would like to restrict. This is the easiest way to learn how this module works
2) Download devel module and enable the access blocks. They will help you decipher if what you programmed with the ACL API module is correct
3) Start by creating your own module (see attached files for a simple example of how to use this module)
Important hints and tips
Use the following set of functions to enable your module to use the
We need to have this in our module or the ACL module will not execute your functions. You can see the acl_node_access_records function as a reference.
/**
* Used by the ACL module.
*/
function MYMODULE_enabled() {
return !content_access_disabling();
}
/**
* Implementation of hook_disable().
*/
function MYMODULE_disable() {
MYMODULE_disabling(TRUE);
}
/**
* Remembers if we have disabled access.
*/
function MYMODULE_disabling($set = NULL) {
static $disabling = FALSE;
if (isset($set)) {
$disabling = $set;
}
return $disabling;
}
Use the nodeapi to refresh your ACL's per node or nodetype on the update and insert operand. Be careful, in drupal 7 these hooks are changed to individual hooks!
For any other question I refer to the example module I included here. This module is really in use and does exactly what the comments in the module are saying.
What does this example module do?
Content type department
- containing 4 user references (see module)
- containing 1 node reference field (see module)
1) It only allows users that have a user reference on this node to view the node.
2) It allows the same (because of the leveraged power of ACL) users to view all referenced nodes to this node
Questions? Place them here and we will improve this documentation
| Comment | File | Size | Author |
|---|---|---|---|
| #16 | acl_example_15.zip | 7.93 KB | miro_dietiker |
| #15 | acl_example_15.zip | 306 bytes | miro_dietiker |
| #11 | acl_example.zip | 13.78 KB | nick_vh |
| #10 | acl_example.zip | 2.43 KB | miro_dietiker |
| #6 | acl_example.txt | 6.42 KB | nick_vh |
Comments
Comment #1
nick_vhHow to use the function acl_node_add_acl
acl_node_add_acl($nid, $acl_id, $view, $update, $delete, $priority) {
If you will use this module to create your own ACL's with custom rules you will definitly get stuck on this one
An example. You have a node (17) and you would like to provide some users only view access but you don't want to loose the other permissions module systems. We think that you were already able to build an ACL list with certain users (1)
acl_node_add_acl($nid = 17, $acl_id = 1, $view = 1, $update = 0, $delete = 0, $priority = 0)
The priority field is very important here. By default the most permission modules will put their priority on 0. This means that all the access will be granted as long as some module grants access to someone.
If you don't want this to happen and you want ACL to be the only player in the field you can set the priority to 1. This will leverage the ACL module to be the most powerful permission control player in the field and will deny access to previously allowed accesses by other modules.
By default it is good to leave this at zero until you really know what this means in production. A good way to find out are the devel module access blocks.
Comment #2
nick_vhUpdating the code example
Included is the module file as a TXT for quick reference of what's in the zip file
Comment #4
salvis(Sorry, I don't have the permission to delete comments.)
acl_example.txt doesn't open at all. You should be able to upload .module, .info, .inc, .patch, etc. files just as they are, without doing anything funny to them.
Comment #5
nick_vhI didn't do anything funny with them?
I cannot upload module files so thats why I created a zip file with those files, what I could do is uploading a patch file but that doesn't help right?
Comment #6
nick_vhAnd as promised the updated module after checking with coder.
There is 1 query I cannot manage to fix since it is a wee bit too specific? If somebody finds out how to fix this please add a patch or a recommendation?
Comment #7
nick_vhWhat do you think if we make a general module to be included in ACL as an example module so people have an easier time to find out? As in a content type with 1 user reference field that permits access to this user?
Comment #8
salvisGreat, that looks much better!
is the way to get the right number of
%ds into the query. I don't thinkWHERE nid IN (%s)works at all, because the string would be quoted and thus the condition always FALSE.Yes, I like the idea of including a sample module. Can we automate the creation of the required content type, so that it is created automatically when the sample module is installed?
Comment #9
miro_dietikerNote this code is missing {node} table joins to get rid of earlyer revisions (per node field).
INNER JOIN {node} n ON n.vid=src.vid
Too many sample modules don't consider revisions which sometimes leads to very broken result if you enable revisions... In this case i guess, the result would be users get simply too many obsolete permissions.
Nick, would be nice to see your much more complete code sample from DDD here too.
Comment #10
miro_dietikerAttached the module modified that shows the general need of vid joins.
If not done so: In case your company assigned in revision 500 ten employees which where later removed in revision 550 again, you will sill assign them permission as employee.
It is always needed to join (inner) to {node} and match the current revision. Obsolete revision lines from fields will get stripped automatically that way.
However the resulting code is php-error free, but not tested with created fields and data.
Note that i've split the SQL statements by intention to make them more readable in the example... (we're always formatting that way in custom modules..)
What we really need to make this a neat example would be some feature export to make it install including the content types and its fields with one single click! Can you provide this, nick?
http://drupal.org/project/features
Comment #11
nick_vhYes! Let's try to get to a nice example feature for the ACL module.
Currently I'm too busy with exams (end of the semester) but if beginning of june is ok for you I'll try to make something nicer out of it.
On the other hand, don't wait for me! If somebody has time to do this earlier, please go ahead.
Attached:
Module :acl_example
Feature : acl_example_feature with some views and content types
NOTE: In the example I used I did not use any query that needed a VID/NID. If you'd like to add this to the example module please do, but then we need to include content profile and such (as in the previous example) and I'm not sure this is straight forward enough to be an 'example' module
NOTE 2: I did not test this feature yet so don't bash if it doesn't work
Comment #12
miro_dietikerThanks nick. This module code looks much improved. Regarding my issue the code is still not considering revisions.
Seems like you didn't use node revisions. But you're still based on node with fields.
All node-field implementations have to consider revisions, since this is a core functionality of drupal.
So ALL your selects need a node join to get rid of obsolete revision entries.
You don't need to use content_profile.. that's nothing to do with this.
If i have time i'll pass another fix for the new example.
Comment #13
nick_vh@miro_dietiker : Indeed, I did not yet (also see the note of previous comment)
If I have time I will improve it :-)
Comment #14
salvisPlease post files unzipped.
Comment #15
miro_dietikerNick, attached your zip with modified SQL considering the node joins that are needed again for proper revisioning support...
Also removed your .svn garbage.
salvis, we really can't upload .module files so i post it as a zip too...
No other test done till now.
Comment #16
miro_dietikeroops... empty folders in the zip... now the right ones.
Comment #17
salvisWhy can't you add '.txt' to the file name and keep the file visible for everyone?
Comment #18
miro_dietikerRight, that would be the best solution then :-)
Sorry, i didn't think about that patches are more straight forward.. ;-)
Well, you need to download all this file by file and save it in the right directory structure...
Note these are now already 7 or 8 files..
I'll submit it as clean filebased attachments in the next version if preferred that way.
Comment #19
salvisFor multi-file patches,
diff -uprN olddir/modules newdir/modules
should do the trick, where 'newdir/modules' contains acl_example.
This should create a nice patch that can easily be applied and unapplied, and it can be viewed online just as easily as well as processed using http://drupal.org/project/dreditor.
Comment #20
miro_dietikerNick, i have absolutely no idea where you've that function from:
It doesn't exist. Nor in your previous examples nor in acl.
What's that from?
Comment #21
nick_vh@miro_dietiker
http://drupal.org/node/764318
And when you're there, review the patch please ;-)
Comment #22
nick_vh- edit : here was a double post, please remove
Comment #23
jayjaydluffy commentedHello!
Can anyone help me out?
I created a module that allows the user to "Personalize" the "Book" in the site based on terms. If a user selects the term e.g. "Money", only the pages with "money" term shall be displayed in the book. The links in the Book Menu for unselected pages are gone, HOWEVER, each page is still accessible, link is visible on Book Navigation and still printed on "Printer-friendly version". So that prompts me to use ACL. The method I used is, I stored all the nids the user doesn't want in an array, run foreach, and foreach NID, give 0, 0, 0, 10 (priority). The 3 tables by ACL were populated correctly, BUT my big problem is, I still could access the unwanted pages, as well as the links is visible on Book Navigation and so on...
My questions are:
1. Is ACL the right tool for me?
2. If yes, what did I miss then?
3. Do I really need to have hook_nodeapi on my custom module? Because in my case, I don't need operands like "Insert", "Delete" etc...
4. Does node_access table get updated everytime ACL_id is created?
I tried looking at other examples similar, if not close, to my functions but did not find one. Really hope someone could help me out! Thanks guys (in advance..)
Comment #24
salvis@jayjaydluffy: Please don't hijack threads. Open your own issue.
Before you do so, read the release notes regarding "DNA" and follow the recommendation.
Comment #25
chris_car commented@jayjaydluffy: you can call node_access_acquire_grants($node) in order to update the node_access table for one noe, if your custom module does not implement hook_nodeapi.
Comment #26
salvis