Restrict access to resources by resource ID in CakePHP using ACL - cakephp

Let's say I have a Project model and a User model in a CakePHP application. Using ACL I can control if users can access to projects and/or to particular actions in a ProjectsController.
But I would like to go further and control whether a user is allowed to view a specific project, e.g. accessing a project with id = 3 using a URL like http://example.com/projects/3.
Is this possible with ACL as well or I have to develop additional checks on top of it?
Thanks!

To restrict access to specific values of a model, you'll need to use something other than ACL.
It'll be best to define a relationship between the users and projects, whether that's inclusive or exclusive.
You're probably needing a ProjectUser model (HABTM in Project and User) and a simple function in that model, maybe userAllowed($projectId, $userId), that checks that the user has been given access to that project.

Related

CakePHP 1.3: Public User Profile With Routes Setup

All,
I have a CakePHP app I am developing with user accounts and some social interaction and I am looking to allow each user to have a profile and make it public and whatever information the user decides to make available. Currently the user is able to access his/her personal account at http://www.domain.com/account, but I want the user to also have a profile at http://www.domain.com/users/profile/user234.
What is the best approach?
Create a function profile($username) in my users_controller.php?
Create a profiles_controller.php to handle users profiles?
Is there a better way?
Or is there a CakePHP Profile Plugin available I can use
Also,
Is it possible to use CakePHP routes to have something like this: http://user1234.domain.com?
Thank you for you help!
1 & 2) Both ways work. I would put it profiles controller because its simply more logical but there is not real guideline for that. Usually you do things in the domain they belong to.
3) Not really.
4) Not for profiles but for the whole user thing http://github.com/cakedc/users But be aware that the profiles part is using a key/value storage for the fields of the profile. But you can simply change that by extending the plugins models and controllers on app level - OOP 4tw! :)
For subdomain routing you need to implement a custom route object. See this ticket related to that topic. http://cakephp.lighthouseapp.com/projects/42648/tickets/2429 Lookup the book.cakephp.org if you need to learn how to create custom routes. See http://book.cakephp.org/2.0/en/development/routing.html?highlight=router#custom-route-classes for CakePHP 2.0. And see http://book.cakephp.org/1.3/en/view/1634/Custom-Route-classes for 1.3.

CakePHP ACL: Is a base group/ARO required

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.

Using ACL or simple permissions for CakePHP app

I am building a simple website that needs 3 user levels (member, mod, admin) and am currently using ACL that sets permission on a per-group basis. Now, this is all working out fine, but I am wondering if it would not be better to just have a role column in the users table that would contain a tinyint and go with that.
Why I am considering this is the following. Say I wanted to have an "admin bar" on the top of the page, I'd have to check in which group the user is, but group names can change and are not static, the role column would be. This raises the question, is ACL suited for websites that have such a simple permissions scheme?
Funny - I just recently wrote a simple Auth for scenarios like that - I called it "Tiny": http://www.dereuromark.de/2011/12/18/tinyauth-the-fastest-and-easiest-authorization-for-cake2/
It should be pretty much exactly just about what you need.
It does need the roles to be present in the Session Auth, though and that you manage user roles yourself. So you might have to add this to your login method if you want to use multi role Auth.
As you said - the core one is way to powerful and a real overkill for simple use cases.
Just one thing: call the field "role_id" and not "role".
This is what i use http://bakery.cakephp.org/articles/watermark86/2010/09/23/user-permissions-based-on-a-routing-prefix
Though acl is the right way but for small/simple cases like urs you can use this

How do I build internal Access Control for site features in CakePHP

I went through the tutorials and examples on the CakePHP Acl and Auth components today in detail. I configured my Auth component to use $this->Auth->authorize = 'actions'. With this I was able to successfully restrict access to specific site actions without a problem.
However, my application needs to go a bit beyond this and I'm unsure of how best to accomplish my goals for this application.
Within the application that I am developing using CakePHP 1.3.8, there are specific "site features". For example, users of the application will have the ability to message one another.
I want to treat each message as an ACO so that I can control who can and cannot view or delete the message.
Another site feature is the earning of "badges" for achieving certain goals. For these badges I'd like to treat them as ACO's for the locking and unlocking of these badges.
I do not think that I can do this with the out-of-the-box ACL functionality of CakePHP as this goes beyond restricting access to actions. I'm looking for any ideas on how best to achieve this functionality.
With the standard ACL functionality in CakePHP it's only possible to create ACO entries for controller actions. This means that your setup (treating every single message as a seperate ACO) will not fly. Same as with badges.
For your messages I would go for a setup in which you would check in your view/edit/delete methods if a certain user is the sender or receiver of the message.
Something like
# in messages_controller
function view($id) {
if(!$isSender($loggedInUserId) || !$isReceiver($loggedInUserId)) {
$this->Session->setFlash("You're not allowed to view this message")
$this->redirect('index');
}
# do view stuff here
}
function edit($id) {
if(!$isSender($loggedInUserId)) {
$this->Session->setFlash("You're not allowed to edit this message")
$this->redirect('index');
}
# do edit stuff here
}
Regarding the badges, I would go for a regular HABTM (HasAndBelongsToMany) relation between a User and a Badge. When a User reaches a certain goal, you make a call like Badge::unlock($badge, $user) which saves the new badge for the user to the users_badges join table.
From there you can do basic stuff like listing all the badges for a certain user, etc.
I studied over Cake's Acl component much closer and figured that I could write something that sort of imitates this functionality for my internal "feature" access control. My thoughts are that I could have a Faro (Feature access request objects), Faco, and Facos_Faros table. Faco and Faro will have a HABTM relationship. I could then create my own component that manages it all.

CakePHP ACL use case(s)

I have got a simple web app in development, i want to establish a couple of user groups; Admin, Doctors & Patients.
Each group would have their access restricted to particular controller actions rather than individual content. So for example, Doctors can view patient records (index & view actions), but cannot delete them.
Usually i would create a groups model, and assign the various users to a group. And filter in the beforeFilter() method to determine if the user has access. But if ACL can do the job, why right the code, right?
Thanks
You do not need to filter in the beforeFilter() method to determine if the user has access but you need to provide configuration to Auth component there. Follow Simple Acl controlled Application from tutorial (Setting up permissions).

Resources