node User {
String username
}
node Role {
String name
}
relationship MEMBER_OF { }
relationship PARENT_OF { }
relationship HAS_PERMISSION {
boolean read
boolean update
boolean delete
boolean ...
}
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?
- 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.
- 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
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:
- 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.
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.
Sorry for this huge post, but I can't figure out how to do that...
--
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 neo4j+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
IF(
MATCH
(u:User {name:'U1'})-[r:HAS_PERMISSION]->(o:Object {name:'O1'})
RETURN r.READ
) ELSE IF (
MATCH
(u:User {name:'U1'}),
(o:Object {name:'O1'}),
u-[r:HAS_PERMISSION]->()-[:PARENT_OF*]->o
RETURN r.READ
) ELSE (
MATCH
(u:User {name:'U1'}),
(o:Object {name:'O1'}),
u-[*]->(v:Role)-[r:HAS_PERMISSION]->o
RETURN r.READ
)
MATCH
(u:User {name:'U1'}),
(o:Object {name:'O1'}),
s = shortestPath(u-[r:HAS_PERMISSION]->()-[:PARENT_OF*]->o)
RETURN r.READ
MATCH
(u:User {name:'U1'}),
(o:Object {name:'O1'}),
s = shortestPath(
u-[r:HAS_PERMISSION]
OPTIONAL ->()-[:PARENT_OF]
->o
)
RETURN r.READ