CakePHP 2.0    Plugin ACL    

ACL Plugin for CakePHP 2.0

The core of CakePHP contains a system to control access rights based on Access control list. This mechanism is very useful, but I have to admit, not very easy to dive in the first time you try to use it.

Moreover, CakePHP doesn't provide out of the box an interface to configure the rights managed through ACL.

This plugin is such an interface allowing to manage permissions of your application's users and roles.

Technically, it allows to manage the content of the aros, acos and aros_acos tables, used by the CakePHP ACL Component. Its interface is partially inspired by the one you can find in the Croogo CMS, and a part of the code comes from this tutorial of the CakePHP documentation.

 

 

Prerequisites

  • CakePHP 2.0.x

  • a website whose access rights are managed through the ACL Component. A good introduction on how to use this Component can be found in the CakePHP documentation.

  • a table in your database containing the users (its name can be configured)

  • a table in your database containing the roles (its name can be configured). The example given in the tutorial above uses for instance a table called groups and not roles.

Features

  • creation of acos for each action of your controllers

  • automatic detection of new controllers and/or actions

  • clear display of roles permissions

  • clear display of users specific permissions

  • easy edition of roles permissions (through AJAX)

  • easy edition of users specific permissions (through AJAX)

Demo

A sample application containing the ACL plugin can be found here. It is built with CakePHP 1.3 and the corresponding plugin version, but the functionnalities are the same so far.

Download

This plugin is available on the downloads page.

