需要在使用Neo4j的应用程序中分层定义访问策略。
模型:应用程序使用树结构(每个Node
只有一个父),可以表示为
(:Node)-[:SUBTREE_OF]->(:Node)
为简单起见。
还有User
个Group
成员,Permission
个成员objectId
。权限包含两个属性:accessLevel
,其中包含已为其设置权限的对象的ID以及WRITE
,可以是READ
,NONE
或(u:User)-[:MEMBER_OF]->(g:Group)
(g:Group)-[:WITH]->(p:Permission{objectID:"99", accessLevel:"WRITE"})
。< / p>
所以
User
问题:需要为可以由其所有子级继承的对象指定权限访问级别。这意味着需要在运行时使用此对象的指定权限(如果已指定)确定特定Node
到特定accessLevel
的访问级别,或者如果未指定权限则确定最近的指定父权限。
如何编写将返回指定Node
或最近父Node
的{{1}}属性的查询?
答案 0 :(得分:3)
现在,您的:Permissions
通过objectID属性与:Nodes
和:Applications
相关联,但是对于使用图形关系的有效查询,这可能应该建模为与对象本身的关系。此时,问题是accessLevel
是否应存储在:Permission
节点中,或者是否要完全删除:Permission
个节点并使用{建模{ {1}}与:HasPermission
属性的关系。
我假设您现在要保留accessLevel
个节点。
假设:Permission
只能是一个:User
的成员,那么获取:Group
(或其:Node
祖先)权限的查询会变成类似:
:Node
返回包括我们最终匹配的MATCH (:User{ID:123})-[:MEMBER_OF]->(group:Group), (node:Node{ID:123})
WITH group, node
// looking for a :Node going up the chain with a permission from your group
OPTIONAL MATCH (node)-[jumps:SUBTREE_OF*0..]->(target:Node)<-[:HasPermission]-(perm:Permission)<-[:WITH]-(group)
WITH node, target, perm, jumps
ORDER BY SIZE(jumps) LIMIT 1
RETURN target, COALESCE(target = node, false) as same_node, COALESCE(perm.accessLevel, "WRITE") as accessLevel
:节点(如果我们无法在层次结构中找到一个并且默认为&#34; WRITE&#34;访问级别,则它将为null) ,target
是否:我们想要获得权限的节点是具有权限的节点(false表示我们发现了具有权限或默认的祖先),same_node
是访问级别相关权限。您可能并不需要所有这些,但测试它是否正常工作非常有用。
修改
记得我们可以通过对我们遍历链的关系数进行排序,轻松地强制执行排序以选择具有组权限的最近父节点(或节点本身)。改变了我上面的查询来处理这个问题。