【问题标题】:How do I query a permissions graph using gremlin?如何使用 gremlin 查询权限图?
【发布时间】:2018-11-12 12:03:42
【问题描述】:

我有以下图表:

我正在使用 Tinkergraph 来尝试弄清楚:

  1. User#1 是否对 Resource#1 具有“读取”权限? (它没有)
  2. User#2 是否对 Resource#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,从 User#1 开始并遵循路径,直到找到一个带有标签“read”的“outEdge”通向顶点 资源#1。

啊,在我写这篇文章的时候,我可能刚刚想通了,但由于我对 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)

【问题讨论】:

    标签: graph permissions acl gremlin rbac


    【解决方案1】:

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

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

    在单个查询中涵盖所有三种情况的最佳方法是从用户开始,遍历所有memberchild_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
    

    【讨论】:

    • 感谢您,这是关于无限制标签的非常有用的提示,通常您的查询更有意义! ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2021-10-15
    相关资源
    最近更新 更多