Re: Using ACL to limit access to data
Hello, This may be bit OT now and should belong under Tree Traversal Methods, however I just wanted to maintain a coherent thread so that I can easily find it later on. I have been looking back at the top of this thread to see if I missed anything at the same time I kept looking back as to why I used a recursive approach to building the tree traversal data for my MPTT implementation. As I said earlier, it's been about three months since I last touched the implementation found here: http://abing.gotdns.com/wobject.php.html Setting all other fields aside, here are the important fields for a node in the object tree: id = object's ID parent_id = object's parent ID lft, rgt = fields for MPTT data link_order = indicates position of a node relative to its siblings Looking at these fields, one can say that parent_id and link_order are not needed. Ordinarily the recursive approach to rebuilding the MPTT data every time the nodes are updated is also not needed. MPTT was developed to remove the need for recursion in tree traversal. Looking back at the notes I have on paper, I remembered why I made the decision to include these redundant fields. Here are the use cases for my system that warrant such fields: * Inserting a new node in an arbitrary position within a subtree. There are three cases for this. Each case requires finding a specific node in the subtree and making sure (for validation purposes) that node is the one we want. 1. Insert a new node at the beginning of the subtree. We need to find the first child node of the parent node. This can easily be found with WHERE Node.lft=(ParentNode.lft + 1). This needs two queries, one to obtain the node data of the parent node and another one to find the node itself. With adjacency list, only one query is needed. 2. Insert a new node at the end of the subtree. We need to find the last child node of the parent node. This can easily be found with WHERE Node.rgt=(ParentNode.rgt -1). This is similar to case #1. 3. Insert a new node right after a specified sibling node in the subtree. This was where things got a bit sticky. How do you find out if a node is an immediate child of its parent? The best, MPTTish way I could come up with was to issue a query to find *all* the nodes under our parent and then traverse it to find the all the immediate children of our parent. This does not scale very well with very large subtrees. The solution I finally decided on is to combine the MPTT approach with the adjacency list approach and maintain a parent_id and a link_order field for each node. Then it was only a simple matter of having WHERE Node.parent_id=(ParentNode.id) AND Node.link_order=Position. There are probably better ways of doing this and I would gladly explore the alternatives when I find the time. However, there is another use case that warrants this decision. Which leads us to... * Obtain a list of immediate child nodes and be able to paginate them. This is where I needed adjacency list approach. As I mentioned above, I could not think of an easier (read: obvious + generic) way to obtain the immediate child nodes of a chosen parent using only the MPTT technique. Once I was able to solve those problems, the other operations/use cases (arbitrary node reparenting, node removal, node deletion) are easily solved by using a combination of adjacency list and MPTT. Finally, as for the recursive _rebuildTreeTraversalData() method, it's a bit of a misnomer as it not only rebuilds the tree traversal data, it also rebuilds and fixes any discrepancies in the adjacency list data when nodes are moved around in the whole tree. I also wrote it so that _rebuildTreeTraversalData() tries to avoid calling itself as much as possible. As for handling ACL, I was looking at this particular implementation at the time: http://phpgacl.sourceforge.net/ There is a demo here: http://phpgacl.sourceforge.net/demo/phpgacl/admin/acl_list.php However, I must admit that I have no idea if this implementation scales better than the CakePHP implementation. But judging from the database schema here: http://phpgacl.cvs.sourceforge.net/phpgacl/phpgacl/schema.xml?view=annotate the project also uses MPTT and it would be interesting to see if and how their implementation handles the case presented by Dr. Tarique. -- _nimrod_a_abing_ [?] http://abing.gotdns.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
Thanks for the explanation Nimrod. Interesting reading. Langdon This may be bit OT now and should belong under Tree Traversal Methods, however I just wanted to maintain a coherent thread so that I can easily find it later on. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
Hi abing and all, I heard on the grapevine that the acl code is currently being refactored, so some of what I write below may be obsolete before too long. On Jan 3, 4:09 am, Nimrod A. Abing [EMAIL PROTECTED] wrote: snip I have tried using a stack-based algorithm instead of recursion, but surprisingly(?!?) it eats up more memory than the recursive version. Probably because I'm storing objects (which is needed) into the stack. I'm interested in hearing about others' experience with MPTT implementations using both the stack-based and recursive approach. Unless I misunderstand and you are not talking about deleting a single (group of) nodes, moving a single (group of) nodes or creating a single (1) node; updating MPTT tables recursively is unnecessary. For deleting a node or group of nodes, the acl_node class already takes care of this with a minimum of sql and affected rows. To clarify what I mean for moving (groups of) nodes, and ignoring that a person has 2 parents :), consider I accidentally put Uncle bob under the wrong grandparent whilst building my family tree. The sql that puts Bob and all of his children, grandchildren etc. in the right place should action everthing under Uncle bob as a whole - not each of his family members individually in a recursive manner. Irrespective of the size of Bobs family the following sql would be executed: 1) change the lft and rght fields for Bob and all children such that the branch is moved out of the tree leaving a hole. 2) change the lft and rght fields of everything inbetween where Bob was to where he needs to be such that the hole is under Bobs Parent. 3) change the lft and rght fields for Bob and all children such that the branch is in the right place and Bob has the right parent. There are never more than 6 sql statements to move a node or group of nodes; and rows that don't need to change are unafected (only the rows inbetween where Bob and his family now are and were they where are afected). I added to the following ticket a while ago https://trac.cakephp.org/ticket/1234 regarding this. The online acl admin demo allows you to move things around to test this change if you are curious. See http://www.noswad.me.uk/AclAdminDemo/aros (use the Load from user table link if no aros present) or http://www.noswad.me.uk/AclAdminDemo/acos (create something if no acos present and go to the data view) and use the Move this - form to reparent something(s). The exact code in use for the demo, incase there are any differences with the ticket code can be seen here: http://www.noswad.me.uk/AclAdminDemo/acl_node (set parent method) I have a partially finished MPTT behaviour, which was based upon the acl_node class and has some additional functionality namely reordering without reparenting using the above logic (so for example, you could if you really wanted use it to design your multi-level menu. and move option 1.1.1.15 to position 1.1.1.7 by reordering up 8 steps). If there are any other MPTT functions that are of interest (I can't think of any) I'd be glad to hear of them. Dr. Tarique Sani: I wonder if that book mentions leaving data holes between tree nodes (akin to numbering lines as 10,20,30 in BASIC such that you can create line 15 if you find you need to add something without renumbering the whole file). Means that some functionality is lost ( you can't know how many children a parent has without specifically searching), but I can't think of any other way of handling frequent inserts. HTH, AD7six Please note: The manual/bakery is a good place to start any quest for info. The cake search (at the time of writing) erroneously reports less/no results for the google group. The wiki may contain incorrect info - read at your own risk (it's mainly user submitted) :) You may get your answer quicker by asking on the IRC Channel (you can access it with just a browser here:http://irc.cakephp.org). --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
Hi abing and all, On Jan 3, 12:50 pm, Nimrod A. Abing [EMAIL PROTECTED] wrote: snip Will this be available on the 1.2 or 1.1 branch or both? I assume 1.2 only. snip http://www.sitepoint.com/print/hierarchical-data-database I maintain that recursion isn't necessary to display MPTT tables. Anything that is recursive or converts MPTT tables to nested arrays is not exactly using the benefits that the DB structure offers ;). For inserts, I am talking about inserting a single new node in an arbitrary parent. For example, inserting a new node under Meat, say Chicken. I want to insert it so that it goes in between Beef and Pork. i.e., We end up with Beef, Chicken, Pork under Meat. The logic necessary to add a new node in the middle of it's siblings isn't very different from adding a new node and then reordering. The minimum executed sql is about the same as creating alone - slightly different ofsets. snip For reordering, I am talking about moving a node within its subtree changing its left to right order. In the example above, say I change my mind and switch Beef and Pork so that we end up with Pork, Chicken, Beef. This is what I have currently developed and am testing in the MPTT behaviour. For deletes, when I delete a non-leaf node, all of its children will be reparented to the immediate parent of their parent. snip Delete does not seem to work as I expected in the aros example. I get the message aro Daniele (and any child aros) deleted. This does not conform to my requirement that its child nodes be reparented to their grandparent. What I need is akin to a child being orphaned and sent to their grandparents when their parents die. Though deleting the children of a node makes much more sense when we are talking about filesystems. I have never heard of or considered this case. Why would you want to do that exactly? It seems perfectly logical to me that if you delete a node you also want to delete it's children. But in any case, the sql to do what you have explained isn't much different than deleting a node and all children (would just need to delete the node, re-index the children -1, the 'new' parent right field -2 and all subsequent nodes -2.) I just don't understand why you would want to. snip Comments are very much welcome. Though at this stage, I am thinking of rewriting the whole thing to use the implementation described here: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/461776 Adding redundancy like that will make some tasks simpler but I wouldn't expect it to help with any of the problems that having large tables would cause. But variety is what spawns new ideas so if you go that route I'd be interested to see what you come up with ;). HTH, AD7six Please note: The manual/bakery is a good place to start any quest for info. The cake search (at the time of writing) erroneously reports less/no results for the google group. The wiki may contain incorrect info - read at your own risk (it's mainly user submitted) :) You may get your answer quicker by asking on the IRC Channel (you can access it with just a browser here:http://irc.cakephp.org). --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
Hello, On 1/3/07, AD7six [EMAIL PROTECTED] wrote: Hi abing and all, On Jan 3, 12:50 pm, Nimrod A. Abing [EMAIL PROTECTED] wrote: snip Will this be available on the 1.2 or 1.1 branch or both? I assume 1.2 only. Oh well, I might as well port my CMS to 1.2. A lot of the new stuff in 1.2 seems to cover the things that I found lacking in 1.1 that prompted me to start some modifications to the core CakePHP code. snip http://www.sitepoint.com/print/hierarchical-data-database I maintain that recursion isn't necessary to display MPTT tables. Anything that is recursive or converts MPTT tables to nested arrays is not exactly using the benefits that the DB structure offers ;). You're absolutely right about not requiring recursion. Been looking at your code as well as the AclNode implementation. But there is one case I can think of where recursion is necessary. See below. For inserts, I am talking about inserting a single new node in an arbitrary parent. For example, inserting a new node under Meat, say Chicken. I want to insert it so that it goes in between Beef and Pork. i.e., We end up with Beef, Chicken, Pork under Meat. The logic necessary to add a new node in the middle of it's siblings isn't very different from adding a new node and then reordering. The minimum executed sql is about the same as creating alone - slightly different ofsets. I remember now why I used recursion. I was not able to come up with an ideal and generic way to compute the offsets for abitrary reordering and moving. I was in a hurry so I went with the recursive approach. For deletes, when I delete a non-leaf node, all of its children will be reparented to the immediate parent of their parent. snip Delete does not seem to work as I expected in the aros example. I get the message aro Daniele (and any child aros) deleted. This does not conform to my requirement that its child nodes be reparented to their grandparent. What I need is akin to a child being orphaned and sent to their grandparents when their parents die. Though deleting the children of a node makes much more sense when we are talking about filesystems. I have never heard of or considered this case. Why would you want to do that exactly? It seems perfectly logical to me that if you delete a node you also want to delete it's children. But in any case, the sql to do what you have explained isn't much different than deleting a node and all children (would just need to delete the node, re-index the children -1, the 'new' parent right field -2 and all subsequent nodes -2.) I just don't understand why you would want to. This is application-specific. I wanted there to be an option for a user, if a node is deleted and it contains children, the user should be able to chose from two options: A.) Delete everything under the node that is about to be deleted; or B.) Delete the node, but reassign all children to their grandparent. Use case A is the most common case. B is for those cases when you want to just be able to reduce the number of levels in a particular subtree. This is because reparenting the child nodes of a node one by one and deleting the empty node takes much more effort (on the part of the user) than simply deleting the node and reparenting its children in one go. snip Comments are very much welcome. Though at this stage, I am thinking of rewriting the whole thing to use the implementation described here: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/461776 Adding redundancy like that will make some tasks simpler but I wouldn't expect it to help with any of the problems that having large tables would cause. But variety is what spawns new ideas so if you go that route I'd be interested to see what you come up with ;). I most certainly will try it out. But if it falls flat on its face, I can just use your MPTT code :) -- _nimrod_a_abing_ [?] http://abing.gotdns.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Tree traversal methods - Was: Using ACL to limit access to data
I was monitoring the other thread you started and I was not aware of this new thread. Anyway, just read my last two replies to your original thread to get a picture of what I am trying to use MPTT for. I took a recursive approach for rebuilding tree traversal data for reasons described in my last two replies to the original thread. The recursive approach at the time seemed to make sense and offered better DRY possibilities in terms of not having to write and maintain a separate set of queries for each function applied to the tree. I also posted a link to my current implementation. I made a few optimizations so that recursion is used only when absolutely necessary. But as AD7six points out, it is possible to rebuild the tree traversal data without resorting to recursion (as is being done by the current AclNode implementation). On 1/3/07, Langdon Stevenson [EMAIL PROTECTED] wrote: Hi Nimrod This discussion has peaked my interest in MPTT implementations. I am working on an object system for a CMS based on CakePHP and the object tree is implemented using MPTT. I did a textbook implementation of the thing, which means using a recursive algorithm to reorder the tree traversal data (lft and rgt) for each tree node in for inserts and deletes. Tree traversal methods are not in my area of expertise unfortunately (I am better at using the tools given to me), so excuse me if I can't add much to this sub thread. I am however very interested to hear what you have to say on the subject :-) Regards, Langdon -- _nimrod_a_abing_ [?] http://abing.gotdns.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Tree traversal methods - Was: Using ACL to limit access to data
I don't have that book. But the best link that I can find about the subject (with an example in Access 2000) is here: http://www.mvps.org/access/queries/qry0023.htm I'm not on Windows right now and I haven't looked into it yet to see if this is what you mean. On 1/3/07, Dr. Tarique Sani [EMAIL PROTECTED] wrote: On 1/3/07, Langdon Stevenson [EMAIL PROTECTED] wrote: This discussion has peaked my interest in MPTT implementations. I am working on an object system for a CMS based on CakePHP and the object tree is implemented using MPTT. I did a textbook implementation of the thing, which means using a recursive algorithm to reorder the tree traversal data (lft and rgt) for each tree node in for inserts and deletes. Tree traversal methods are not in my area of expertise unfortunately (I am better at using the tools given to me), so excuse me if I can't add much to this sub thread. I am however very interested to hear what you have to say on the subject :-) If I am not mistaken Joe Celko's book on Nested Tree sets has a chapter on what to do when your trees need frequent inserts /me adds TODO: to find that book Tarique -- = PHP Applications for E-Biz: http://www.sanisoft.com Cheesecake-Photoblog: http://cheesecake-photoblog.org = -- _nimrod_a_abing_ [?] http://abing.gotdns.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
On Dec 31 2006, 1:30 pm, Langdon Stevenson [EMAIL PROTECTED] wrote: snip Langdon Oh the joy, my message went missing - sorry for the pseudo-duplicate if it turns up. I had a thought regarding the originally posed problem, so thought I would reply. ACL doesn't lend itself very well to limiting multiple result sets. but then it isn't really designed to. Generally speaking I see 2 means of limiting access: 1) adding a field to the relavent table (access_level = 1,2,3) and adding a condition such that only data meeting the condition is returned (access_level = $userAccessLevel). Obviously this doesn't use ACL at all, but then ACL isn't always the right solution. 2) Using ACL and cheating. What do I mean? Consider wanting to find all albums that Bob can access. First see if Bob has access to Albums in general, by checking if he has access to the ACO parent for all albums ( $this-checkAcl (Bob,Albums,'*'); ) Given that, unless there is a rule denying access to Bob (or one of Bobs parents) to an album, he has access. The below pseudo code isn't complete, I realised whilst writing it that if one of Bobs parents is denied access but Bob himself (or an intermediary parent) is granted access, Bob would still get denied. However I include the code for comments... function index() { $Constraint = $this-_getSubQuery(); $data = $this-Album-findAll($Constraint,NULL,$order, $limit, $page); $this-set('data',$data); $this-render('index'); } function _getSubQuery() { $user = $this-Session-read('User.username'); $aro = $this-Aro-findByAlias ($user); $aroLft = $aro['lft']; $aroRght = $aro['rght']; $SubSQL[] = NOT EXISTS ( SELECT Album.id FROM `Albums`as Album, `acos`, `aros_acos`, `aros` WHERE `acos`.`alias` = CONCAT('Album:', `Album`.`id`) /* Will bomb out if there is no specific ACO for that album */ AND `aros_acos`.`aco_id` = `acos`.`id` /* Will bomb out if there is no specific rule for this album */ AND `ArosAco`.`_read` 1, /* Only succeed for deny rules */ AND `aros_acos`.`aro_id` = `aros`.`id` /* Ties the results to the found aro/user/group */ AND `aros`.`lft` = $aroLft /* Ties the results to Bob or his parents */ AND `aros`.`rght` = $aroRght /* Ties the results to Bob or his parents */ ORDER BY `aros`.`lft` DESC, /* Find the rule for Bob First, his lft field is higher than all his parents */ `acos`.`lft` DESC /* Find the rule for The album First, it's lft field is higher than all it's parents */ ); return $SubSQL; } So, anyone willing to pickup the baton and comment on whether this could work? Be made better-er, or differently? HTH, AD7six Please note: The manual/bakery is a good place to start any quest for info. The cake search (at the time of writing) erroneously reports less/no results for the google group. The wiki may contain incorrect info - read at your own risk (it's mainly user submitted) :) You may get your answer quicker by asking on the IRC Channel (you can access it with just a browser here:http://irc.cakephp.org). --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Tree traversal methods - Was: Using ACL to limit access to data
Here you go: http://groups-beta.google.com/group/cake-php/browse_thread/thread/263d3ffd6fb7533d I need to get back to work :) I'll keep monitoring both threads for any new developments. I'll also be taking a look at implementing the alternative tree traversal method that I pointed out. When I find the time I will try to write a benchmark, say 1,000 - 10,000 nodes, unless someone can point me to an already existing benchmark for this. On 1/4/07, Langdon Stevenson [EMAIL PROTECTED] wrote: Hi Nimrod I was monitoring the other thread you started and I was not aware of this new thread. Sorry, could you point me to that thread please? I can't seem to find it in my mail history :-( Regards, Langdon -- _nimrod_a_abing_ [?] http://abing.gotdns.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Tree traversal methods - Was: Using ACL to limit access to data
Thanks Nimrod, I forgot that I changed the subject line ... Here you go: http://groups-beta.google.com/group/cake-php/browse_thread/thread/263d3ffd6fb7533d I need to get back to work :) I'll keep monitoring both threads for any new developments. I'll also be taking a look at implementing the alternative tree traversal method that I pointed out. When I find the time I will try to write a benchmark, say 1,000 - 10,000 nodes, unless someone can point me to an already existing benchmark for this. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
On 1/4/07, AD7six [EMAIL PROTECTED] wrote: 1) adding a field to the relavent table (access_level = 1,2,3) and adding a condition such that only data meeting the condition is returned (access_level = $userAccessLevel). Obviously this doesn't use ACL at all, but then ACL isn't always the right solution. I would bet my money on a non ACL approach for limiting access to multiple records/sets and using ACL for things which operate on a single records So you end up with a part which is application specific and a part which is ACL dependent and generic 2) Using ACL and cheating. What do I mean? Consider wanting to find all albums that Bob can access. I guess what I have said above borders on ACL + Cheating :0) Cheers Tarique -- = PHP Applications for E-Biz: http://www.sanisoft.com Cheesecake-Photoblog: http://cheesecake-photoblog.org = --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
Hi Tariqu This implies heavily that limiting the number of Acos is the key. Can you give an example of how a user may accumulate large numbers of Acos? Yes, if you see to my previous example - getting in findAll* which pictures/albums/categories a user is allowed to see (depending which group she belongs to) you will soon have a large number of ACOs That's true, if users are able (and likely) to belong to many groups that have lots of nesting. In my system that will never happen, as the business rules and nature of the system limit the number of Acos per user. I think that you are probably right. The question then becomes: is this a problem? If so, why is it a problem? The problem for me is what would be a DRY way to do this. I very easily can do it the usual way by adding criteria to findAll or even some funky bindModel stuff, but this way there is access restriction code in almost every controller / model. A valid point. I had thought about looking into redeclaring the find functions so that they inserting the criteria into the query automatically. That would remove the requirement for adding the criteria to each query in a model. It would also have the advantage of reducing the potential for security holes. The more I think and talk about the problem, the more I get the impression that there really is no simple, easy solution. If we want to have the power and flexibility of ACL, with its ability to nest groups of AROs and ACOs then we have to pay the price for that and provide sufficient processing power to support it. Regards, Langdon --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
On 1/2/07, Langdon Stevenson [EMAIL PROTECTED] wrote: The more I think and talk about the problem, the more I get the impression that there really is no simple, easy solution. And that is what I am not ready to accept as yet ;-) but the sinking feeling is there. Cheers Tarique -- = PHP Applications for E-Biz: http://www.sanisoft.com Cheesecake-Photoblog: http://cheesecake-photoblog.org = --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
The more I think and talk about the problem, the more I get the impression that there really is no simple, easy solution. And that is what I am not ready to accept as yet ;-) but the sinking feeling is there. Perhaps it's a matter then of more horse power? It would be interesting to do a cost benefit analysis on a problem like this. What we seem to be talking about is creating an entirely new method of defining and retrieving our security information hierarchy, something different to modified preorder tree traversal. This is where I get scared and run away! I have done a bit of Googling on the subject and for now MPTT seems to be the peak of the art. Regards, Langdon --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
I've been thinking about this for a while (and am going to have to *do* it in the next week or two:). I plan to specify a 'securing_attribute_name' for each model - set to a default false in AppModel. For your example, the the securing attribute may be 'group_id' on an Album or 'Album.group_id' for a Picture (this assumes a Picture belongsTo an Album and is never fetched without it's parent). The securing attribute (group_id) can be de-normalized for performance or if secured models are likely to be unbound from their parents. In the beforeFind() of AppModel, the conditions get modified to compare the User's securing_attribute_id (may also be an array) to the column specified in securing_attribute_name (either '=' or 'IN (...)'). That's the easy bit. Where I get a bit stuck is in the integration with cake's acl (probably because I'm not yet familiar enough with it). The securing_attribute_id could be per user (if the user has access to the same group of data for all roles) or per role (where the user access different groups of data dependent on the role they are currently in). Ideally, I think it would be useful to be able to set an additional column (securing_attribute_id) on the aco_aros table ( see https://trac.cakephp.org/ticket/1846 ). In my implementation, I will probably turn it on it's head and set the aco's based upon the secured object last accessed (i.e. if you want to modify a picture, then you must navigate via an album which will load the aco's you have been assigned for that album). This way the user_id and secring_attribute_id become the primary key to select the aco's, mitigationg some of the performanc issues with extra large datasets. ~Philip Dr. Tarique Sani wrote: On 1/1/07, Langdon Stevenson [EMAIL PROTECTED] wrote: Can you elaborate on your requirements a little further? Perhaps I am missing something? Let me give a real-life example. The largest known installation of Coppermine Picture Gallery (an Open Source project that I lead) has more than 3 million pictures and approx 100,000 users. As long as all the pictures and albums were public this was not a big problem. However Coppermine has a concept of user albums and private albums and password protected albums which can be or cannot be seen by public - the webmaster turned on the private albums feature and the hell broke loose as the queries started including criteria like aid NOT IN (1,5,.. long list of aids) and the looping checks were just too much. Coming to cakePHP perspective - I am currently wondering on how to exclude certain records from model-findAll* calls using the current ACL techniques. Actions which return or affect just one record will be no big deal atleast for some time but as the ACOs increase (in the above case 3 million +) performance will start to slow down even in those cases. That said I have to agree that example given by me is a rare one but at the same time a very plausible one. Cheers Tarique -- = PHP Applications for E-Biz: http://www.sanisoft.com Cheesecake-Photoblog: http://cheesecake-photoblog.org = --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
On 1/2/07, Langdon Stevenson [EMAIL PROTECTED] wrote: What we seem to be talking about is creating an entirely new method of defining and retrieving our security information hierarchy, something different to modified preorder tree traversal. MPTT can't be and should not be abandoned - we have to find a way to apply the results in a better way Tarique -- = PHP Applications for E-Biz: http://www.sanisoft.com Cheesecake-Photoblog: http://cheesecake-photoblog.org = --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
On Jan 2, 5:03 pm, Dr. Tarique Sani [EMAIL PROTECTED] wrote: On 1/2/07, Langdon Stevenson [EMAIL PROTECTED] wrote: What we seem to be talking about is creating an entirely new method of defining and retrieving our security information hierarchy, something different to modified preorder tree traversal.MPTT can't be and should not be abandoned - we have to find a way to apply the results in a better way Tarique -- = PHP Applications for E-Biz:http://www.sanisoft.com Cheesecake-Photoblog:http://cheesecake-photoblog.org = Hi All, I just finished a working version of an access control component that would allow you to define owner delete, owner view, owner edit etc. using ACL without defining a rule for each actual aco, or even creating each aco. The code for now is here http://bin.cakephp.org/view/1153809117 It's not the answer to everything but I hope it might at least be useful in sparking ideas. Here's an example in how it works: For the url /demo2/categories/edit/1 where demo2 is a plugin and the AC component has been included. The following occurs: // Find the aro for the currently logged in user SELECT `Aro`.`id`, `Aro`.`model`, `Aro`.`foreign_key`, `Aro`.`alias`, `Aro`.`lft`, `Aro`.`rght` FROM `core_aros` AS `Aro` WHERE (`Aro`.`alias` = 'username') LIMIT 1 SELECT `Category`.`id`, `Category`.`user_id` FROM `demos_categories` AS `Category` WHERE (`Category`.`id` = 1) LIMIT 1 // Find the aco for the current section/controller/action/param combination. SELECT `Aco`.`alias` FROM `core_acos` AS `Aco` WHERE (`Aco`.`alias` IN ( 'demo2:categories:owner_edit:1', 'demo2:categories:owner_edit', 'demo2:categories:edit:1', 'demo2:categories:edit', 'demo2:categories', 'demo2', 'ROOT') ) ORDER BY `Aco`.`lft` DESC LIMIT 1 // If either query returns nothing (i.e. the basic ACL data isn't present), access is denied, otherwise the results of which are used like so: $this-checkAcl ($resultOfFirstQuery,$resultOfSecondQuery,'*'); and the result of this call is used to decide access or not. If a slug/title field is used in the url instead of the row id, this is taken into account by the component if the slug is either the first or a named parameter for the call. The list of ACOs generated for the second query prepends owner_action:id and owner_action to the potential list of ACOs if the model instance can be identified AND a user is currently logged in (identified by a session variable), otherwise these aco aliases are not added to the list. In this way it is possible to, for example define that USERS can owner_edit posts, and irrespective of how many users or posts you have, this one rule will be found and honored. Happy new year all, Comments welcome, AD7six Please note: The manual/bakery is a good place to start any quest for info. The cake search (at the time of writing) erroneously reports less/no results for the google group. The wiki may contain incorrect info - read at your own risk (it's mainly user submitted) :) You may get your answer quicker by asking on the IRC Channel (you can access it with just a browser here:http://irc.cakephp.org). --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
On 1/3/07, Dr. Tarique Sani [EMAIL PROTECTED] wrote: On 1/2/07, Langdon Stevenson [EMAIL PROTECTED] wrote: What we seem to be talking about is creating an entirely new method of defining and retrieving our security information hierarchy, something different to modified preorder tree traversal. MPTT can't be and should not be abandoned - we have to find a way to apply the results in a better way This discussion has peaked my interest in MPTT implementations. I am working on an object system for a CMS based on CakePHP and the object tree is implemented using MPTT. I did a textbook implementation of the thing, which means using a recursive algorithm to reorder the tree traversal data (lft and rgt) for each tree node in for inserts and deletes. I looked into the MPTT implementation in the ACL code and it looks like it cleverly avoids having to do recursive traversal in updating the lft and rgt fields during an update. But I think the optimizations used will only work in very simple trees that support the basic CRUD operations. My object tree needs to support reordering of nodes within a subtree as well as moving a node from one subtree to another. Because of this, an extra field is used and needs to be updated when the tree traversal data is updated. The simplest and most maintainable solution I found was through a recursive algorithm. The scenario presented by Dr. Tarique, very large tree of ACO's with very large tree of ARO's is a very real problem with my object system. MPTT provides for minimal amount of memory and SQL queries during reads. But when it comes to writes and updates, the thing uses up a lot of memory and requires a lot of SQL queries when updating a very large tree (this is using my current recursive implementation). I have not found the time to write a good benchmark yet, but from initial tests (20-100 nodes) the results do not look very good. I have tried using a stack-based algorithm instead of recursion, but surprisingly(?!?) it eats up more memory than the recursive version. Probably because I'm storing objects (which is needed) into the stack. I'm interested in hearing about others' experience with MPTT implementations using both the stack-based and recursive approach. Recently, I dug up an article on the ASPN Python Cookbook which implements DOM tree traversal without recursion or node tracking (using stack): http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/461776 From the looks of things, it seems to be much simpler than MPTT and can be optimized in a number of ways depending on the application specifics. But it also seems to require some changes to the database tables to add support for pointers to a node's parent, first child, and next sibling. -- _nimrod_a_abing_ [?] http://abing.gotdns.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Tree traversal methods - Was: Using ACL to limit access to data
Hi Nimrod This discussion has peaked my interest in MPTT implementations. I am working on an object system for a CMS based on CakePHP and the object tree is implemented using MPTT. I did a textbook implementation of the thing, which means using a recursive algorithm to reorder the tree traversal data (lft and rgt) for each tree node in for inserts and deletes. Tree traversal methods are not in my area of expertise unfortunately (I am better at using the tools given to me), so excuse me if I can't add much to this sub thread. I am however very interested to hear what you have to say on the subject :-) Regards, Langdon --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Tree traversal methods - Was: Using ACL to limit access to data
On 1/3/07, Langdon Stevenson [EMAIL PROTECTED] wrote: This discussion has peaked my interest in MPTT implementations. I am working on an object system for a CMS based on CakePHP and the object tree is implemented using MPTT. I did a textbook implementation of the thing, which means using a recursive algorithm to reorder the tree traversal data (lft and rgt) for each tree node in for inserts and deletes. Tree traversal methods are not in my area of expertise unfortunately (I am better at using the tools given to me), so excuse me if I can't add much to this sub thread. I am however very interested to hear what you have to say on the subject :-) If I am not mistaken Joe Celko's book on Nested Tree sets has a chapter on what to do when your trees need frequent inserts /me adds TODO: to find that book Tarique -- = PHP Applications for E-Biz: http://www.sanisoft.com Cheesecake-Photoblog: http://cheesecake-photoblog.org = --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
Nice implementation - which I am sure will fit very well where the data structure is similar to the one you have, that is where data belongs to groups. Would love to hear more thoughts from more people - on access control for data in a massively multi-user systems built using cakePHP Cheers and happy new year Tarique On 1/1/07, Langdon Stevenson [EMAIL PROTECTED] wrote: Ok, have a look at this :-) Warning: 1. You need a solid understanding of ACL for this to make sense. -- = PHP Applications for E-Biz: http://www.sanisoft.com Cheesecake-Photoblog: http://cheesecake-photoblog.org = --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
Hi Tarique Nice implementation - which I am sure will fit very well where the data structure is similar to the one you have, that is where data belongs to groups. Would love to hear more thoughts from more people - on access control for data in a massively multi-user systems built using cakePHP Interesting question. I don't see a problem though with extending this system. I would do so by adding an Aco for each user (effectively creating their own individual group) and using the same system of restriction. Given caching, or session storage of the Aco/s there wouldn't be any performance issue, even if you were talking about hundreds of thousands of users. Can you elaborate on your requirements a little further? Perhaps I am missing something? Regards, Langdon --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
On 1/1/07, Langdon Stevenson [EMAIL PROTECTED] wrote: Can you elaborate on your requirements a little further? Perhaps I am missing something? Let me give a real-life example. The largest known installation of Coppermine Picture Gallery (an Open Source project that I lead) has more than 3 million pictures and approx 100,000 users. As long as all the pictures and albums were public this was not a big problem. However Coppermine has a concept of user albums and private albums and password protected albums which can be or cannot be seen by public - the webmaster turned on the private albums feature and the hell broke loose as the queries started including criteria like aid NOT IN (1,5,.. long list of aids) and the looping checks were just too much. Coming to cakePHP perspective - I am currently wondering on how to exclude certain records from model-findAll* calls using the current ACL techniques. Actions which return or affect just one record will be no big deal atleast for some time but as the ACOs increase (in the above case 3 million +) performance will start to slow down even in those cases. That said I have to agree that example given by me is a rare one but at the same time a very plausible one. Cheers Tarique -- = PHP Applications for E-Biz: http://www.sanisoft.com Cheesecake-Photoblog: http://cheesecake-photoblog.org = --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
Hi Tarique Good example. Let me give a real-life example. The largest known installation of Coppermine Picture Gallery (an Open Source project that I lead) has more than 3 million pictures and approx 100,000 users. As long as all the pictures and albums were public this was not a big problem. However Coppermine has a concept of user albums and private albums and password protected albums which can be or cannot be seen by public - the webmaster turned on the private albums feature and the hell broke loose as the queries started including criteria like aid NOT IN (1,5,.. long list of aids) and the looping checks were just too much. I see the problem alright :-) I guess that in that situation you are limited by the complexity of the Aco tree. In my case I anticipate including business rules that minimise the list of Acos for a user. It should really be possible to limit a user to just half a dozen Acos or so in any given situation. One way of doing this is to only extract Acos that are related to the Model that is being queried. This could be handled by naming conventions. I already do this in fact by filtering out the :data Acos. The idea was to avoid exactly that problem of overloading the query. Coming to cakePHP perspective - I am currently wondering on how to exclude certain records from model-findAll* calls using the current ACL techniques. Actions which return or affect just one record will be no big deal atleast for some time but as the ACOs increase (in the above case 3 million +) performance will start to slow down even in those cases. That said I have to agree that example given by me is a rare one but at the same time a very plausible one. Absolutely. I will argue that growth of Aco numbers can be dealt with though. Firstly by the method mentioned above and secondly by caching of the Aco data for the user. This would mean no need to query Acos for findAll queries, other than at login (at which time you select all of their Acos and store them in a session or cache). After that it is just a matter of limiting the number of Acos included in an IN () clause to a reasonable number, possibly based on model type, or some other criteria. Given that, I think that the design would scale well with both large numbers of users and records. However I have never had to deal with a system that holds millions of records, so I may be wrong. It would be very interesting to find out. Regards, Langdon --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
On 1/1/07, Langdon Stevenson [EMAIL PROTECTED] wrote: This would mean no need to query Acos for findAll queries, other than at login (at which time you select all of their Acos and store them in a session or cache). We will very quickly run out of memory if session is kept in memory, if not reading large number of ACOs from cache/file based session would be *almost* just as expensive as queries from a database. After that it is just a matter of limiting the number of Acos included in an IN () clause to a reasonable number, possibly based on model type, or some other criteria. As soon as we introduce 'some other criteria' the solution becomes app specific. I am getting more and more inclined to believe that access restriction to data will always have to be based on app specific criteria. Can anyone tell if the newly introduced Behaviours in 1.2 would be helpful in this regard? Cheers Tarique -- = PHP Applications for E-Biz: http://www.sanisoft.com Cheesecake-Photoblog: http://cheesecake-photoblog.org = --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
Hi Tarique This would mean no need to query Acos for findAll queries, other than at login (at which time you select all of their Acos and store them in a session or cache). We will very quickly run out of memory if session is kept in memory, if not reading large number of ACOs from cache/file based session would be *almost* just as expensive as queries from a database. This implies heavily that limiting the number of Acos is the key. Can you give an example of how a user may accumulate large numbers of Acos? (Other than a superuser who would logically have access to everything I ask this not to be argumentative, only to try to get a better understanding of the issue. I may well be facing the same problems as you, only I haven't realised it yet! :-) After that it is just a matter of limiting the number of Acos included in an IN () clause to a reasonable number, possibly based on model type, or some other criteria. As soon as we introduce 'some other criteria' the solution becomes app specific. I am getting more and more inclined to believe that access restriction to data will always have to be based on app specific criteria. I think that you are probably right. The question then becomes: is this a problem? If so, why is it a problem? Are you intending for your Cake app to share its security data with other applications? If your application essentially stands alone, then surely it won't matter if its Acos are application specific? Regards, Langdon --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
On 1/2/07, Langdon Stevenson [EMAIL PROTECTED] wrote: This implies heavily that limiting the number of Acos is the key. Can you give an example of how a user may accumulate large numbers of Acos? Yes, if you see to my previous example - getting in findAll* which pictures/albums/categories a user is allowed to see (depending which group she belongs to) you will soon have a large number of ACOs I think that you are probably right. The question then becomes: is this a problem? If so, why is it a problem? The problem for me is what would be a DRY way to do this. I very easily can do it the usual way by adding criteria to findAll or even some funky bindModel stuff, but this way there is access restriction code in almost every controller / model. This for a large project soon gets to be P2C2E (Process too Complicated to Explain) unless explained in great details at every step. May be it needs inversion of approach to solve it Cheers Tarique -- = PHP Applications for E-Biz: http://www.sanisoft.com Cheesecake-Photoblog: http://cheesecake-photoblog.org = --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Using ACL to limit access to data
Hi I thought that I would share something that I have just developed with the list. My ACL implementation does a good job of limiting access to controllers and their actions. Cake's ACL is great for checking if: Mr User (an ARO) is allowed to access Mr Object (an ACO). However the standard ACL system does not give you a simple way to generate a list of ACO's that Mr User is allowed to access. Therefore if you want to prevent a user from accessing data that they are not allowed to you have to build some sort of security into your controllers that works out how to limit who can request what. You could also use an afterFind callback to check the access rights on each row returned by a query. This would slow your system to a halt in no time with large queries. I wanted to make the most of Cake's ACL system, so I poked around in the API and got an understanding for how it all works. From there I wrote a function that retrieves a list of ACOs that the current user is allowed to access. My solution: - I created a set of ACO's that represent each client, and their various departments - Each data record is tagged with the department that the creator belongs to when they are created (assigning an owner to the data) - When a user requests a data record a list of ACOs that they are allowed to access is generated - Find queries have an extra WHERE clause added to them like this that checks if the owner of the data is in the list of owners that the user is associated with: AND `Master`.`owner` IN ('client_dept_1:data', 'client_dept_2:data') As a result, only records that the user is allowed to access are returned to them. I am quite pleased with this result as it represents only a small increase in overhead to the find queries, and it allows me to make full use of the (quite awesome) power of ACL. I will look at caching the ACO list of the user some time soon to help reduce the number of queries required for each request. Once that is done this system should have negligible impact on the performance of the system, but give me complete control over who can see what. I hope this may be useful to someone. If so, and you would like to know more about generating a list of ACOs for individual AROs, then let me know. I would be happy to share. Regards and a happy New Year to everyone, Langdon --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
Hello Langdon This sounds great. Please let me know how to access a sample of your code. Looking forward. Thanks! Devon Langdon Stevenson wrote: Hi I thought that I would share something that I have just developed with the list. My ACL implementation does a good job of limiting access to controllers and their actions. Cake's ACL is great for checking if: Mr User (an ARO) is allowed to access Mr Object (an ACO). However the standard ACL system does not give you a simple way to generate a list of ACO's that Mr User is allowed to access. Therefore if you want to prevent a user from accessing data that they are not allowed to you have to build some sort of security into your controllers that works out how to limit who can request what. You could also use an afterFind callback to check the access rights on each row returned by a query. This would slow your system to a halt in no time with large queries. I wanted to make the most of Cake's ACL system, so I poked around in the API and got an understanding for how it all works. From there I wrote a function that retrieves a list of ACOs that the current user is allowed to access. My solution: - I created a set of ACO's that represent each client, and their various departments - Each data record is tagged with the department that the creator belongs to when they are created (assigning an owner to the data) - When a user requests a data record a list of ACOs that they are allowed to access is generated - Find queries have an extra WHERE clause added to them like this that checks if the owner of the data is in the list of owners that the user is associated with: AND `Master`.`owner` IN ('client_dept_1:data', 'client_dept_2:data') As a result, only records that the user is allowed to access are returned to them. I am quite pleased with this result as it represents only a small increase in overhead to the find queries, and it allows me to make full use of the (quite awesome) power of ACL. I will look at caching the ACO list of the user some time soon to help reduce the number of queries required for each request. Once that is done this system should have negligible impact on the performance of the system, but give me complete control over who can see what. I hope this may be useful to someone. If so, and you would like to know more about generating a list of ACOs for individual AROs, then let me know. I would be happy to share. Regards and a happy New Year to everyone, Langdon --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
RE: Using ACL to limit access to data
Hi, This sounds along the lines of what I was planning to do. Except that I didn't want to modify the core code, since I'd have to do the same on every version update. So I decided just to make my own implementation, that heavily borrow's from cake's (not in code, just in concept). Sounds useful, though. Brandon --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
Hi devon This sounds great. Please let me know how to access a sample of your code. Looking forward. I will put a sample together today and post it. It is still just prototype, so I am sure that it can be improved upon. Regards, Langdon --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
Hi Brandon This sounds along the lines of what I was planning to do. Except that I didn't want to modify the core code, since I'd have to do the same on every version update. Agreed. My solution does not modify Cake core code in any way, I just used various function in the ACL code in a different way to achieve the desired result. So I decided just to make my own implementation, that heavily borrow's from cake's (not in code, just in concept). Sounds useful, though. I considered doing this too, but was put off by the thought of having to access control systems to maintain. I would be interested to hear your thoughts on what I post. Regards, Langdon --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
RE: Using ACL to limit access to data
All this expectation is killing me ;) When will we be able to take a glimpse at it? Thanks for the hard work. -MI --- Remember, smart coders answer ten questions for every question they ask. So be smart, be cool, and share your knowledge. BAKE ON! -Mensaje original- De: cake-php@googlegroups.com [mailto:[EMAIL PROTECTED] En nombre de Langdon Stevenson Enviado el: Domingo, 31 de Diciembre de 2006 06:56 p.m. Para: cake-php@googlegroups.com Asunto: Re: Using ACL to limit access to data Agreed. My solution does not modify Cake core code in any way, I just used various function in the ACL code in a different way to achieve the desired result. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---
Re: Using ACL to limit access to data
Ok, have a look at this :-) Warning: 1. You need a solid understanding of ACL for this to make sense. 2. I am sure that this code could be improved substantially by better programmers than me. The aim was just to make something that worked to see if it could be done. I guess that it should be made into a component. Pre-requisites: 1. User authentication (I am using dAuth for this) 2. An Aro structure of usernames and groups that match the authentication system 3. An Aco structure of groups that data can belong to Once you have that then you are ready to protect your data. // First, get a list of Acos that the user has access to and // return it as a comma delimited string with '' mark around each // Aco alias. The functions used are listed below. $ownerString = $this-_arrayToList($this-_getDataAcos()); // Query the database for records that we are allowed to access // using the list generated above as a filter. This requires the // table have a column that holds an Aco name for each record to define // who can access it. In this case the column name is 'owner'. $this-set( 'data', $this-Master-findAll( 'WHERE `Master`.`owner` IN ('.$ownerString.')' ) ); This will return a data set of only the records that the ACL system says the user should have access to. /* * The function _getDataAcos() does the following: * * - Gets the username of the current user from the session * - Retrieves the ARO path for the username * - Gets all AroAco links for the Aro path * - Gets the Alias for each Aco from each link * - Finds Acos that have the extension :data (meaning that they * are used for controlling data rather than controller actions * - Gets all children data Acos and puts them in an array * - Returns the array of data Acos * * I put it in appController.php so that it is available everywhere */ function _getDataAcos () { $aro = new Aro(); // Get the username. It may be better to pass this to the function $user = $this-Session-read('User'); $username = $user['username']; // Get the Aro path for this user $aroPath = $aro-getPath($username); // Retrieve all links for the list of Aros $Link = new ArosAco(); foreach ($aroPath as $path) { $temp[] = $Link-findAllByAro_id($path['Aro']['id']); } $Aco = new Aco(); // Iterate through the links foreach ($temp as $tempAro) { // Iterate through each Aco attached the the current Aro foreach ($tempAro as $tempLink) { // If the Aco's alias has the extension :data we want it if (count(explode(':', $tempLink['Aco']['alias'])) 1) { $acos[] = $tempLink['Aco']['alias']; // Get the children of the Aco so that we inherit their access $tempAcos[] = $Aco-getChildren($tempLink['Aco']['object_id']); // Iterate through all child Acos foreach($tempAcos as $potentials) { // There are two levels of nesting, so iterate the second foreach ($potentials as $potential) { // Check that the Acos are data Acos // This is not really required if (count(explode(':', $potential['Aco']['alias'])) 1) { // Put the Acos we have selected in an array $acos[] = $potential['Aco']['alias']; } } } } } } // send back the Aco array return $acos; } /* * This function just turns the array of names into a comma delimited * string with each item in ''. */ function _arrayToList($sourceArray = null) { $ownerString = ''; $ownerArray = $this-_getDataAcos(); foreach ($ownerArray as $owner) { $ownerString .= '\''.$owner.'\','; } return trim($ownerString, ','); } So that's it. Hope that it made some sense. I have done basic testing on it, and it appears that the data is protected according to the rules of the ACL. However, if you want to use this code I would strongly suggest that you conduct your own testing to be sure I haven't made some glaring error in the security. If anyone can suggest improvements, or a better way to achieve the same result, I would like to hear it :-) Regards, Langdon --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Cake PHP group. To post to this group, send email to cake-php@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~--~~~~--~~--~--~---