Description
Problem
I prefer to automatically deny all requests unless they're explicitly allowed by permissions & access controls instead of using guards on a per-route basis like this:
@Module({
imports: [
CaslModule.forRoot({/* ... */}),
],
controllers: [/* ... */],
providers: [
/* ... */
{
provide: APP_GUARD,
useClass: AccessGuard,
},
],
})
export class AppModule implements NestModule {}
I use a @Public()
decorator to denote routes that that are explicitly intended for unauthenticated use, but the AccessGuard
automatically denies them because of the user check: https://github.com/getjerry/nest-casl/blob/master/src/access.service.ts#L30-L32
Proposed Solution
There are probably a lot of ways to implement this. Here are a few suggestions:
1. Separate decorator to opt-out of the guard:
@Controller("public")
export class PublicDataController {
@UseAbilityAllowAll()
@Get("data")
public async getPublicData() {}
}
2. Extend the interface of the UseAbility
guard:
@Controller("public")
export class PublicDataController {
@UseAbility({
subject: PublicData,
action: Actions.read,
disableUserCheck: true,
})
@Get("data")
public async getPublicData() {}
}
This could allow you to mix public and non-public access control for the same resources, and maintain a simpler external interface. However it would make contract with the Permissions
more complicated as user
could be undefined.