mongodbgomgo

Mongo Aggregate Nested Array, Lookup


I am creating a web application using MongoDB and Go, which includes role based access control. I am storing the information regarding this in 2 collections, permissions and roles.

This is how these two collections look like. Permissions

{
    "operation": "create",
    "resource": "project"
}
{
    "operation": "read",
    "resource": "project"
}
{
    "operation": "update",
    "resource": "project"
}
{
    "operation": "delete",
    "resource": "project"
}
{
    "operation": "create",
    "resource": "user"
}

resource is something on which an operation is performed. So if there is some operation which cannot be performed on some resource, then, I needn't store it. For example user can only be created hence only create user need to be stored. Currently there are only 4 operations(create, read, update, delete) in the scope of the application, but could increase, like upload could come into picture.

Roles

{
    "role": "admin",
    "display_name": "Administrator",
    "permissions": [
      {
        "operation": "create",
        "resource": "project"
      },
      {
        "operation": "read",
        "resource": "project"
      },
      {
        "operation": "update",
        "resource": "project"
      },
      {
        "operation": "delete",
        "resource": "project"
      }
    ]
}

Roles contain role, the name of role to be displayed on UI and the set of permissions that role has.

I need to send this information to UI using a REST API in a specific format, which would describe whether a specific role can perform an operation on a resource or not using the checked flag and whether a specific operation on a resource is editable or not by using the flag isEditable. For example the permissions collection doesn't contain an operation delete on resource user, so it should not be editable, hence flag is set to false. Similarly user can be created, hence it is set to true.

 {
    display_name: "System Administrator",
    role: "admin",
    permissions: [
      {
        resource: "user",
        privilages: {
          create: { checked: false, isEditable: true },
          delete: { checked: false, isEditable: false },
          update: { checked: false, isEditable: false },
          read: { checked: false, isEditable: false }
        }
      },
      {
        resource: "project",
        privilages: {
          create: { checked: true, isEditable: true },
          delete: { checked: true, isEditable: true },
          update: { checked: true, isEditable: true },
          read: { checked: true, isEditable: true }
        }
      }
   ]
}

Is it possible to perform this using mongo aggregations? Or do I need to make modifications in my schema, If yes, then what modifications should I make.


Solution

  • I was able to solve the problem in 3 steps:

    1. Include all the permissions for every role and add a flag called checked. This increased data redundancy but that wasn't a big issue.
    2. Do a group by on resource field in roles collection.
    3. Populate the missing privileges for every resource with isEditable set to false on server side.

    I had to traverse the data on server side, but this was the most efficient way I could think of.