【问题标题】:Querying ACL/permissions graph using gremlin?使用 gremlin 查询 ACL/权限图?
【发布时间】:2026-01-22 11:30:01
【问题描述】:

我的权限图如下所示:

在这种情况下,

  1. user1 拥有对 folder1Group1 的权限。
  2. user2 拥有没有任何组的直接权限,尽管用户是 group2 的一部分,其中 group2 没有对 folder1 的访问权限。
  3. user3 具有通过组层次结构的权限,而不是组对文件夹的直接访问权限。

我能够编写单独的 gremlin 查询来确定用户是否具有通过其中一个组的权限和用户直接权限。

通过组检查权限

g.V().has('user','userId','user1').emit().repeat(out('member_of'))
 .outE('has_permission').has('permission','p1').inV()
 .has('folder','folderId','folder1').hasNext()

用户直接权限

g.V().has('user','userId','user2')
  .outE('has_permission').has('permission','p1').inV()
  .has('folder','folderId','folder1').hasNext()

但我无法弄清楚单个查询中的逻辑,该查询可以检查直接和组以查看用户是否具有权限。

有人可以帮我吗?

【问题讨论】:

    标签: graph permissions acl gremlin gremlin-server


    【解决方案1】:

    你的图表:

    g = TinkerGraph.open().traversal()
    g.addV('user').property('userId','user1').as('u1').
      addV('user').property('userId','user2').as('u2').
      addV('user').property('userId','user3').as('u3').
      addV('group').property('groupId','group1').as('g1').
      addV('group').property('groupId','group2').as('g2').
      addV('group').property('groupId','group3').as('g3').
      addV('folder').property('folderId','folder1').as('f1').
      addE('member_of').from('u1').to('g1').
      addE('member_of').from('u2').to('g2').
      addE('member_of').from('u3').to('g3').
      addE('member_of').from('g3').to('g1').
      addE('has_permission').from('g1').to('f1').
      addE('has_permission').from('u2').to('f1').iterate()
    

    您的问题的一般解决方案:

    g.V().has('user','userId',<userId>).
      emit().
        until(__.not(outE('member_of'))).
        repeat(out('member_of')).
      filter(out('has_permission').has('folder','folderId',<folderId>)).hasNext()
    

    在样本图上执行的遍历:

    gremlin> g.V().has('user','userId','user1').
               emit().
                 until(__.not(outE('member_of'))).
                 repeat(out('member_of')).
               filter(out('has_permission').has('folder','folderId','folder1')).hasNext()
    ==>true
    gremlin> g.V().has('user','userId','user2').
               emit().
                 until(__.not(outE('member_of'))).
                 repeat(out('member_of')).
               filter(out('has_permission').has('folder','folderId','folder1')).hasNext()
    ==>true
    gremlin> g.V().has('user','userId','user3').
               emit().
                 until(__.not(outE('member_of'))).
                 repeat(out('member_of')).
               filter(out('has_permission').has('folder','folderId','folder1')).hasNext()
    ==>true
    

    【讨论】:

    • 谢谢丹尼尔。这有助于确定用户是否有权限。
    • 关于那个的后续问题,现在上面的查询有助于确定用户是否有权限,我怎样才能额外过滤用户拥有的确切权限。在图中,has_permission 边缘标签具有属性“permission”和一些权限让我们说“write”
    • gremlin> g.V().has('user','userId',110143).emit().until(.not(out('member_of'))).repeat( out('member_of')).filter(out('has_permission').has('folder','folderId',191099)).hasNext() ==>true gremlin> g.V().has('user', 'userId',110143).emit().until(.not(outE('member_of'))).repeat(out('member_of')).filter(out('has_permission').has( 'permission','V').has('folder','folderId',191099)).hasNext() ==>false 为什么第二个查询返回 false 虽然用户拥有 'V' 权限?
    • 知道了,谢谢。我像下面这样。gremlin> g.V().has('user','userId',50781).emit().until(__.not(outE('member_of'))).repeat(out('member_of' )).filter(outE('has_permission').has('permission','V').inV().has('folder','folderId',230383)).valueM
    【解决方案2】:

    谢谢丹尼尔。 只是为了使上述查询复杂化以检查用户是否已授予权限。 以下是像我这样正在寻找的任何人的答案

    gremlin> g.V().has('user','userId','user3').
               emit().
                 until(__.not(outE('member_of'))).
                 repeat(out('member_of')).
               filter(outE('has_permission').has('permission','V').inV().has('folder','folderId','folder1')).hasNext()
    ==>true
    
    
    

    【讨论】: