CakePHP 2.3: Filter find results based on current user

848 Views Asked by At

I have models with the the following relations, defining a situation where users can belong to many groups, and multiple groups can be granted access to a project.

User HABTM Group HABTM Project

I would like to set things up so that any find() done on the Project model will only return results to which the current user has access, based on her group membership.

My first thought is to use the beforeFind() callback to modify the query. However, the two-level association has me stumped. I solved a similar problem (see this question) by rebinding models. However, that was for a custom find method—I don't think that approach will work in a general situation like this where I need to modify arbitrary queries.

Using afterFind() to filter results isn't a good idea because it will confuse pagination (for example) when it doesn't return the right number of records.

Finally, I have a nagging suspicion that I'm trying to re-invent the wheel. The access control I've seen in CakePHP (e.g. Cake ACLs) has been at the controller/action level rather than at the model/record level, but I feel like this should be a solved problem.

Edit: I eventually decided that this was over-complicated and just added a getAccessibleByUser($id) method to my Project model. However, I'm still curious whether it's possible to globally add this kind of restriction to all find() operations. It seems like exactly the sort of thing you'd want to do in beforeFind(), and I suspect (as DavidYell suggests below) that the answer may lie with the Containable behavior.

1

There are 1 best solutions below

2
David Yell On

You should look at the Containable behaviour. If you are using CakePHP 2.x then it comes in the box.

This behaviour allows you to manage the model relations and the data which is returned by them, along with allowing you to pass conditions, such as a group_id into your contain.

http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html