2

I'm working on a data dashboards application that needs a user permissions system for admins that allows them to easily show or hide different parts of the sitemap depending on who the user is.

The following is what I've come up with so far for what to do, but I'd like to hear what alternatives are out there, whether it's using a relational or non-relational database (or both).

I currently plan to have a users collection in my MongoDB database that would look like the following (auth is handled by Auth0 and that stuff doesn't need to be stored here):

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

There would also be a dashboards collection that resembles the sitemap of the website. It'd look like the following (assume a given parent's children are never shared with another parent -- that happens to be the case in the application):

[
  {
    "_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"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
]

I only associated users with permissions at the content level because I figure if someone has access to a given leaf node of the site map, they automatically have access to all of that node's ancestors. Ex: Because demo user with _id e5jg can see the Regional Map, he has access to the Top Priority Areas card, the Market Strategy page, and the Restaurants dashboard.

Whenever the permissions are changed (controllable through a not-yet-built UI interface), I plan to:

  1. update the users collection and
  2. programatically trigger a MongoDB aggregation pipeline to join the users collection and the dashboards collection to create a users.dashboards collection that basically comprises sitemaps on a user-by-user basis. That would look like the following:
[
  {
    "username": "demo",
    "dashboards": [
      {
        "dashboard": "Restaurants",
        "tools": [
          "tool": "Management",
          "pages": [
            {
              "page": "Market Strategy",
              "cards": [
                {
                  "card": "Top Priority Areas",
                  "contents": [
                    {
                      "content": "Regional Map",
                      "dataSource": "topPriorityMapData"
                    },
                  ]
                }
              ]
            }
          ]
        ]
      }
    ]
  }
]

The purpose of the users.dashboards collection would be so that when a user logs into the app, their specific sitemap can be fetched. The frontend would then programatically use that sitemap to generate the views that the user can see.

This approach feels off to me, especially with the crazy amount of $unwinding that would have to be done to flatten the dashboards collection before it can be joined to the users collection with $lookup. And then the crazy $grouping that would then have to happen to nest everything back together on a user-by-user basis.

The other problem is I need the data to be sorted despite all that $unwinding and re$grouping -- that is, the order in which children (dashboards, tools, pages, cards, contents) are returned to the frontend would ideally stay in the same order originally laid out in the dashboards collection. Ex: If there's a user that only has access to one page in a tool that has five pages, that one page should be removed from her sitemap but the other pages shouldn't get shuffled.

What would be a better way to approach building a user permissions system for this application?

jlin
  • 51
  • 3
  • 2
    Asking for "Thoughts on a better way" is not a valid SO question. [ask] [help] – philipxy Mar 16 '19 at 01:49
  • thanks for the feedback! edited the post – jlin Mar 16 '19 at 02:19
  • 2
    Changing the title isn't much of an edit. The whole content is basically prone to "opinion" in response, other than to say that [nesting arrays is a really bad idea](https://stackoverflow.com/a/23577266/2313887) and always born from thinking "these would be the relations" when in reality you need a much *"flatter"* design than you originally think. – Neil Lunn Mar 16 '19 at 04:25
  • Asking for "better ways" when the subject is higher-level design not coding typically requires answers that are too long to fit in one post. And the answers tend to be more opinion- than fact-based. Alas. – Erwin Smout Mar 18 '19 at 10:11

0 Answers0