> For the complete documentation index, see [llms.txt](https://kinesis-school-of-programming.gitbook.io/nestjs-unleashed/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kinesis-school-of-programming.gitbook.io/nestjs-unleashed/extra-module-1-authentication-authorization/authorization/requiring-permissions.md).

# Requiring permissions

Routes may now require one of a set of roles to be accessed.

A decorator will be used to define the necessary <mark style="color:blue;">`roles`</mark> for a route. Let's then create it in <mark style="color:purple;">auth</mark>/<mark style="color:purple;">decorators</mark>/<mark style="color:purple;">roles.decorator</mark>. Notice that it accepts an array of <mark style="color:blue;">`roles`</mark>.

```typescript
export const ROLES_KEY = 'roles';

export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles);
```

Another approach would be to define the decorator like this. It may be interesting in simple cases where the passed metadata should simply be appended to the route.

```ts
export const Roles = Reflector.createDecorator<Role[]>();
```

> You can read more about this approach in this [NestJS doc](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata).

Afterwards, we'll create our first guard from scratch, the <mark style="color:blue;">`RolesGuard`</mark>. As can be guessed, it will protect the routes according to the necessary <mark style="color:blue;">`roles`</mark>.

```sh
nest g gu auth/guards/roles
```

Below we can see a basic skeleton, with a <mark style="color:blue;">`reflector`</mark> and the <mark style="color:blue;">`canActivate()`</mark> signature.

```typescript
@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {}

  canActivate(context: ExecutionContext) {}
}
```

Inside the <mark style="color:blue;">`canActivate()`</mark> method, the first step is to collect the <mark style="color:blue;">`roles`</mark> metadata from the route (or controller). Remember that, if there is metadata for both the controller and a route, then the one from the route will be used. If there is no metadata, this guard will be out of the way.

```typescript
const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
  context.getHandler(),
  context.getClass(),
]);
if (!requiredRoles) return true;
```

{% hint style="info" %}
We could also use <mark style="color:blue;">`getAllAndMerge()`</mark> for merging the metadata of controller and route together, if this behavior was desired.
{% endhint %}

Then, the <mark style="color:blue;">`user`</mark> is extracted from the <mark style="color:blue;">`request`</mark>. The <mark style="color:blue;">`Request`</mark> type is from <mark style="color:blue;">`express`</mark>, which has a <mark style="color:blue;">`user`</mark> interface in it. As we are sure that the <mark style="color:blue;">`user`</mark> in the <mark style="color:blue;">`request`</mark> will always have the fields in the <mark style="color:blue;">`RequestUser`</mark> interface, we can make the **type assertion** to it without weighing our conscience. Lastly, check if the <mark style="color:blue;">`user`</mark> is an <mark style="color:blue;">`ADMIN`</mark>, immediately giving access in positive case.

```typescript
const request = context.switchToHttp().getRequest<Request>();
const user = request.user as RequestUser;
if (user.role === Role.ADMIN) return true;
```

And finally, check if the <mark style="color:blue;">`user`</mark> has one of the required roles.

```typescript
const hasRequiredRole = requiredRoles.some((role) => user.role === role);
return hasRequiredRole;
```

Now, the <mark style="color:blue;">`RolesGuard`</mark> can be activated globally, <mark style="color:red;">**after**</mark> the <mark style="color:blue;">`JwtAuthGuard`</mark>.

```typescript
{
  provide: APP_GUARD,
  useClass: RolesGuard,
}
```

{% hint style="danger" %}
It's important to follow this order! Otherwise, the guards' behavior will be compromised.
{% endhint %}

We can then state that a route requires one or more roles like the following:

```typescript
@Roles(Role.ADMIN)
```

<mark style="color:green;">**Commit**</mark> - Global roles guard and decorator for required roles in routes

With this, we can start to protect some routes. For example, we can require the <mark style="color:blue;">manager</mark> <mark style="color:blue;">`role`</mark> for the following routes:

* <mark style="color:blue;">`create()`</mark>, <mark style="color:blue;">`update()`</mark> and <mark style="color:blue;">`remove()`</mark> routes in the
  * <mark style="color:blue;">`ProductsController`</mark>
  * <mark style="color:blue;">`CategoriesController`</mark>
* <mark style="color:blue;">`find()`</mark> routes in the <mark style="color:blue;">`UsersController`</mark>

And require the <mark style="color:blue;">admin</mark> <mark style="color:blue;">`role`</mark> for the <mark style="color:blue;">`assignRole()`</mark> route.

<mark style="color:green;">**Commit**</mark> - Requiring roles in some routes
