Using ACL or simple permissions for CakePHP app - cakephp

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

Related

Role based access control pattern design

I'm currently working on a project where a user can have many roles, and each role has assigned one or many permissions. Permissions describe the actions that a user can apply to ressources. For example let's consider that I have three ressources that I can interact with using my API : users, books, payments.
I'd like to have all users able to update their personal informations like phone number... etc. This led me to give update permission on user's ressource for all users. But the problem is that I want them to be able to updates their own profiles only. Furthermore, some users have admin permissions and can change other users permissions, therefor they have another kind of update permission on user's resource.
So my question is : what's the best way to design the permission table. Below you can find my schema design. Thank you for your answers in advance.
User(firstName string, lastName string, roles Role[])
Role(name string, description string, permissions Permission[])
Permission(name string, effect 'Allow' | 'Deny', resource string, action string)
Well I am not entirely sure what you meant by resource and action. If you meant URI template and HTTP method, then ok. Otherwise you might need a different solution or somehow add parameters to your design if you want to allow or deny individual resources per id.
If we are talking about a REST API, which I assume, then you can do something like PATCH /api/v1/current-user/profile {...} for updating your profile and PATCH /api/v1/users/{user-id}/profile {...} to update somebody else's profile. If you meant controller classes and their methods, then you can do the same with two different controllers, something like CurrentUser.partialUpdate(params) and User.partialUpdate(params).
As of updating user permissions, I wonder how to do it, because you can update only role permissions and give or take away roles for the users in your model.
Another thing I don't understand that why do you need the allow|deny flags. If roles collide because users can have multiple roles or permissions collide, because you can both allow and deny the same thing, then how do you resolve it without a hierarchy? And if you don't have a hierarchy, then this flag is completely useless and just deny all and allow what is added to the role.
As of the one user multiple roles approach it is not a great idea, at least in places where people take security seriously a single account or at least a single session can have only a single role. Since this would make a lot of repetition I would solve this on a role level and make composite roles or support role inheritance. So for example the Administrator role would be the composite of the OwnProfileEditor and ProfileEditor sub-roles, which I would rather call Features or Capabilities or PermissionGroups rather than Roles.
Usually RBAC is not that flexible, so people tend to add per User Permissions to override Role Permissions. I would not do it, because you will end up with a mess if you follow that approach.

Multi guards authentication VS User Type authentication

I'm wondering about which approach is better using multi auth with guards and different auth tables Or using the same auth table with different roles/Types in this scenario
let say we have two different users types "doctor" and "patient" each of them has totally different profile data
If we use multi-auth we can set all user's data with auth data in the same table but we will repeat ourselves if we have a model that belongs to the two users types let say "Hospital" and we will check on guards everywhere.
On the other hand, if we implement roles or types we have to split profile data into three separate tables one for users auth data(email, pass,..etc) with polymorphic relation with others for user-related data let say (patient-data and doctors-data)
but we have to join everywhere we use user data.
There may be a better solution and I know that there is no absolute right solution I am looking for an answer based on previous experiences in terms of performance and the possibility of expansion.
I would always go with the roles/permissions way for the authentication part. This way you can just have one way to log in.
You can split the login form or you can use the same form for all roles. Based on their role you can redirect them to another page where they can see their actions. For example, a separate vendor dashboard. You can use different login URLs of course where you only allow users to login with a certain role. This is a small adaption to the current login flow by just checking on the role as well. You can even create your own controller for it if needed.
You can always use middleware or permission based on the current role of the user to determine where they can go or what they can see.
Multi auth always makes it more complex, while in your case you just have users that log in but have different permissions

Django change user group to oneToOne Field

I want to create multiple levels of users in my application developed using django1.6 and python 3.2. I inserted the levels in auth_group table. but in the add user page of Django Admin I can assign one user to more than one group(multiselect Group values). Actually I want is one user to one Group only.
Please reply me.
Definitely change the django core is not an option. You shouldn't never do it because in the future you will have problems to update your system to the new django versions,
I can't see clearly why you want to do it but if you really think is a good implementation you should extend your Authentication model to implement what you need:
https://docs.djangoproject.com/en/dev/topics/auth/customizing/

Suggestions for creating a multi-blog site in CakePHP with ACL 'memberships'

I've been diving into CakePHP this year and I'm loving it! However, I've just run across a problem that I'm not sure how to handle. My database design is this--
USER can belong to one or more WEBSITE
A WEBSITE can have many USER
So I have a many-to-many relationship which is tracked in MEMBERSHIP
MEMBERSHIP also tracks what group_id the USER has for that WEBSITE.
For example, if user1 joins website3 as an administrator and website5 as a editor, then the MEMBERSHIP table has an entry reflecting both those roles.
Basically my problem is Cake's ACL. In the above-mentioned model, user1's group_id would change depending on which WEBSITE he's selected after logging in. (And he could subsequently change to even more websites within the dashboard by changing the group_id again and again). Cake's ACL appears to only handle 'user belongs to one group' period.
Can I trick the ACL by giving it the group_id from the session every time its changed and then reload the AROs? Would it make more sense to scrap ACL and create my own permissions module?
Any suggestions or ideas to point me in the right direction would be GREATLY appreciated!
i think it will be the best way to create your own permission module.
the reasons are quite simple:
you can modify/extend it in any way YOU want
you will not break any cakePHP specifications

Creating a login like Basecamp in CakePHP

I am trying to create a basecamp like login where users can login to see their companies projects using the url:
http://abc.com/companyname/
I dont know how to create a 2 level auth... (one at the company level and another at the user level)
I am new to cakePHP and I dont know how to modify the in built Auth component for my requirement.. Any help would be grateful...
I would use the Auth component for the login. I wouldn't mess with the ACL and stuff as that's pretty confusing I find.
I would approach this by adding a user_level, access_level, or permissions column in your users table. Then in here you can store a numerical value or similar.
Then in the User model, when they login using Auth you can store that value in the Auth user session object. So you can get at it using $this->Auth('User.access_level') in your controllers.
Now the Auth component by default has an isAuthorized() function in the app_controller. This function is called to see if someone has logged in. You can modify this to check that access_level and take action appropriately. I used this technique so that users can't get into the /cms routing unless they are admin = 1.
There is more information on this in the docs, http://book.cakephp.org/view/172/Authentication and you can find out more about isAuthorized() here, http://api.cakephp.org/class/auth-component#method-AuthComponentisAuthorized
Do make sure that you setup all your Auth component variables in your app_controller. Also make sure that your auth type is set to controller, and that you're allow() and deny() are configured properly.
The one big catch with all this, is that if you using a beforeFilter() in your controllers, you will need to make sure to do parent::beforeFilter() to ensure that the stuff in the app_controller is run beforehand :)
Honestly, I think that you should check out the ACL component. The book tutorial is very good if you follow it through. The major caveat is that it does not provide a mechanism for row-level access control (e.g. can user X edit this particular entry). However, it does provide a basis for doing user/group level access control, which you can then extend yourself to create the row level access you require.
In short, the ACL component supports cascading permissions (e.g. subgroups can have finely-grained access control, but otherwise inherit permissions from the parent group). That can make life a lot easier, if you need both robustness as well as granularity.
You might also check out the bakery, as there are additional auth components written by the community that may serve what you need. Highly recommended, as Auth/ACL stuff is difficult to do well, and always a major concern with web apps.

Resources