Enforcing Role-Based Access

We want to manage user access to different data depending on their role. In the recipe below, a user with the operator role can only view processing orders from a shop and a manager can only view shipped and completed orders.

To implement role-based access, we will use a JSON Web Token with role information in the payload, and the queryRewrite extension point to manage data access.

Let's add the role verification in the cube.js file.

module.exports = {
  queryRewrite: (query, { securityContext }) => {
    if (!securityContext.role) {
      throw new Error('No role found in Security Context!');
    }

    if (securityContext.role == 'manager') {
      query.filters.push({
        member: 'Orders.status',
        operator: 'equals',
        values: ['shipped', 'completed'],
      });
    }

    if (securityContext.role == 'operator') {
      query.filters.push({
        member: 'Orders.status',
        operator: 'equals',
        values: ['processing'],
      });
    }

    return query;
  },
};

To get the number of orders as a manager or operator, we will send two identical requests with different JWTs:

{
  "iat": 1000000000,
  "exp": 5000000000,
  "role": "manager"
}
{
  "iat": 1000000000,
  "exp": 5000000000,
  "role": "operator"
}

We have received different data depending on the user's role.

// Manager
[
  {
    'Orders.status': 'completed',
    'Orders.count': '3346',
  },
  {
    'Orders.status': 'shipped',
    'Orders.count': '3300',
  },
]
// Operator
[
  {
    'Orders.status': 'processing',
    'Orders.count': '3354',
  },
]

Please feel free to check out the full source code or run it with the docker-compose up command. You'll see the result, including queried data, in the console.

Did you find this page useful?