代码之家  ›  专栏  ›  技术社区  ›  whisperstream

如何使用gremlin查询权限图?

  •  1
  • whisperstream  · 技术社区  · 8 年前

    我有以下图表:

    permissions graph

    我用Tinkergraph试着找出:

    1. 用户#1 拥有“阅读”权限 资源#1 ? (事实并非如此)
    2. 用户#2 拥有“写入”权限 资源#1 ? (确实如此)。

    我还试图找到一个不特定于这个精确图的查询,因为在现实模型中,可能存在多个层次角色。我刚刚开始掌握Gremlin的语法,但我发现这个特殊的查询很难理解。下面是创建上图的代码:

        Graph graph = TinkerGraph.open();
        Vertex user1 = graph.addVertex(T.label, "user", T.id, 1, "name", "marko");
        Vertex user2 = graph.addVertex(T.label, "user", T.id, 2, "name", "vadas");
        Vertex role1 = graph.addVertex(T.label, "role", T.id, 3, "name", "role_1");
        Vertex role2 = graph.addVertex(T.label, "role", T.id, 4, "name", "role_2");
        Vertex resource1 = graph.addVertex(T.label, "resource", T.id, 5, "name", "resource_1");
        Vertex resource2 = graph.addVertex(T.label, "resource", T.id, 6, "name", "resource_2");
    
        user1.addEdge("read", resource2, T.id, 7);
        user1.addEdge("member", role2, T.id, 8);
        user2.addEdge("owns", resource2, T.id, 9);
        user2.addEdge("member", role1, T.id, 10);
    
        role1.addEdge("child_of", role2, T.id, 11);
        role1.addEdge("read", resource1, T.id, 12);
    
        role2.addEdge("write", resource1, T.id, 13);
        role2.addEdge("write", resource2, T.id, 14);
    

    我目前试图回答问题#1是使用 repeat ,从 用户#1 并跟随路径,直到找到一个标签为“read”的“outEdge”指向顶点 资源#1 .

    啊哈,在我写这篇文章的时候,我可能刚刚弄明白了,但由于我对小鬼很陌生,也许有人对小鬼很了解,可以检查一下,或者告诉我是否有更好的方法?如果没有,那么这可能会帮助其他试图解决同样问题的人。

    q1 = graph.traversal().V(user1.id())
        .repeat(__.out().simplePath())
        .until(__.outE().hasLabel("read").inV().is(resource1)).path().toList();
    // q1 returns [] (which is expected)
    
    q2 = graph.traversal().V(user2.id())
        .repeat(__.out().simplePath())
        .until(__.outE().hasLabel("write").inV().is(resource1)).path().toList();
    // q2 returns [[v[2], v[3], v[4]]]  (which seems right too)
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Daniel Kuppitz    8 年前

    您不应该遍历任意的外边缘(没有标签限制)。我想你在找

    1. 与资源的直接连接
    2. 从用户角色到资源或服务器的连接
    3. 从任何父角色到资源的连接

    在一个查询中覆盖所有三种情况的最佳方法是从用户开始,遍历所有 member child_of 边,沿路径发射所有顶点,并最终检查是否存在 read / write 从任意顶点到资源的连接:

    gremlin> // Does User#1 have "read" permission on Resource#1? (it does not)
    gremlin> g.V(1).emit().
                 repeat(out("member","child_of")).
               out("read").has("name","resource_1").hasNext()
    ==>false
    
    gremlin> // Does User#2 have "write" permission on Resource#1? (it does).
    gremlin> g.V(2).emit().
                 repeat(out("member","child_of")).
               out("write").has("name","resource_1").hasNext()
    ==>true