如何使用gremlin查询权限图?

时间:2018-06-02 16:10:13

标签: graph permissions acl gremlin rbac

我有以下图表:

permissions graph

我正在使用Tinkergraph试图弄清楚:

  1. 用户#1 是否对资源#1 拥有“读取”权限? (它没有)
  2. 用户#2 是否对资源#1 拥有“写入”权限? (确实如此)。
  3. 我还试图找到一个不是特定于这个确切图形的查询,因为在现实生活模型中,它们之间可能存在多个层次结构角色。我刚刚开始掌握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 开始,然后按照路径找到“outEdge”,标签为“read”,导致vertex 资源#1

    Aahhh,因为我正在写这篇文章,我可能已经想到了,但是因为我对Gremlin很陌生,也许知道Gremlin的人可以理智地检查它或告诉我是否有更好的方法来做到这一点?如果没有,那么这可能会帮助那些试图解决同样问题的其他人。

    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 个答案:

答案 0 :(得分:1)

你不应该遍历任意的边缘(没有标签限制)。我认为你正在寻找

  1. 与资源的直接连接
  2. 从用户角色到资源的连接或
  3. 从任何父角色到资源的连接
  4. 在单个查询中覆盖所有三种情况的最佳方法是从用户开始,遍历所有memberchild_of边,沿路径发出所有顶点并最终检查是否存在&# 39;从任何顶点到资源的sa 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