Actualización módulo de roles e implementación de permission middleware
This commit is contained in:
@ -9,8 +9,7 @@ export class AuthService {
|
|||||||
userName:string,
|
userName:string,
|
||||||
password:string
|
password:string
|
||||||
){
|
){
|
||||||
const user =
|
const user = await userModel.findOne({
|
||||||
await userModel.findOne({
|
|
||||||
userName
|
userName
|
||||||
}).populate("roleId");
|
}).populate("roleId");
|
||||||
|
|
||||||
|
|||||||
74
backend/src/modules/auth/permission.middleware.ts
Normal file
74
backend/src/modules/auth/permission.middleware.ts
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import { Request, Response, NextFunction } from "express";
|
||||||
|
|
||||||
|
export const permissionMiddleware = (
|
||||||
|
module: string,
|
||||||
|
action: string
|
||||||
|
) => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) => {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
const user = (req as any).user;
|
||||||
|
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
|
||||||
|
return res.status(401).json({
|
||||||
|
message: "Usuario no autenticado."
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!user.permissions) {
|
||||||
|
|
||||||
|
return res.status(403).json({
|
||||||
|
message: "El usuario no tiene permisos asignados."
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const hasPermission = user.permissions.some(
|
||||||
|
|
||||||
|
(permission: any) =>
|
||||||
|
|
||||||
|
permission.module === module &&
|
||||||
|
permission.action === action
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (!hasPermission) {
|
||||||
|
|
||||||
|
return res.status(403).json({
|
||||||
|
|
||||||
|
message: "No tiene permisos para realizar esta acción."
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
next();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
return res.status(500).json({
|
||||||
|
|
||||||
|
message: "Error al validar permisos.",
|
||||||
|
|
||||||
|
error
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
@ -57,9 +57,10 @@ export class RoleController {
|
|||||||
|
|
||||||
res.status(201).json(role);
|
res.status(201).json(role);
|
||||||
|
|
||||||
} catch(error){
|
} catch(error:any){
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
message:"Error al crear role"
|
message:error.message,
|
||||||
|
error
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,29 +0,0 @@
|
|||||||
import { Request, Response, NextFunction } from "express";
|
|
||||||
|
|
||||||
export const roleMiddleware =
|
|
||||||
(allowedRoles: string[]) => {
|
|
||||||
|
|
||||||
return (
|
|
||||||
req: any,
|
|
||||||
res: Response,
|
|
||||||
next: NextFunction
|
|
||||||
) => {
|
|
||||||
|
|
||||||
const userRole =
|
|
||||||
req.user.roleName;
|
|
||||||
|
|
||||||
if (
|
|
||||||
!allowedRoles.includes(
|
|
||||||
userRole
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
|
|
||||||
return res.status(403).json({
|
|
||||||
message:
|
|
||||||
"No tiene permisos para realizar esta acción"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
next();
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -5,11 +5,13 @@ const roleSchema = new mongoose.Schema({
|
|||||||
roleName:{
|
roleName:{
|
||||||
type:String,
|
type:String,
|
||||||
required:true,
|
required:true,
|
||||||
unique:true
|
unique:true,
|
||||||
|
trim:true
|
||||||
},
|
},
|
||||||
|
|
||||||
description:{
|
description:{
|
||||||
type:String
|
type:String,
|
||||||
|
trim:true
|
||||||
},
|
},
|
||||||
|
|
||||||
active:{
|
active:{
|
||||||
|
|||||||
@ -1,19 +1,20 @@
|
|||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import { RoleController } from "./role.controller";
|
import { RoleController } from "./role.controller";
|
||||||
import { authMiddleware } from "../auth/auth.middleware";
|
import { authMiddleware } from "../auth/auth.middleware";
|
||||||
|
import { permissionMiddleware } from "../auth/permission.middleware";
|
||||||
|
|
||||||
const roleRouter = Router();
|
const roleRouter = Router();
|
||||||
|
|
||||||
const controller = new RoleController();
|
const controller = new RoleController();
|
||||||
|
|
||||||
roleRouter.get("/", authMiddleware, controller.getAll);
|
roleRouter.get("/", authMiddleware, permissionMiddleware("roles", "read"), controller.getAll);
|
||||||
|
|
||||||
roleRouter.get("/:id", authMiddleware, controller.getById);
|
roleRouter.get("/:id", authMiddleware, permissionMiddleware("roles", "read"), controller.getById);
|
||||||
|
|
||||||
roleRouter.post("/", authMiddleware, controller.create);
|
roleRouter.post("/", authMiddleware, permissionMiddleware("roles", "create"), controller.create);
|
||||||
|
|
||||||
roleRouter.put("/:id", authMiddleware, controller.update);
|
roleRouter.put("/:id", authMiddleware, permissionMiddleware("roles", "update"), controller.update);
|
||||||
|
|
||||||
roleRouter.delete("/:id", authMiddleware, controller.delete);
|
roleRouter.delete("/:id", authMiddleware, permissionMiddleware("roles", "delete"), controller.delete);
|
||||||
|
|
||||||
export default roleRouter ;
|
export default roleRouter ;
|
||||||
@ -1,7 +1,10 @@
|
|||||||
import roleModel from "./role.model";
|
import roleModel from "./role.model";
|
||||||
|
import userModel from "../user/user.model";
|
||||||
|
|
||||||
import { IRole } from "./role.interface";
|
import { IRole } from "./role.interface";
|
||||||
|
|
||||||
export class RoleService {
|
export class RoleService {
|
||||||
|
|
||||||
async getAll() {
|
async getAll() {
|
||||||
|
|
||||||
return await roleModel.find();
|
return await roleModel.find();
|
||||||
@ -16,6 +19,18 @@ export class RoleService {
|
|||||||
async create(
|
async create(
|
||||||
data:IRole
|
data:IRole
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
const exists = await roleModel.findOne({
|
||||||
|
|
||||||
|
roleName:data.roleName
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if(exists){
|
||||||
|
|
||||||
|
throw new Error("Ya existe un rol con ese nombre.");
|
||||||
|
}
|
||||||
|
|
||||||
return await roleModel.create(data);
|
return await roleModel.create(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,6 +38,23 @@ export class RoleService {
|
|||||||
id:string,
|
id:string,
|
||||||
data:Partial<IRole>
|
data:Partial<IRole>
|
||||||
){
|
){
|
||||||
|
if (data.roleName) {
|
||||||
|
|
||||||
|
const exists = await roleModel.findOne({
|
||||||
|
|
||||||
|
roleName: data.roleName,
|
||||||
|
|
||||||
|
_id: {
|
||||||
|
$ne: id
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if (exists) {
|
||||||
|
throw new Error("Ya existe un rol con ese nombre.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return await roleModel.findByIdAndUpdate(
|
return await roleModel.findByIdAndUpdate(
|
||||||
id,
|
id,
|
||||||
data,
|
data,
|
||||||
@ -35,6 +67,31 @@ export class RoleService {
|
|||||||
async delete(
|
async delete(
|
||||||
id:string
|
id:string
|
||||||
){
|
){
|
||||||
|
// Verificar que el rol exista
|
||||||
|
const role = await roleModel.findById(id);
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verificar si el rol está asignado a usuarios
|
||||||
|
const usersWithRole = await userModel.countDocuments({
|
||||||
|
roleId: id
|
||||||
|
});
|
||||||
|
|
||||||
|
if (usersWithRole > 0) {
|
||||||
|
throw new Error(
|
||||||
|
"No se puede eliminar el rol porque está asignado a uno o más usuarios."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(role.roleName === "ADMINISTRADOR"){
|
||||||
|
|
||||||
|
throw new Error(
|
||||||
|
|
||||||
|
"No se puede eliminar el rol Administrador.");
|
||||||
|
}
|
||||||
|
|
||||||
return await roleModel.findByIdAndDelete(id)
|
return await roleModel.findByIdAndDelete(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user