开发者

How to limit data to users who own it without limiting admin users in CakePHP?

Currently I am writing an application where I have multiple 开发者_JAVA技巧users. They have data that should only be visible to them and not the other authenticated users in the system. I also have administrators who manage the system and have access to all of the information. What is the best way to limit users to their data without limiting admin users?

Currently I am using a callback to limit the queries by user, but the admin will get the same limits. So I need to know a better way to do it. More importantly, the right way to do it.

For example, I want the standard user to be able to see their user information only and be limited to CRUD operations on their information only. The admin, however, should be able to see ALL users and CRUD ALL user data. Any ideas?


You need:

  • Information about the current user
  • Information about the item in question

You combine them with something like this (simple example):

$user = $this->Auth->user();
$book = $this->Book->find(…);
if ($user['type'] != 'admin' && $user['id'] != $book['Book']['creator_id']) {
    $this->Session->setFlash("You're not allowed to view this item");
    $this->redirect('somewhere');
}

You could make a method in your model like

function userCanAccessItem($item, $user)

to centralize the logic for the access check and call it from your controller.

Better yet, if you're using Cake's admin routing, you can omit all checking in the admin_ actions and only apply normal user access privilege checking in the user accessible actions.

You may also want to look at ACLs for more fine-grained access control.


You can get the current user info this way: $this->Auth->user(). You can use the user group id in your callback to limit the query. Also take a loot at WhoDidIt Behavior.


For any one else who comes here this is how I set it up.

First I set up a basic Role based ACL

Then I deny access to reports/all for normal users

$config['rules']['deny'][reports/all'] = 'Role/default' ;

Then in the model that I wanted to protect I added this:

public function beforeFind($queryData){
    //TODO:make this cleaner
    App::uses('ComponentCollection', 'Controller');
    App::uses('AclComponent', 'Controller/Component');
    $collection = new ComponentCollection();
    $this->Acl = new AclComponent($collection);     

    if(!$this->Acl->check(array('User'=>AuthComponent::user()),'/reports/all/')){  // must be a user (not admin)
        $this->bindModel(array('hasOne' => array('ReportsUser')));
        $queryData['conditions']['ReportsUser.user_id'] = AuthComponent::user('id');
        $queryData['recursive'] = 2;
    }
    return $queryData;
}

On the cases where ACL doesn't allow access to reports/all we add a condition to any find queries so it only shows reports with the correct user_id.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