Как структурировать пользовательские разрешения в базе данных для вложенных представлений? - PullRequest
1 голос
/ 16 марта 2019

Я работаю над приложением информационных панелей, которому нужна система разрешений пользователей для администраторов, которая позволяет им легко отображать или скрывать различные части карты сайта в зависимости от того, кто пользователь.

Ниже приводится то, что я уже придумал, что делать, но я хотел бы услышать, какие есть альтернативы, будь то реляционная или нереляционная база данных (или обе).

В настоящее время я планирую иметь коллекцию users в моей базе данных MongoDB, которая будет выглядеть следующим образом (auth обрабатывается Auth0, и этот материал здесь не нужно хранить):

[
  {
    _id: "e5jg",
    username: "demo",
    permissions: [ // ids in this array correspond to content ids in collection below
      "lk4n",
      "d30j",
      "hjyut",
    ]
  }
]

Также будет dashboards коллекция, которая напоминает карту сайта. Это выглядело бы следующим образом (предположим, что дети данного родителя никогда не используются совместно с другим родителем - так происходит в приложении):

[
  {
    "_id": "9gtl",
    "dashboard": "Restaurants",
    "tools": [
      {
        "tool": "Management",
        "pages": [
          {
            "page": "Market Strategy",
            "cards": [
              {
                "card": "Top Priority Areas",
                "contents": [
                  {
                    "_id": "lk4n",
                    "content": "Regional Map",
                    "dataSource": "topPriorityMapData"
                  },
                  {
                    "_id": "78ty",
                    "content": "Stakeholders",
                    "dataSource": "stakeholdersData"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
]

Я только ассоциировал пользователей с разрешениями на уровне content, потому что я полагаю, что если у кого-то есть доступ к данному листовому узлу карты сайта, он автоматически имеет доступ ко всем предкам этого узла. Пример: поскольку пользователь demo с _id e5jg может видеть Regional Map, у него есть доступ к карте Top Priority Areas, странице Market Strategy и панели инструментов Restaurants.

Когда бы ни менялись разрешения (управляемые через еще не построенный интерфейс пользовательского интерфейса), я планирую:

  1. обновить коллекцию пользователей и
  2. программно запускает конвейер агрегации MongoDB, чтобы присоединиться к коллекции users и коллекции dashboards, чтобы создать коллекцию users.dashboards, которая в основном состоит из файлов сайтов для каждого пользователя. Это будет выглядеть следующим образом:
[
  {
    "username": "demo",
    "dashboards": [
      {
        "dashboard": "Restaurants",
        "tools": [
          "tool": "Management",
          "pages": [
            {
              "page": "Market Strategy",
              "cards": [
                {
                  "card": "Top Priority Areas",
                  "contents": [
                    {
                      "content": "Regional Map",
                      "dataSource": "topPriorityMapData"
                    },
                  ]
                }
              ]
            }
          ]
        ]
      }
    ]
  }
]

Цель коллекции users.dashboards заключается в том, чтобы при входе пользователя в приложение можно было получить его конкретную карту сайта. Затем веб-интерфейс программно использует этот файл Sitemap для создания представлений, которые может видеть пользователь.

Этот подход мне не по вкусу, особенно из-за сумасшедшего количества $unwind, которое необходимо сделать, чтобы сгладить коллекцию dashboards, прежде чем ее можно будет присоединить к коллекции users с помощью $lookup. А затем сумасшедший $group, который должен был бы произойти, чтобы все вложить друг в друга на индивидуальной основе.

Другая проблема заключается в том, что мне нужно, чтобы данные сортировались, несмотря на все эти $unwind значения и повторы $group значения, то есть порядок, в котором возвращаются дочерние элементы (информационные панели, инструменты, страницы, карточки, содержимое) внешний интерфейс в идеале должен оставаться в том же порядке, который изначально был указан в коллекции dashboards. Пример: если есть пользователь, который имеет доступ только к одной странице в инструменте, который имеет пять страниц, эту одну страницу следует удалить из ее карты сайта, но другие страницы не должны перемешиваться.

Как лучше подходить к созданию системы разрешений пользователей для этого приложения?

...