I'm pretty new to using CakePHP but I'm already finding incredibly useful for rapidly developing web apps.
However, I was wondering if there is a way to restrict access to certain objects in a non-standard way. For example, if I was to create a single CMS system allows users to create a "site", how can I assert that the users (multiples) have access to that particular site?
I could check this in my site controller but would I need to check this for every single controller on my site - for example, I would need to check that the current Page, News, Contacts, Files etc being edited belongs to the site ID and the user has access to edit it?
ie, thecms.com/pages/edit/123 (how can I be sure user 9 can edit page 123 which belongs to site 2)
I'm assuming this is outside of what ACL can offer as they're entity specific. Is there any easy way to do this?
I assume that you already know about CakePHP's Auth and ACL component, which can provide ways for restricting content. But it's also true what you say: that CakePHP's ACL is 'entity-specific' and not the best option for a 'per-record' basis (e.g. user 3 shouldn't access article 7). So I propose this code; try it and let me know:
Within the app/app_controller.php file:
<?php
class AppController extends Controller {
function checkPermission($aro, $aco, $loggedUserRole = 'User') {
if ($loggedUserRole != 'Admin') {
$permission = ($aro == $aco);
if (!$permission) {
$this->Session->setFlash('You cannot access that.');
$this->redirect('/somewhere');
}
}
}
}
Then, within the action that you want to restrict, put:
$this->checkPermission($this->Auth->user('id'), $someId, $this->Auth->user('role'));
So, the checkPermission() function does the following:
When called, you pass an id for the user you want to authorize, an id of the thing the user is trying to access, and also a role (so it is assumed that there is a column of 'Role' within the users table; also, $this->Auth->user('id')
means the user session data automatically stored by the Auth component). The checkPermission() method then checks if the passed role is not an admin (supposing there will be admins who will have access to all), and then checks equality of both the $aro and $aco parameters. If not, then it redirects somewhere with a message of 'forbidden'.
Now, the $aco parameter can be a variety of things. For example, suppose you are making a function for editing a user's account, which takes an argument of $userId. So you compare the logged-in user's id (from $this->Auth->user('id')
) with the passed $userId. If not equal, it means the logged-in user should not be editing that user record.
Another example:
You have an action for deleting an article, which accepts an $articleId argument. You can fetch the article from the database and then pass the article's user_id
value as the $aco, before deleting the article. Again, the logged-in user would be kicked out if such user_id
is not him.
I hope this solution serves you well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With