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:
@@ -42,6 +42,42 @@ ROLE_RANKS = {
|
||||
'lectura': 10,
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Roles dinámicos (modelo skeen.role). ROLE_SELECTION/ROLE_RANKS quedan como
|
||||
# respaldo para el arranque (antes de que la semilla XML esté disponible) y para
|
||||
# no romper instalaciones viejas.
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
|
||||
def role_records(env):
|
||||
"""Registros de skeen.role (incluye inactivos) o lista vacía si no existe."""
|
||||
try:
|
||||
return env['skeen.role'].sudo().with_context(active_test=False).search([])
|
||||
except KeyError:
|
||||
return []
|
||||
|
||||
|
||||
def role_selection(env):
|
||||
"""[(code, name)] de los roles configurados, con respaldo estático."""
|
||||
seleccion = [(r.code, r.name) for r in role_records(env) if r.code]
|
||||
return seleccion or ROLE_SELECTION
|
||||
|
||||
|
||||
def role_keys(env):
|
||||
"""Códigos de rol válidos (incluye inactivos, para no invalidar históricos)."""
|
||||
return tuple(k for k, _ in role_selection(env))
|
||||
|
||||
|
||||
def role_rank_map(env):
|
||||
"""{code: rank} de los roles configurados, con respaldo estático."""
|
||||
mapa = {r.code: r.rank for r in role_records(env) if r.code}
|
||||
return mapa or dict(ROLE_RANKS)
|
||||
|
||||
|
||||
def min_rank(env, code):
|
||||
"""Rango mínimo exigido por un código ('recepcion' -> 50 por defecto)."""
|
||||
return role_rank_map(env).get(code, ROLE_RANKS.get(code, 10))
|
||||
|
||||
MENU_ROLES_KEY = 'skeen.menu_roles'
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
@@ -69,16 +105,30 @@ WRITE_RANK_MIN = 'recepcion'
|
||||
# rango, no por nombre, para no duplicar la lista de roles.
|
||||
|
||||
|
||||
# Mapa de cada acción de agenda al permiso por rol equivalente. El permiso de
|
||||
# rol es el default; la lista propia del usuario (agenda_perms) lo pisa.
|
||||
AGENDA_ROLE_PERM = {
|
||||
'ver': 'agenda.ver',
|
||||
'agendar': 'agenda.agendar',
|
||||
'editar': 'agenda.editar',
|
||||
'eliminar': 'agenda.eliminar',
|
||||
'visitas': 'agenda.visitas',
|
||||
}
|
||||
|
||||
|
||||
def agenda_defaults_for(user):
|
||||
"""Permisos de agenda por defecto de un usuario (sin lista propia)."""
|
||||
ver = ['ver']
|
||||
"""Permisos de agenda por defecto de un usuario (sin lista propia).
|
||||
|
||||
Se derivan de los permisos por acción del rol; 'ver' siempre se conserva.
|
||||
"""
|
||||
if user is None:
|
||||
return list(ver)
|
||||
if user.role == 'admin':
|
||||
return list(AGENDA_PERM_KEYS)
|
||||
if user.role_rank() >= ROLE_RANKS.get(WRITE_RANK_MIN, 50):
|
||||
return list(AGENDA_PERM_KEYS)
|
||||
return list(ver)
|
||||
return ['ver']
|
||||
from .permissions import resolve_role_perms_for_user
|
||||
role_perms = resolve_role_perms_for_user(user)
|
||||
acciones = [a for a, key in AGENDA_ROLE_PERM.items() if role_perms.get(key)]
|
||||
if 'ver' not in acciones:
|
||||
acciones.insert(0, 'ver')
|
||||
return acciones
|
||||
|
||||
|
||||
def resolve_agenda_perms(user):
|
||||
|
||||
Reference in New Issue
Block a user