fase 2.1: roles editables (modelo skeen.role) y permisos por accion (43 claves, 9 grupos) con enforcement en backend y gating en frontend; editor de roles/permisos/menus en Configuracion
This commit is contained in:
@@ -15,7 +15,8 @@ import time
|
||||
|
||||
from odoo.http import request, Response
|
||||
|
||||
from ..roles import ROLE_RANKS, get_menu_roles, AGENDA_PERMS, resolve_agenda_perms
|
||||
from ..roles import ROLE_RANKS, get_menu_roles, AGENDA_PERMS, resolve_agenda_perms, min_rank
|
||||
from ..permissions import has_perm, PERM_LABELS
|
||||
|
||||
TTL_SECONDS = 60 * 60 * 12 # 12 horas
|
||||
SECRET_KEY = 'skeen.frontend.secret'
|
||||
@@ -158,10 +159,10 @@ def forbid_roles(*roles):
|
||||
def require_role(min_role='lectura'):
|
||||
"""Decorator: exige token válido y un rol con rango >= min_role.
|
||||
|
||||
Deja pasar OPTIONS (preflight CORS) sin autenticación.
|
||||
Deja pasar OPTIONS (preflight CORS) sin autenticación. El rango mínimo se
|
||||
resuelve en cada petición desde skeen.role (editable), con respaldo en
|
||||
ROLE_RANKS.
|
||||
"""
|
||||
required = RANK.get(min_role, 10)
|
||||
|
||||
def decorator(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper(self, *args, **kw):
|
||||
@@ -170,7 +171,7 @@ def require_role(min_role='lectura'):
|
||||
user = current_user(request.env)
|
||||
if not user:
|
||||
return _json({'status': 'error', 'message': 'No autenticado'}, 401)
|
||||
if user.role_rank() < required:
|
||||
if user.role_rank() < min_rank(request.env, min_role):
|
||||
return _json({'status': 'error', 'message': 'Sin permiso'}, 403)
|
||||
if user.role == 'medico' and any(
|
||||
request.httprequest.path == p or request.httprequest.path.startswith(
|
||||
@@ -184,6 +185,33 @@ def require_role(min_role='lectura'):
|
||||
return decorator
|
||||
|
||||
|
||||
def require_perm(perm):
|
||||
"""Decorator: exige token válido y el permiso por acción `perm`.
|
||||
|
||||
Se apila junto a @require_role: el rango sigue siendo el guard base y este
|
||||
decorador refina la acción concreta contra 'skeen.role_perms' (defaults en
|
||||
permissions.py). El rol admin siempre pasa. Un permiso ausente = acceso
|
||||
denegado (403), nunca 200.
|
||||
"""
|
||||
def decorator(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper(self, *args, **kw):
|
||||
if request.httprequest.method == 'OPTIONS':
|
||||
return _json({}, 200)
|
||||
user = current_user(request.env)
|
||||
if not user:
|
||||
return _json({'status': 'error', 'message': 'No autenticado'}, 401)
|
||||
if not has_perm(user, perm):
|
||||
return _json({
|
||||
'status': 'error',
|
||||
'message': 'Sin permiso: %s' % PERM_LABELS.get(perm, perm),
|
||||
}, 403)
|
||||
request.frontend_user = user
|
||||
return func(self, *args, **kw)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Permisos de ACCION dentro de la Agenda (selector por usuario).
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user