55 lines
2.0 KiB
TypeScript
55 lines
2.0 KiB
TypeScript
import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common';
|
|
import { User, UserRole } from '../../users/user.entity';
|
|
|
|
/**
|
|
* 资源所有者或管理员权限 Guard
|
|
*
|
|
* 用途:检查用户是否有权限访问资源
|
|
* - 管理员(admin、super_admin)可以访问任何资源
|
|
* - 普通用户只能访问自己的资源(通过比较 id)
|
|
*
|
|
* 使用场景:
|
|
* - 查询用户信息:管理员可以查询任何用户,普通用户只能查询自己
|
|
* - 更新用户信息:管理员可以更新任何用户,普通用户只能更新自己
|
|
* - 删除用户:管理员可以删除任何用户,普通用户只能删除自己
|
|
*/
|
|
@Injectable()
|
|
export class OwnerOrAdminGuard implements CanActivate {
|
|
canActivate(context: ExecutionContext): boolean {
|
|
const request = context.switchToHttp().getRequest<{
|
|
user?: User;
|
|
params: { id?: string };
|
|
}>();
|
|
|
|
const user = request.user;
|
|
|
|
if (!user) {
|
|
throw new ForbiddenException('未授权访问');
|
|
}
|
|
|
|
// 获取请求的资源ID(从路由参数中)
|
|
const requestedId = request.params?.id;
|
|
|
|
if (!requestedId) {
|
|
// 如果没有提供资源ID,只允许管理员访问
|
|
const isAdmin = user.role === UserRole.ADMIN || user.role === UserRole.SUPER_ADMIN;
|
|
if (!isAdmin) {
|
|
throw new ForbiddenException('权限不足,需要管理员权限');
|
|
}
|
|
return true;
|
|
}
|
|
|
|
const requestedUserId = +requestedId;
|
|
|
|
// 检查权限:管理员可以访问任何资源,普通用户只能访问自己的资源
|
|
const isAdmin = user.role === UserRole.ADMIN || user.role === UserRole.SUPER_ADMIN;
|
|
const isOwner = user.id === requestedUserId;
|
|
|
|
if (!isAdmin && !isOwner) {
|
|
throw new ForbiddenException('权限不足,只能访问自己的资源或需要管理员权限');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|