import { Request, Response } from 'express'; import { z } from 'zod'; import { getErrorMessage } from '../../utils/error-utils'; import { rbacService } from './rbac.service'; const AssignRoleDto = z.object({ userId: z.string(), roleId: z.string(), expiresAt: z.string().optional(), }); const GrantPermissionDto = z.object({ userId: z.string(), permissionId: z.string(), expiresAt: z.string().optional(), }); /** * EN: RBAC Controller * VI: Controller RBAC */ export class RBACController { /** * EN: Get user permissions * VI: Lấy quyền của người dùng */ async getUserPermissions(req: Request, res: Response): Promise { try { const userId = (req as any).user?.id || (req as any).user?.sub || req.params.userId; if (!userId) { res.status(400).json({ success: false, error: { code: 'USER_ID_REQUIRED', message: 'User ID required' }, }); return; } const permissions = await rbacService.getUserPermissions(userId); const roles = await rbacService.getUserRoles(userId); res.json({ success: true, data: { permissions, roles, }, }); } catch (error: unknown) { res.status(500).json({ success: false, error: { code: 'GET_PERMISSIONS_FAILED', message: getErrorMessage(error) || 'Failed to get permissions', }, }); } } /** * EN: Assign role to user * VI: Gán role cho người dùng */ async assignRole(req: Request, res: Response): Promise { try { const data = AssignRoleDto.parse(req.body); const grantedBy = (req as any).user?.id || (req as any).user?.sub; await rbacService.assignRole(data.userId, data.roleId, { grantedBy, expiresAt: data.expiresAt ? new Date(data.expiresAt) : undefined, }); res.json({ success: true, data: { message: 'Role assigned successfully' }, }); } catch (error: unknown) { if (error instanceof z.ZodError) { res.status(400).json({ success: false, error: { code: 'VALIDATION_ERROR', message: 'Invalid input', details: error.issues, }, }); return; } res.status(500).json({ success: false, error: { code: 'ASSIGN_ROLE_FAILED', message: getErrorMessage(error) || 'Failed to assign role', }, }); } } /** * EN: Revoke role from user * VI: Thu hồi role từ người dùng */ async revokeRole(req: Request, res: Response): Promise { try { const { userId, roleId } = req.body; if (!userId || !roleId) { res.status(400).json({ success: false, error: { code: 'INVALID_INPUT', message: 'userId and roleId required' }, }); return; } await rbacService.revokeRole(userId, roleId); res.json({ success: true, data: { message: 'Role revoked successfully' }, }); } catch (error: unknown) { res.status(500).json({ success: false, error: { code: 'REVOKE_ROLE_FAILED', message: getErrorMessage(error) || 'Failed to revoke role', }, }); } } /** * EN: Grant permission to user * VI: Cấp quyền cho người dùng */ async grantPermission(req: Request, res: Response): Promise { try { const data = GrantPermissionDto.parse(req.body); const grantedBy = (req as any).user?.id || (req as any).user?.sub; await rbacService.grantPermission(data.userId, data.permissionId, { grantedBy, expiresAt: data.expiresAt ? new Date(data.expiresAt) : undefined, }); res.json({ success: true, data: { message: 'Permission granted successfully' }, }); } catch (error: unknown) { if (error instanceof z.ZodError) { res.status(400).json({ success: false, error: { code: 'VALIDATION_ERROR', message: 'Invalid input', details: error.issues, }, }); return; } res.status(500).json({ success: false, error: { code: 'GRANT_PERMISSION_FAILED', message: getErrorMessage(error) || 'Failed to grant permission', }, }); } } /** * EN: Check permission * VI: Kiểm tra quyền */ async checkPermission(req: Request, res: Response): Promise { try { const userId = (req as any).user?.id || (req as any).user?.sub; const { resource, action, scope } = req.query; if (!userId || !resource || !action) { res.status(400).json({ success: false, error: { code: 'INVALID_INPUT', message: 'userId, resource, and action are required', }, }); return; } const hasPermission = await rbacService.hasPermission( userId, resource as string, action as string, scope as string | undefined ); res.json({ success: true, data: { hasPermission }, }); } catch (error: unknown) { res.status(500).json({ success: false, error: { code: 'CHECK_PERMISSION_FAILED', message: getErrorMessage(error) || 'Failed to check permission', }, }); } } /** * EN: Get all roles * VI: Lấy tất cả roles */ async getRoles(req: Request, res: Response): Promise { res.status(501).json({ success: false, error: { code: 'NOT_IMPLEMENTED', message: 'Get roles is not yet implemented / Lấy roles chưa được triển khai' }, timestamp: new Date().toISOString() }); } /** * EN: Create new role * VI: Tạo role mới */ async createRole(req: Request, res: Response): Promise { res.status(501).json({ success: false, error: { code: 'NOT_IMPLEMENTED', message: 'Create role is not yet implemented / Tạo role chưa được triển khai' }, timestamp: new Date().toISOString() }); } } export const rbacController = new RBACController();