Hi Benjamin, how about setting up your example as a graph gist (gist.neo4j.org) with a tiny sample dataset?
Am 14.07.2014 um 15:28 schrieb Benjamin Makus <[email protected]>: > I now decided to use Neo4j as my main DB, this will simplify ACL stuff very > much. > > So here's my basic schema: > node User { > String username > } > > node Role { > String name > } > > relationship MEMBER_OF { } > > relationship PARENT_OF { } > > relationship HAS_PERMISSION { > boolean read > boolean update > boolean delete > boolean ... > } > > Each User can be MEMBER_OF many roles. > Each User can have a HAS_PERMISSION relation to every other node (i.e. > Article, Event, ...). > Each Role can have a HAS_PERMISSION relation to every other node (i.e. > Article, Event, ...). > Each HAS_PERMISSION relation defines what is allowed and what's not allowed. > This can be different actions dependent on the node, i.e. Article has an > "addComment" and a "publish" Permission, whereas Event doesn't have those > Permissions. > Each secured node can have a PARENT_OF relation to another node, but for > example Article will never have a parent, because it's always at root level > of my application. > > This approach looks very flexible, but I'm stuck with the queries... I had a > look at your ACL example, here: > http://docs.neo4j.org/chunked/stable/examples-acl-structures-in-graphs.html > > Reference Node? > Is there any reason to use a Reference Node instead of Labels? Use Labels > Query #1: > Input: User node u, some secured Node s > Query: Find the first HAS_PERMISSION relation, that connects u and s > Returns: the HAS_PERMISSION relation > I thought about using shortestPath(), but that doesn't fit in all situations. MATCH path = shortestPath((u:User {username:{name}})-[:HAS_PERMISSION*]->(s:Article {id:{articleId})) RETURN path > Query #2: > Input: User node u, some Label l, a Permission p > Query: Find all nodes, labeled with Label l, where User u is somehow related > to via HAS_PERMISSION and HAS_PERMISSION has Permission p set to true > Returns: List of nodes, labeled with Label l MATCH (u:User {username:{name}})-[:HAS_PERMISSION {read:true}*]->(node:Label) RETURN n I'd probably change the HAS_PERMISSION.permission to CAN_READ CAN_WRITE CAN_PUBLISH CAN_DELETE for performance and clarity reasons. > Basically both queries can use a similar algorithm, but I need some kind of > precedence in it, so it will find the right HAS_PERMISSION relation. It's > like: What does "first" mean ? > User takes precedence over Role > Secured Node takes precedence over its parent > This means: If I have a graph, where > User u has Write Access to the Parent p of Secured Node s > Some Role r of the User u has only Read Access to Secured Node s > Then the User u will have write access to Secured Node s, because it has to > match the Users permissions first. Don't you ask for a certain permission in the first place? You could filter paths after the fact or order them by the number of roles and parents (and minimize that number) ? return path, length(FILTER (n in nodes(path) WHERE n:Role)) as roles, length(FILTER (n in nodes(path) WHERE (n)<-[:PARENT_OF]-() )) as parents order by roles + parents asc > > And there's another scenario: > User's Role r1 has Write Access = false for Secured Node s > User's Role r2 has Write Access = true for Secured Node s > Then of the write access must be granted. this would be easier with the CAN_WRITE relationship which then wouldn't exist in your case 1 Otherwise you have to filter them out, that's why you'd only look for paths with -[:HAS_PERMISSION {write:true}]-> > > > Sorry for this huge post, but I can't figure out how to do that... No worries, happy to help. Please write it up as a graphgist, this will definitely be helpful to others too. (If you need help with that ping me). Michael > > -- > 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. -- 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.
