I've inherited an app that makes heavy use of Cake's ACL -- a component I've never used -- and is configured such that 3 group AROs have access to an entire controller. ACOs exist for each action in the controller, but no permissions are explicitly assigned at the action level.
I've now run into a situation where I need one group to have access to one particular method, but I need to deny it for the other 2 groups. Is there any way to, rather than explicitly assigning permissions for each group to each action, simply indicate that the 2 groups do not have permissions to the one action in question?
Essentially, I want to keep the current "access to everything" default, but override that with a "deny for [this particular action]". I've tried cake bake acl deny GroupName ControllerName actionName, but that doesn't seem to have any impact.
By way of a fairly ubiquitous analogy, I'd like this to behave like Apache's AllowOverride. By default, allow everything to everyone, but deny a given action to a given group. I'm not sure whether that's helpful, but there it is.
Thanks.
This command will grant all your AROs access to your ACOs cake acl grant RootGroupName RootControllerName all.
Thereafter you can specify the particular actions you would like to deny access to: cake acl deny GroupName ControllerName|AcoActionName AcoActionName|permissions
If your second value after deny was an AcoActionName you would have to use one of the following values for permissions: all, create, read, update, delete.
A small tangent:
This is where I believe the confusion may lie. The structure of your
ACL [ACOs and AROs] are simply names of nodes that generally match the
structure of your controller/action setup, but can be called any name
your would like since the permissions are checked in each action. CakePHP ACLs organized in a
Tree (data structure) and the external nodes can have database level CRUD permissions set.
Here is a sample ACL schema for users and comments.
Aco tree:
---------------------------------------------------------------
[1] controllers (root node)
[2] Comments
[3] edit
[4] add
[5] delete
---------------------------------------------------------------
Aro tree:
---------------------------------------------------------------
[1] Groups (root node)
[2] Users
[3] Admin
---------------------------------------------------------------
Assuming access has been granted globally, all Requestors have access to all Objects. If you would like to deny Users from being able to edit comments once they have submitted them you would run cake acl deny Users Comments edit
Here is a great tutorial on ACLs, particularly the App_Controller code at the end which has a nice snippet that checks permissions for an ACO structure that matches controller/action: User Permissions and CakePHP ACL.
Additionally, the CakePHP Book has a nice snippet to insert all your controller/actions as ACO rules: An Automatic Tool for Creating ACOs
Related
I've got a simple ARO/ACO set up with simply all my users as AROs and all my Modules as ACOs and the ARO_ACOs table holds the permission rights.
This works great, except when I delete a User, I'd like to be able to clean up the ARO_ACOs and ARO tables by removing any entries associated with the ARO related to the user.
How do I go about this? The documentation is not helpful at all!
Using the ACL behavior? No action required
Assuming the acl behavior is in use, there's no need to do anything as it automatically deletes acl records for aros/acos, which will also delete the permission records at the same time.
I'm using CakePHPs ACL to handle user permissions.
When a user creates a, lets say Post, I automatically create an ACO for that post, and allow the user to access it.
But, if I would like to change the user later on so that a different user "takes over" the ownership of the post, what would I do in the ACL?
Is there a delete/remove ACL function I can use to remove rows, and the add the new relationship?
I thought about using deny on the old user, and then allow all on the new one, but it would be messy if the parent group has both allow/deny in the structure.
Are there any alternatives, other than using manual sql queries?
I'm implementing the ACL component for my CakePHP app (1.3.14). I have everything setup correctly, but there are a few areas where I'm still fuzzy.
Mainly, do I need to explicitly set rights (ACOs) for a special base user group (AROs)?
For simplicity, let's say I have Administrators and then everyone else (general users). So do I need to create a group for these general users and map all their allow rights? Seems like management of these rights would be never ending as the app grew.
Also, what about assigning users to multiple groups?
Ideally if a person had a user account the Auth component would grant access to the system as a whole. Then ACL would simply deny them from the sections that were protected by an existing group.
It seems like the coupling of ACL and Auth is too high. But it may be my new (limited) understanding. Any clarification would be greatly appreciated.
UPDATE
I've started a bounty. In summary, I want to implement CakePHP ACL (preferably, but a matching third-party component is acceptable) that meets/addresses the following:
Assign users to multiple groups
Easily maintain a "public" user group - don't have to constantly add the controllers/actions a general user can access
Code example of managing access to a controller/access
Code example of properly testing a user belongs to a group.
I think the best you can hope for using Cake's native ACL implementation is something like the following:
cake acl create aro root public
cake acl create aro root registered
cake acl create aro registered administrators
(create acos using AclExtras)
cake acl grant registered controllers
cake acl grant public controllers
cake acl deny public controllers/MySecureController
cake acl deny public controllers/Widgets update
cake acl deny public controllers/Widgets delete
(the above is all done through the cake shell, but is easily translated to the PHP variant)
Basically, you can either use a "default-deny" paradigm (as demonstrated in Cake's own ACL tutorial), or a "default-allow" paradigm as above. Whichever method you choose will depend on how you expect the application to grow: will most of your controllers be public with only a select few restricted to Administrators, or will most of your application be restricted with Public given specific access where needed? Either way, you still need to either grant or deny access.
Notice the two AROs created under root: public and registered. With this model, treat registered as if it were root when creating your ARO tree -- put all of your "real user" groups underneath it. That way, you can use ACL as normal on the objects under registered, and the public users will exist outside of that.
All that said, there's nothing stopping you from using Cake's authentication mechanism and rolling your own access control method. Here's an example: Simple Authentication and Authorization Application. (NOTE: This is written for CakePHP 2.0, but the concepts apply to 1.3 as well).
EDIT -
After re-reading the question and the other responses, I realized you're aiming more for a role-based access control model rather than the traditional one-aro-per-user model of the builtin ACL component. Here are a couple of examples of extending the built-in auth component for RBAC:
Role-based ACL in CakePHP
CakePHP Auth component: Users, Groups, Permissions
Also, this two-part article describes an approach to database-backed role-based authorization that can be applied to your Cake application.
You can have both ACOs tree and AROs tree. In the AROs tree you will have adminsGroup<-usersGroup. You will need to setup rights for these groups. In the ACOs tree you will have baseACO<-subACO<-treeOfACOsForUsers. You will not need to maintain any new ACOs if: 1) userGroups are allowed to use subACO, 2) any new ACO is a child of subACO. The idea is to organize a tree of ACOs, so that if you allow access to a parent all children are accessable automatically. You can have a branch with denied access also. So you will need to maintain (assigning permissions) only several branches close to the root.
You may be interested to look at my PoundCake Control Panel - a plugin implementing ACL with user friendly web interface (CakePHP v1.3 is supported).
UPDATE:
Here is what you need.
I (finally) got ACL to work properly, based on group permissions. However when I create a new user (Users/add) it automagically.. I mean.. autoinconveniently creates a User ARO..
While this is not really a big problem, I would like my ARO table to stay as clean as possible. Just my groups.
How do I disable the automatic creation of a User ARO object when creating a new user through CRUD?
i had the same problem and, like you, i said to myself "its not a big deal as long as it's working"... but when i started to have more and more users and when i added new groups, i found that ACL was not working correctly.. If you're using a group-based permissions, you MUST ONLY have groups in your AROS table.
Brief, the documentation says that you need to add the bindNode() in your Users model if you want a group-based ACL, but what they don't tell you is that for group-based permissions your User model doesn't have to implement the requester behavior and you don't need the parentNode() neither. Remove those two and it should be ok.
I added a note on the documentation, i hope it gets published :)
Good Luck
I am using Acl in new web app.
in my app there are four groups of users.
I have given $this->Auth->authorize = 'actions' so that it will check the permission for actions automatically.
my problem is some of the actions such as change Password,edit profile,etc...
are common to all users.
But now i need to create each record for the permission of each users in acos_aros table.
this is too annoying
1) Is there any way to give permission to all types of users with a single allow statement?
2) Is there any way to allow and deny user by checking whether parameter is passed or not?
that means i need to give permission to pass parameter to an action for a specific user. If any other user pass the parameter and try to access the data i need to deny them.
whether row level access control can be done with ACL?
Any help will be appreciated.
Thankz in advance :)
If you put a $this->Auth->allow('action1','action2'...) into your beforeFilter() of the controller, access is granted to all users. If you need an ACL-only solution, you have to create a parent aco to which all other acos you want to allow are children. Then grant your users the rights on the parent.
The ACL plugin from the bakery could come in handy, if you already have your ACL tree structure.
For building the ACL tree structure the build_acl() script in the tutorial at the end of the cake-manual is useful.
Allowing to pass the parameter for all users and checking their role in the action is not an option?
the solution for the 2nd problem is here
but this is not implemented using ACL :(