auth guard update

This commit is contained in:
Joseph Ditton 2021-12-03 14:46:44 -07:00
parent 84b45cd6b1
commit 95961c5a14
5 changed files with 28 additions and 23 deletions

View File

@ -9,6 +9,7 @@ import { RolesGuard } from './providers/guards/roles.guard';
import { JwtService } from './providers/services/jwt.service'; import { JwtService } from './providers/services/jwt.service';
import { RolesService } from './providers/services/roles.service'; import { RolesService } from './providers/services/roles.service';
import { UsersService } from './providers/services/users.service'; import { UsersService } from './providers/services/users.service';
import { GuardUtil } from './providers/util/guard.util';
@Module({ @Module({
imports: [TypeOrmModule.forRoot(config), UsersModule], imports: [TypeOrmModule.forRoot(config), UsersModule],
@ -17,6 +18,7 @@ import { UsersService } from './providers/services/users.service';
UsersService, UsersService,
RolesService, RolesService,
JwtService, JwtService,
GuardUtil,
{ provide: APP_GUARD, useClass: AuthGuard }, // auth guard should come before roles guard { provide: APP_GUARD, useClass: AuthGuard }, // auth guard should come before roles guard
{ provide: APP_GUARD, useClass: RolesGuard }, // otherwise users won't be authenticated before roles check { provide: APP_GUARD, useClass: RolesGuard }, // otherwise users won't be authenticated before roles check
], ],

View File

@ -18,7 +18,7 @@ export default class Seeds implements Seeder {
// only insert roles if not present already // only insert roles if not present already
const role = await roleRepository.findOne(roleObj); const role = await roleRepository.findOne(roleObj);
if (!role) { if (!role) {
console.log(`Creating role '${role.key}'`); console.log(`Creating role '${roleObj.key}'`);
await roleRepository.insert(roleObj); await roleRepository.insert(roleObj);
} else { } else {
console.log(`Role '${role.key}' already exists`); console.log(`Role '${role.key}' already exists`);

View File

@ -1,24 +1,17 @@
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { JwtService } from '../services/jwt.service'; import { JwtService } from '../services/jwt.service';
import { SKIP_KEY } from 'server/decorators/skip.decorator'; import { GuardUtil } from '../util/guard.util';
import { Reflector } from '@nestjs/core';
import { Class } from 'server/dto/class.dto';
@Injectable() @Injectable()
export class AuthGuard implements CanActivate { export class AuthGuard implements CanActivate {
constructor(private reflector: Reflector, private jwtService: JwtService) {} constructor(private guardUtil: GuardUtil, private jwtService: JwtService) {}
canActivate(context: ExecutionContext) { canActivate(context: ExecutionContext) {
const skippedGuards = this.reflector.getAllAndOverride<Class<CanActivate>[]>(SKIP_KEY, [ // Handlers and Controllers can both skip this guard in the event that
context.getHandler(), if (this.guardUtil.shouldSkip(this, context)) {
context.getClass(),
]);
if (skippedGuards) {
const skippedGuard = skippedGuards.find((guard) => this instanceof guard);
if (skippedGuard) {
return true; return true;
} }
}
const req = context.switchToHttp().getRequest(); const req = context.switchToHttp().getRequest();
const authHeader = req.headers.authorization; const authHeader = req.headers.authorization;
if (!authHeader) return false; if (!authHeader) return false;

View File

@ -5,7 +5,7 @@ import { JwtBodyDto } from 'server/dto/jwt_body.dto';
import { RoleKey } from 'server/entities/role.entity'; import { RoleKey } from 'server/entities/role.entity';
import { RolesService } from '../services/roles.service'; import { RolesService } from '../services/roles.service';
import { UsersService } from '../services/users.service'; import { UsersService } from '../services/users.service';
import { some } from 'lodash'; import { intersection, isEmpty } from 'lodash';
@Injectable() @Injectable()
export class RolesGuard implements CanActivate { export class RolesGuard implements CanActivate {
@ -16,7 +16,6 @@ export class RolesGuard implements CanActivate {
context.getHandler(), context.getHandler(),
context.getClass(), context.getClass(),
]); ]);
console.log(requiredRoles);
if (!requiredRoles) { if (!requiredRoles) {
return true; return true;
@ -26,12 +25,6 @@ export class RolesGuard implements CanActivate {
if (!jwtBody) return false; // unauthenticated users are not authorized if (!jwtBody) return false; // unauthenticated users are not authorized
const user = await this.usersService.find(jwtBody.userId, ['userRoles']); return !isEmpty(intersection(jwtBody.roles, requiredRoles));
const roles = await this.rolesService.findByKey(...requiredRoles);
const roleMatches = user.userRoles.map((userRole) => {
return !!roles.find((role) => role.id === userRole.roleId);
});
return some(roleMatches);
} }
} }

View File

@ -0,0 +1,17 @@
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { SKIP_KEY } from 'server/decorators/skip.decorator';
import { Class } from 'server/dto/class.dto';
@Injectable()
export class GuardUtil {
constructor(private reflector: Reflector) {}
public shouldSkip(guard: CanActivate, context: ExecutionContext) {
const skippedGuards = this.reflector.getAllAndOverride<Class<CanActivate>[]>(SKIP_KEY, [
context.getHandler(),
context.getClass(),
]);
return !!(skippedGuards && skippedGuards.find((SkippedGuard) => guard instanceof SkippedGuard));
}
}