roles.guard.ts 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'
  2. import { Reflector } from '@nestjs/core'
  3. import { HAS_ANY_ROLES_KEY, HAS_ROLES_KEY } from './roles.decorator'
  4. import { Role } from '../model/role.enum'
  5. @Injectable()
  6. export class RolesGuard implements CanActivate {
  7. constructor(private reflector: Reflector) {}
  8. canActivate(context: ExecutionContext): boolean {
  9. const classRoles = this.reflector.get<Role[]>(HAS_ROLES_KEY, context.getClass())
  10. const classAnyRoles = this.reflector.get<Role[]>(HAS_ANY_ROLES_KEY, context.getClass())
  11. const roles = this.reflector.get<Role[]>(HAS_ROLES_KEY, context.getHandler())
  12. const anyRoles = this.reflector.get<Role[]>(HAS_ANY_ROLES_KEY, context.getHandler())
  13. if (!classRoles && !classAnyRoles && !roles && !anyRoles) {
  14. return true
  15. }
  16. let result = true
  17. const request = context.switchToHttp().getRequest()
  18. const userRoles = request.user?.roles || []
  19. if (classRoles) {
  20. result = result && matchAll(classRoles, userRoles)
  21. }
  22. if (classAnyRoles) {
  23. result = result && matchAny(classAnyRoles, userRoles)
  24. }
  25. if (roles) {
  26. result = result && matchAll(roles, userRoles)
  27. }
  28. if (anyRoles) {
  29. result = result && matchAny(anyRoles, userRoles)
  30. }
  31. return result
  32. }
  33. }
  34. function matchAny(roles: Role[], userRoles: Role[]) {
  35. return roles.some((role) => userRoles.includes(role))
  36. }
  37. function matchAll(roles: Role[], userRoles: Role[]) {
  38. return roles.every((role) => userRoles.includes(role))
  39. }