PRIMEIRO ENVIO
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
import { RBACService } from '../services/rbac.service';
|
||||
|
||||
export interface AuthorizedRequest extends Request {
|
||||
user?: {
|
||||
id: string;
|
||||
email: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Middleware to check if user has required permission
|
||||
*/
|
||||
export function requirePermission(permissionId: string, projectIdParam?: string) {
|
||||
return (req: AuthorizedRequest, res: Response, next: NextFunction) => {
|
||||
if (!req.user) {
|
||||
return res.status(401).json({ error: 'Authentication required' });
|
||||
}
|
||||
|
||||
const userId = req.user.id;
|
||||
let projectId: string | undefined;
|
||||
|
||||
// Extract project ID from request parameters if specified
|
||||
if (projectIdParam) {
|
||||
projectId = req.params[projectIdParam] || req.body[projectIdParam] || req.query[projectIdParam] as string;
|
||||
}
|
||||
|
||||
// Check if user has the required permission
|
||||
if (!RBACService.hasPermission(userId, permissionId, projectId)) {
|
||||
return res.status(403).json({
|
||||
error: 'Insufficient permissions',
|
||||
required: permissionId,
|
||||
projectId: projectId || 'global'
|
||||
});
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Middleware to check if user has any of the required permissions
|
||||
*/
|
||||
export function requireAnyPermission(permissionIds: string[], projectIdParam?: string) {
|
||||
return (req: AuthorizedRequest, res: Response, next: NextFunction) => {
|
||||
if (!req.user) {
|
||||
return res.status(401).json({ error: 'Authentication required' });
|
||||
}
|
||||
|
||||
const userId = req.user.id;
|
||||
let projectId: string | undefined;
|
||||
|
||||
// Extract project ID from request parameters if specified
|
||||
if (projectIdParam) {
|
||||
projectId = req.params[projectIdParam] || req.body[projectIdParam] || req.query[projectIdParam] as string;
|
||||
}
|
||||
|
||||
// Check if user has any of the required permissions
|
||||
if (!RBACService.hasAnyPermission(userId, permissionIds, projectId)) {
|
||||
return res.status(403).json({
|
||||
error: 'Insufficient permissions',
|
||||
required: `Any of: ${permissionIds.join(', ')}`,
|
||||
projectId: projectId || 'global'
|
||||
});
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Middleware to check if user has all of the required permissions
|
||||
*/
|
||||
export function requireAllPermissions(permissionIds: string[], projectIdParam?: string) {
|
||||
return (req: AuthorizedRequest, res: Response, next: NextFunction) => {
|
||||
if (!req.user) {
|
||||
return res.status(401).json({ error: 'Authentication required' });
|
||||
}
|
||||
|
||||
const userId = req.user.id;
|
||||
let projectId: string | undefined;
|
||||
|
||||
// Extract project ID from request parameters if specified
|
||||
if (projectIdParam) {
|
||||
projectId = req.params[projectIdParam] || req.body[projectIdParam] || req.query[projectIdParam] as string;
|
||||
}
|
||||
|
||||
// Check if user has all of the required permissions
|
||||
if (!RBACService.hasAllPermissions(userId, permissionIds, projectId)) {
|
||||
return res.status(403).json({
|
||||
error: 'Insufficient permissions',
|
||||
required: `All of: ${permissionIds.join(', ')}`,
|
||||
projectId: projectId || 'global'
|
||||
});
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Middleware to check if user is admin
|
||||
*/
|
||||
export function requireAdmin() {
|
||||
return requirePermission('admin:system');
|
||||
}
|
||||
|
||||
/**
|
||||
* Middleware to check project access
|
||||
*/
|
||||
export function requireProjectAccess(action: 'read' | 'update' | 'delete' | 'share' = 'read', projectIdParam: string = 'projectId') {
|
||||
return (req: AuthorizedRequest, res: Response, next: NextFunction) => {
|
||||
if (!req.user) {
|
||||
return res.status(401).json({ error: 'Authentication required' });
|
||||
}
|
||||
|
||||
const userId = req.user.id;
|
||||
const projectId = req.params[projectIdParam] || req.body[projectIdParam] || req.query[projectIdParam] as string;
|
||||
|
||||
if (!projectId) {
|
||||
return res.status(400).json({ error: 'Project ID required' });
|
||||
}
|
||||
|
||||
// Check if user can access the project
|
||||
if (!RBACService.canAccessProject(userId, projectId, action)) {
|
||||
return res.status(403).json({
|
||||
error: 'Project access denied',
|
||||
action,
|
||||
projectId
|
||||
});
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Middleware to check if user owns the resource or is admin
|
||||
*/
|
||||
export function requireOwnershipOrAdmin(ownerIdParam: string = 'userId') {
|
||||
return (req: AuthorizedRequest, res: Response, next: NextFunction) => {
|
||||
if (!req.user) {
|
||||
return res.status(401).json({ error: 'Authentication required' });
|
||||
}
|
||||
|
||||
const userId = req.user.id;
|
||||
const resourceOwnerId = req.params[ownerIdParam] || req.body[ownerIdParam] || req.query[ownerIdParam] as string;
|
||||
|
||||
// Allow if user is the owner or is admin
|
||||
if (userId === resourceOwnerId || RBACService.isAdmin(userId)) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return res.status(403).json({
|
||||
error: 'Access denied - ownership or admin privileges required'
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to get user permissions for response
|
||||
*/
|
||||
export function getUserPermissionsForResponse(userId: string, projectId?: string) {
|
||||
return {
|
||||
permissions: RBACService.getUserPermissions(userId, projectId).map(p => ({
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
resource: p.resource,
|
||||
action: p.action
|
||||
})),
|
||||
roles: RBACService.getUserRoles(userId, projectId).map(ur => ({
|
||||
roleId: ur.roleId,
|
||||
projectId: ur.projectId,
|
||||
grantedAt: ur.grantedAt
|
||||
})),
|
||||
isAdmin: RBACService.isAdmin(userId)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Middleware to add user permissions to response
|
||||
*/
|
||||
export function addUserPermissions(projectIdParam?: string) {
|
||||
return (req: AuthorizedRequest, res: Response, next: NextFunction) => {
|
||||
if (req.user) {
|
||||
const userId = req.user.id;
|
||||
let projectId: string | undefined;
|
||||
|
||||
if (projectIdParam) {
|
||||
projectId = req.params[projectIdParam] || req.body[projectIdParam] || req.query[projectIdParam] as string;
|
||||
}
|
||||
|
||||
// Add permissions to request for use in route handlers
|
||||
(req as any).userPermissions = getUserPermissionsForResponse(userId, projectId);
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user