Reputation: 3164
I need a system that will allow users to modify data that is related to them.
Like a shopping center, with several stores and a shared catalog. I want the stores to be able to edit and add items, from and in, the global pool. but i want to limit the access of a store to its own items.
how it is done with acl & auth (the concept of course)?
Upvotes: 1
Views: 1058
Reputation: 20102
I've seen this question a few times. From the cake's doc it says:
Access control lists, or ACL, handle two main things: things that want stuff, and things that are wanted.
so in theory, you could handle all the items in your application using ACL, but I see a few problems doing that:
In my opinion, it's better to use the ACL to only grant permission to the controllers methods (CRUD) and manage the item permissions in your code by setting the condition in your queries:
$this->Items->find('all',array('conditions'=>array('store_id'=>$this->Auth->user('store_id'))))
But you might need to repeat this condition everywhere so you could create a Behavior that will modify the queries in order to add a condition in the WHERE clause, so you would always return/edit the items of the current store. For example, create a behavior like this:
/**
* Filter query conditions with the correct `type' field condition.
*/
function beforeFind(&$model, $query)
{
/**
* Condition for the paginators that uses joins
*/
if(isset($query['joins']) && !empty($query['joins'])){
foreach($query['joins'] as $key => $joinTable){
if(ClassRegistry::init($joinTable['alias'])->hasField('store_id')){
$query['joins'][$key]['conditions'][] = $joinTable['alias'].".store_id = '".$_SESSION['store_id']."'";
}
}
}
/**
* condition for the normal find queries
*/
if($model->hasField('store_id') && $model->name != "User"){
$query['conditions'][$model->name.'.store_id'] = $_SESSION['store_id'];
}
return $query;
}
In the controller I'd just need to call the find
method normally
$this->Items->find('all');
This way you don't have to make more queries to see if the user can access an item. I've used something like this on a website and it works fine for me.
Upvotes: 1