feat(roadmap): implementar Sprints 1, 2 y 3 (MVC, Stateless JWT API y Spring Security)

This commit is contained in:
Carlos Tello
2026-09-05 01:46:57 -03:00
parent fa878cb0d5
commit 69b8b7ccef
34 changed files with 1750 additions and 21 deletions
+45
View File
@@ -0,0 +1,45 @@
from functools import wraps
from flask import request, jsonify, redirect, url_for, flash, abort, g
from flask_login import current_user
def require_permission(module: str, min_level: str = 'read'):
"""
Decorador de seguridad declarativa a nivel de método inspirado en @PreAuthorize de Spring Security.
Verifica los privilegios del usuario autenticado (tanto en sesiones web como en API JWT).
Niveles de permiso estándar:
- 'read': Permiso de lectura / consulta
- 'read_write': Permiso de modificación y creación
- 'admin': Permiso de control total
"""
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
user = None
# Evaluar contexto JWT primero si está presente
if hasattr(g, 'jwt_user') and g.jwt_user:
user = g.jwt_user
elif current_user and current_user.is_authenticated:
user = current_user
is_api = request.path.startswith('/api/') or request.is_json
if not user:
if is_api:
return jsonify({'error': 'Unauthorized', 'message': 'Autenticación requerida.'}), 401
flash('Debe iniciar sesión para acceder a este recurso.', 'warning')
return redirect(url_for('auth.login', next=request.url))
# Comprobar privilegios en la matriz RBAC
if not user.has_permission(module, min_level):
if is_api:
return jsonify({
'error': 'Forbidden',
'message': f'Permiso insuficiente en módulo "{module}". Nivel requerido: "{min_level}".'
}), 403
flash(f'No posee permisos suficientes ({min_level}) para gestionar {module}.', 'danger')
abort(403)
return f(*args, **kwargs)
return decorated_function
return decorator