Installation

  • copy the folder acl in your folder /app/plugins

  • configure the admin route (see http://book.cakephp.org/2.0/en/development/routing.html#prefix-routing)

  • copy the parameters found in Acl/Config/bootstrap.php in your file /app/Config/bootstrap.php or load the plugin with its own bootstrap.php file (CakePlugin::load('Acl', array('bootstrap' => true));)

  • access the plugin by navigating to /admin/acl

 

parameter explanation
acl.aro.role.model Name of the model representing the roles

Typically: "Role" ou "Group"
acl.aro.role.primary_key Allows to force the name of the roles primary key

Can be left empty if this name follows the CakePHP conventions ("id")
acl.aro.role.foreign_key Allows to force the name of the role foreign key

Can be left empty if this name follows the CakePHP conventions (e.g. "role_id")
acl.aro.user.model Name of the model representing the users

Typically: "User"
acl.aro.user.primary_key Allows to force the name of the users primary key

Can be left empty if this name follows the CakePHP conventions ("id")
acl.aro.role.display_field Name of the field used to display the roles

Typically: "name"
acl.role.access_plugin_role_ids An array containing the roles ids being in all cases allowed to access the plugin (by bypassing the ACL permissions).

Useful to not being denied access from the ACL plugin when we manipulate the ACL permissions.
acl.role.access_plugin_user_ids An array containing the users ids being in all cases allowed to access the plugin (by bypassing the ACL permissions).

Useful to not being denied access from the ACL plugin when we manipulate the ACL permissions.
acl.user.display_name The name of the field to use to display the users

It can also be a SQL expression such as:

CONCAT(User.lastname, ' ', User.firstname) for MySQL
acl.check_act_as_requester Indicates wether the presence of the ACL Behavior configured as Requester in the user and role models must be automatically verified when the plugin is accessed
acl.gui.roles_permissions.ajax Indicates wether the roles permissions page must be loaded through AJAX.

Depending on the number of permissions to check, this page may takes much time to load. To prevent a webserver timeout, it is possible to configure the page loading through AJAX.
acl.gui.users_permissions.ajax Indicates wether the users permissions page must be loaded through AJAX.

Depending on the number of permissions to check, this page may takes much time to load. To prevent a webserver timeout, it is possible to configure the page loading through AJAX.

FAQ

Looking for a CakePHP 1.3 version ?

Page created on : 2011-12-09 16:15:54 | last update : 2011-12-15 12:33:56

New comment

Your name
Your email
won't be displayed on the website
Your website
Your comment
  • URLs and email addresses surrounded by spaces are automatically activated
  • to include a block of code, surround it with [code]...[/code]

139 comments

<< newer | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
comment by kinkin on 2013-05-19 at 12:41:51
I try use ACL plugin
when i acess URL: http://localhost/demo/admin/acl/aros/check
have error as bellow

Error: Table app_models for model AppModel was not found in datasource default.
---
I have 2 tables users and roles
User hasAndBelongsToMany Role model


comment by Rodrigo de Souza on 2013-05-13 at 16:23:56
hello,

I wonder if there is some planning to adapt the plugin to work in cakehp 2.3

I already use with 2.1 and I really like the tool!

Sincerely,

Rodrigo de Souza
comment by Pankaj on 2013-04-30 at 09:30:30
Hello ,

I have set up plugin on my website, Proble here is how to check the permissions now for any function. Everything is fine with database setup. Just want to know how will we check if we have not granted permission for user to add (new user). Its not checking permissions.. any code on controller file or in view..??

Please kindly provide your help..

Thnx..in advance
comment by corey on 2013-04-01 at 23:20:13 - onlineimage.com
ok to all of you having this same problem, i had to change the AclManagerComponent.php starting at line 600 to make this work, i hope it works ok, it seems to work ok. Correct me if im wrong:
if($specific_permission !== false && isset($specific_permission['Permission']) )
        	        {   
                           //ORIGINAL BROKEN CODE :  if($this->Acl->Aro->Permission->remove(array('Permission.id' => $specific_permission['Permission']['id'])))
        	           //had to write out the SQL code here.....
                            $sql = "UPDATE  `aros_acos` SET  `_create` =  '-1',`_read` =  '-1',`_update` =  '-1',`_delete` =  '-1' WHERE  `aros_acos`.`id` =".$specific_permission['Permission']['id'];
                            
                           $this->Acl->Aro->query($sql);
                           return true;
                            
                        
        	        }
        	        else
        	        {
        	            /*
        	             * As $specific_permission_right has a value, we should never fall here, but who knows... ;-)
        	             */
        	            
        	            trigger_error(__d('acl', 'The specific permission id could not be retrieved'), E_USER_NOTICE);
        	            return false;
        	        }



good luck!
comment by corey on 2013-03-29 at 17:06:18 - onlineimage.com
Hi
first off, this is a real life saver but Im having a weird little problem maybe you can help me with.
the scenario: when i go to take away permissions for a user i get this error:
Notice (1024): An error occured while deleting the specific permission[APP/Plugin/Acl/Controller/Component/AclManagerComponent.php, line 608

it appears the $specific_permission['Permission']['id'] is null, the whole array is null actually. This is strange because I get no errors when i give that user permissions, its only when i take them away....and it works fine with groups (taking and giving permissions)... is it something obvious that i am missing? thanks!

corey
comment by Rudy on 2013-03-25 at 16:51:08 - www.queenheaven.it
Hello
I have tried to put your plugin on my site, based on cake 2.3.1.
It does not work.
It ask me something from another plugin.
Is it compatible with 2.3.1 ?

Thanks

Rudy
comment by ridhia on 2013-03-25 at 07:09:15
hello,

In my project i have 33 controllers.Is that the reason for which it takes a long time to load? How can i make it more faster?

Another thing i want to hide the links that won't be showed to the user if he is not permitted.Is this possible in here?

comment by Adam S on 2013-03-18 at 17:20:24
Great plugin! Thanks.

I noticed that the plugin loads jQuery. Unfortunately, in some situations, if jQuery was loaded prior to the ACLplugin loading it, any loaded jQuery plugins become dissociated.

I quick-fixed the issue by commenting out "echo $this->Html->script('/acl/js/jquery');" in the plugin .ctp files that had it.

The best way to fix this issue is to detect if jquery is already loaded. Maybe a beforeRender line in a helper element would allow this...

comment by Adam Strom on 2013-03-18 at 17:20:18
Great plugin! Thanks.

I noticed that the plugin loads jQuery. Unfortunately, in some situations, if jQuery was loaded prior to the ACLplugin loading it, any loaded jQuery plugins become dissociated.

I quick-fixed the issue by commenting out "echo $this->Html->script('/acl/js/jquery');" in the plugin .ctp files that had it.

The best way to fix this issue is to detect if jquery is already loaded. Maybe a beforeRender line in a helper element would allow this...

comment by Matt on 2013-03-01 at 02:35:09
@Larry,

We are fighting the same demon!

Here is what I found -

- If I create a new user from scratch with my registration page, the user is correctly added to the ARO's table and I can modified the role through the interface.

- However, if I bulk load my users via SQL load (have 100's), then they are not properly entered into the ARO's table and I get the yellow caution sign. If I click on a grey check mark, I get the an "internal error" - different than what you are seeing.

"AclNode::node() - Couldn&#039;t find Aro node identified by &quot;Array ( [Aro0.model] =&gt; Person [Aro0.foreign_key] =&gt; abb9976b-68b3-11e2-8321-000c293ce041 ) &quot;"

Still battling on. Will let you know how it goes.

Happy coding!

Matt

comment by Larry on 2013-02-25 at 19:00:51
I think I've discovered the problem with meshing CakeDC/Users and the ACL Plugin! I feel so stupid for not having noticed it before. CakeDC, in all of their plugins including Users uses var(36) [UUID] for their id field.When you run cake schema create DbAcl, the foreign_key is int(10). I'm assuming here that the foreign_key in question is the User.id and Group.id fields. That would explain why there is a set of strange entries in the foreign_key field in my case (511, 51264, 5126, 5127). Those are the first (numeric) characters in the UUIDs of the referenced tables. Cake/MySQL stores everything it can in an int field until it hits an alpha characters and then gives up. Anyway, making progress.

So, now I've changed the field types in the tables to conform to CakeDC's usage, recreated my users and groups, and am now in the process of re-establishing the permissions. Everything seems to be working fine, except again, when attempting to assign Users Rules (admin/acl/aros/users). Now, I'm getting yellow triangles with an exclamation point next to every checkmark on the table.

The page source reveals the typical massive, hard to read error message, but the gist of it seems to be this:

Notice (8)Undefined index: Aro [APP\Plugin\Acl\Controller\ArosController.php, line 183]

I can't for the life me figure out why Aro would be an undefined index. Line 183 stems from this:

$aro = $this->Acl->Aro->find('first', array('conditions' => array('model' => $user_model_name, 'foreign_key' => $user[$user_model_name][$this->_get_user_primary_key_name()])));

lib/cake/model includes the Aro model. It's got me.
comment by Larry on 2013-02-24 at 21:42:41
@Matt -

Thanks a million. With add the false parameter to the save(), it did return a flash message that the user role had been updated, although all I've got is gray checkmarks under each role for each user. Also, when I extend to recursive = 2 and echo debug($users) on the admin_users view, I get 'Aro' => null, which leads me to think that it didn't actually save anything.

Also, at this point, I've got my three groups repeated in the aros table model field four times with the same foreign key and no parent id. Then the Groups repeat again once with the same parent id for each group. (The last one is correct, I'm pretty sure because the parent id is the id for the record with a "Groups" alias.

I only wish I knew enough about Cake and PHP to really do a fix on this otherwise excellent plugin.
comment by Matt on 2013-02-24 at 03:33:16
@Larry -

You need to turn off validation in the Save function.

In AroController.php->admin_update_user_role(), change

if($this->{$user_model_name}->save($data))

to:

if($this->{$user_model_name}->save($data, false))

The second parameter will disable validation.

Best of luck.

Matt
comment by Larry on 2013-02-23 at 04:06:43
I apologize for being such a pest, but I'm having a really hard time getting this plugin to fully work. Like Kure, my User model is in a plugin (specifically the CakeDC Users plugin). I started out trying this in my bootstrap:

Configure :: write('acl.aro.user.model', 'Users.User');

That didn't work; I got all kinds of error messages about my User model not being a requester (even though it was) and other things that led me to believe that the ACL plugin was just not finding the User model.

So, I tried loading the Users.User model in ArosController and substituting "User" for "$role_model_name" That got me a whole lot further.

However, now, when I go to /admin/acl/aros/users and attempt to assign a role to a user, I get this error message:

The user role could not be updated
username
Please enter a username.
email
Please enter a valid email address.

Of course, there are no fields to enter username and email on that page. I tinkered around some more and got past that only to get this error message:

Unknown column 'Users.User.username' in 'field list'

Can anyone give me a set of steps to make this plugin work with a Users plugin?
comment by Kure ADN on 2013-02-17 at 10:22:33
Thanks @Guillaume for these tricks.

I'm looking for a better plugin integration (my User and Model are in a plugin, so there are little hacks to do for it to work...) I'll post here if I have more infos.
comment by Guillaume on 2013-02-06 at 17:25:43
comment by Guillaume on 2013-02-06 at 16:36:57
Hello :)

In CakePHP 2.3 some things changes...

Model::find('first')
will now return an empty array when no records are found.

So, Acl Manager should be updated : all verifications after a query are obsoletes...
For example
AclManager:597
...
$specific_permission = $this->Acl->Aro->Permission->find('first', array('conditions' => array('aro_id' => $aro_id, 'aco_id' => $aco_id)));

if($specific_permission!==false)
...
Is always true because now an empty array is returned by Model::find('first')

You should replace it (and all same procedures in the plugin) by :
...
if(!empty($specific_permission))
...

Anyway thank you for the good work :)
Best regards,
GL
comment by Larry on 2013-02-03 at 15:03:22
Many thanks for your wonderful plugin. I'm using ver. 2.2.0 of the plugin with ver. 2.2.5 of CakePHP. I've got a couple of problems that are probably due to something that I did wrong.

First, when I go to /admin/acl/aros/ajax_role_permissions, the page displays, but under each role for each action, the little rotating wait symbol displays literally forever. I left the page up all of last night and it is still going. I've got 23 model/controller combinations. Is that too many for it to handle? I also have three roles. I tried changing acl.gui.roles_permissions.ajax in bootstrap.php to false, and that didn't help.

Second, when I go to /admin/acl/aros/user_permissions, I get a fatal error saying " Table groups for model Group was not found in datasource default." (My 'group' table is 'roles' with a model of 'Role.' In the plugin's bootstrap.php file, I've got acl.aro.role.model set to Role in the plugin's bootstrap.php; it doesn't seem to be paying attention to that. I also have the ACL type set to 'requester' in the Role model.

Any ideas that you have on these will be greatly appreciated.
comment by agam on 2013-01-30 at 06:35:28
i want to redirect user to a default page when he is not allowed to access some page instead of redirecting to referrer.
how can i do it?
comment by Alex on 2013-01-27 at 22:36:53
A great plug-in. It works great until I upgraded php to 5.4 and it cause "Debugger" class not found E_Strict error. Can you help me to see what could I do to make it works again?
<< previous | 1 | 2 | 3 | 4 | 5 | 6 | 7 |