@Injectable()
export class AdminLevelGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const allowLevel = this.reflector.get<Partial<AdminLevel>>(
ALLOW_ADMIN_LEVEL,
context.getHandler(),
);
// 관리자 level 제한이 없는 경우
if (isNil(allowLevel)) {
return true;
}
const req = context.switchToHttp().getRequest();
const admin: Admin = req.user;
// 현재 관리자 레벨이 api 에 허용된 level 보다 크면 403을 throw 한다.
if (admin.level > allowLevel) {
throw new ForbiddenException(
HTTP_RESPONSE_ERROR_CODE.ADMINISTRATOR.ADMINISTRATOR013,
);
}
return true;
}
}```tsx
export interface ExecutionContext extends ArgumentsHost {
getClass<T = any>(): Type<T>;
getHandler(): Function;
}
```import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
@Module({
providers: [
{
provide: APP_GUARD,
useClass: RolesGaurd,
},
],
})
export class AppModule {}import { SetMetadata } from '@nestjs/common';
import { AdminLevel } from '@libs/shared/constants/services/admin/admin.db';
export const ALLOW_ADMIN_LEVEL = 'ALLOW_ADMIN_LEVEL';
export const AllowAdminLevel = (adminLevel: AdminLevel) =>
SetMetadata(ALLOW_ADMIN_LEVEL, adminLevel);@UseGuards(AdminLevelGuard)
@AllowAdminLevel(AdminLevel.Master)
@Post()
async create(
@AdminLogin() loggedInAdmin: Admin,
@Body() createAdministratorDto: CreateAdministratorDto,
) {
const existAdmin = await this.administratorsService.findOneBy({
email: createAdministratorDto.email,
});
if (existAdmin) {
throw new BadRequestException(
HTTP_RESPONSE_ERROR_CODE.ADMINISTRATOR.ADMINISTRATOR007,
);
}
const administrator = await this.administratorsService.create(
loggedInAdmin,
createAdministratorDto,
);
return new BaseResponseDto(administrator);
}