PermissionGuard is a custom NestJS guard that implements role-based access control by checking whether the logged-in user has the required permissions to access a particular endpoints and resources. This guard is designed to be highly configurable and reusable across different endpoints within a NestJS application.

Differentiating Between Resource-Specific and General Permissions

The PermissionGuard in NestJS is a versatile and configurable guard designed for role-based access control. It efficiently differentiates between permissions that are specific to a certain resource (like a project) and those that are more general in nature (like editing one’s own user profile). Certainly, let’s clarify how the PermissionGuard works with a focus on the ignoreResource flag and its relation to resource-specific endpoints:

How It Works

The PermissionGuard is adept at handling both resource-specific and general user requests. Here’s how it functions based on the ignoreResource flag:
  1. When ignoreResource is False:
    • This setting is used for endpoints that are tied to a specific resource, such as a particular project.
    • In this case, the guard expects a resource identifier (like a project ID) to be included in the request header.
    • It then verifies if the user has the appropriate permissions for this specific resource. This involves checking the USER and PROJECT permissions, as defined in the UserRoleAssign collection and categorized by the RoleMmbership enum.
    • If the user permissions align with the required resource-specific permissions, access is granted.
  2. When ignoreResource is True or Omitted:
    • This configuration is chosen for more general actions that are not linked to a particular resource, such as editing a user profile.
    • In such cases, the guard does not look for a resource identifier in the request header.
    • Instead, it checks for NONE_RESOURCE permissions, which are broader and not associated with any specific resource.
    • If the user possesses these general permissions, they are allowed to proceed with the request.

Example Usage

Here’s an example of how to apply the PermissionGuard to an endpoint in a controller:
project.controller.ts
@Controller("projects")
export class ProjectController {
  // Endpoint for a resource-specific action
  @UseGuards(PermissionGuard)
  @Permissions(ServerPermission.GET_PROJECTS) // ignoreResource default to false
  @Get("/:projectId")
  async getProject(@Param("projectId") projectId: string) {
    // ...
  }

  // Endpoint for a general action
  @UseGuards(PermissionGuard)
  @Permissions(ServerPermission.UPDATE_USER, true) // ignoreResource is true
  @Put("/update-profile")
  async updateUserProfile() {
    // ...
  }
}
In this setup, PermissionGuard intelligently differentiates between actions that require specific resource access and those that are more general, ensuring that users have the right permissions for each type of request.

Errors and Responses

  • BadRequestException: Triggered if the user object is missing or if the resource header is invalid (for resource-specific permissions).
  • ForbiddenException: Triggered if the user does not possess the required permissions for the action, regardless of whether it is resource-specific or general.
This nuanced approach to handling permissions allows the PermissionGuard to provide a flexible and effective means of implementing security policies in a NestJS application.