Authorisation using NodeJS, AzureAD and MongoDB (Part 1 - Design)
Tags: node, azure, mongodb, programming
Published: 2023-01-17 01:04:19

Application administrators use roles to group together permissions and assign them to individual users or groups of users. These permissions determine the actions that a user is able to take within a particular software. The roles that are assigned to a user depend on their tasks within the application itself. For instance, in a simple inventory application, users who are analysts might only need permissions to browse and download, but not to modify or change information. However, in an analyst group, a senior analyst may be granted full permissions to allow them to modify existing data or create/upload new inventory data.

In general, roles are used to make it easier to manage permissions by allowing administrators to assign a set of permissions to a user or group of users all at once, rather than having to assign individual permissions one at a time. This can make it more efficient to set up and manage access controls within an application.

A role is therefore defined as a collection of permissions that are grouped together and assigned to a user or group of users. A permission, on the other hand, is a specific action or set of actions that a user is allowed to take within a particular application.

I am designing an integration with AzureAD, and MongoDB collections using NodeJS. Roles/Groups will be created in AzureAD that will be synced in MongoDB for application usage. Each role will have its own permissions and Users can have one or more roles.

## Data Definition 

### Permission Schema

```
const permissionSchema = mongoose.Schema(
  {
    permission: {
        type: String,
        unique: true,
        required: true
    }
  }
  {
    timestamps: true,
  }
);

const Permission = mongoose.model('Permission', permissionSchema);
```

### Role Schema

```
const roleSchema = mongoose.Schema(
  {
    role: {
        type: String,
        unique: true,
        required: true
    },
    permissions: [
      {
        permissionId: {
          type: mongoose.Schema.Types.ObjectId,
          ref: 'Permission',
        },
      },
    ]
  }
  {
    timestamps: true,
  }
);

const Role = mongoose.model('Role', roleSchema);
```

### User Schema

```
const userSchema = mongoose.Schema(
  {
    firstName: {
      type: String,
      required: true,
    },
    lastName: {
      type: String,
      required: true,
    },
    phone: {
      type: String,
      required: true,
    },
    email: {
      type: String,
      required: true,
      unique: true,
      lowercase: true,
    },
    roles: [
      {
        roleId: {
          type: mongoose.Schema.Types.ObjectId,
          ref: 'Role',
        }
      },
    ],
  },
  {
    timestamps: true,
  }
);

const User = mongoose.model('User', userSchema);
```

### Management Process

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m14e801jbgq36btz3hdt.png)

### Sync Process

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ept7ib95c84r6g3pb38p.png)

### On Load

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ddql1r1hgcte06fdm051.png)