Как запросить график разрешений с помощью gremlin? - PullRequest
0 голосов
/ 02 июня 2018

У меня есть следующий график:

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, начиная с User # 1 и следуя по пути донашел "outEdge" с меткой "read", ведущей к вершине Resource # 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 Ответ

0 голосов
/ 03 июня 2018

Вы не должны пересекать произвольные внешние ребра (без ограничений надписей).Я думаю, вы ищете

  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
...