Thanks for your answer. I'll try to clarify things a bit.

First I created an ACL CHEAT 
SHEET: http://www.docdroid.net/er3w/acl-cheat-sheet.pdf.html
There you can see lot's of different scenarios. The "*= +r*" and "*= -r*" 
behind the Obj-Nodes show what's the resulting permission for this Object. 
("*= -r*" means: no read permission, "*= +r*" means: read permissions 
granted)
Obj-Nodes are basically arbitrary Nodes which should be secured via ACL.

*For retrieving the correct Permission there are basically just a few rules 
(order is important!):*

   1. User has a direct Permission relation to the Object
   2. User has a direct Permission relation to the Object's parent (or 
   parent of parent of parent of p.......)
   3. User has a role(s) with direct relation to the Object
      1. Take the first Role in every role subtree of the User
      2. Remove those Roles, which are parents of other matching roles
      3. If there's any Role left which grants Permission, take it!
   4. User has a role(s) with direct relation to the Object's parent (or 
   parent of parent of parent of p.......)
      1. Again the same as above: Have a look at each role subtree, etc.
   
*In other words:*

   - A Permission relation that comes directly from the User has 
   precedence. It overrides everything the Roles allow/forbid.
   - This is also true, if the User has a Permission relation, which points 
   at a parent of the Object.
   - If (and only if) there's no Permission relation from the User to the 
   object or one of his parents, then we must have a closer look at the roles.
   - If two equal roles (means: in 2 different subtrees) have a Permission 
   relation to the object or one of its parents, then grant the permission if 
   any of these roles grants it.

*Shortest Path?*

   - *No :(*
   - It doesn't always fit. Especially if there's something like:
      - User is MEMBER_OF Role3
      - User is MEMBER_OF Role2, and Role2 is MEMBER_OF Role1
      - Role3 does not grant READ Permissions to Object
      - Role1 does grant READ Permissions to Object
      - Shortest Path would be to use Role3, but that's not the correct 
      way. As said above: Have a look at both sub-trees (1. Role3, 2. 
      Role2+Role1). And take the first role of each subtree that has a 
Permission 
      relation (1. Role3, 2. Role1). And then return true if any of these Roles 
      grant the Permission. Role1 does grant it, though return true :)
   
*Background:*

   1. User1 puts User2 on his "ignore list":
      - User2 has some basic role which allows him to read every other 
      Users profile
      - But now there's a direct Permission relation from User1 to User2, 
      which says: Not allowed to read this!
   2. User1 should be allowed to edit User2's Article:
      - The basic role says: Users can only read Articles and create new 
      ones. The creator is the only one that can edit it.
      - Now User2 wants User1 as his co-author, so he can give him 
      permission to edit this article.
   
*I altered the ACL design a little bit:*

   - It's now possible to override just a single permission, i.e.:
      - User1 is MEMBER_OF Role2 and Role2 is MEMBER_OF Role1
      - Role1 {read: false, write:false}
      - Role2 {read: true} -> it inherits the write property from Role1 and 
      overrides the read property
      - User {write: true} -> it inherits the read property from Role2 and 
      overrides the write property
   - *There's room for design changes*, if that affects performance in a 
   positive way :)

*Performance questions:*

   - Your suggestion was to use a relation for every possible permission, 
   but how can I "ungrant" Permissions that way? I must be able to say: "Role2 
   is MEMBER_OF Role1, so it inherits all of Role1's permissions, but Role2 
   should not be allowed to have write access". With my suggested design, I'd 
   just say: "Role2 {write: false} MEMBER_OF Role1".
   - I understand that it's faster to just have a look, if "CAN_READ" 
   exists, instead of having a look at the relation properties. But I'm really 
   unsure, if I can build the desired system that way. Maybe there's another 
   neat way to handle this? Or maybe even some Neo4j feature I'm not aware of?

*Again, thank you for your help!* If I get this system running, I'll build 
a small Spring / Spring Security app with it and put it on Github for 
everyone :-)

Btw: I had a look at *Graph Gist, it's really amazing*. I played a bit with 
it. And in a few hours, I'll put an example online which will cover all the 
examples from my ACL CHEAT SHEET.

-- 
You received this message because you are subscribed to the Google Groups 
"Neo4j" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to