Saltar a contenido

Seguridad y RBAC (Core)

El core incluye un sistema RBAC centralizado (Role-Based Access Control) para gestionar los permisos de usuarios en relación a los negocios (business_id).


Objetivo

  • Asegurar que cada usuario solo pueda ver o modificar datos del negocio al que pertenece.
  • Centralizar las políticas de permisos en un solo archivo (core/security/rbac.py).
  • Evitar duplicación de lógica en cada módulo.

Ubicación

core/security/rbac.py

Acciones soportadas

Action = Literal["view", "create", "update", "archive"]

Cada permiso se define sobre una de estas acciones.


Política base

POLICY = {
    "owner":  {"view": True, "create": True, "update": True, "archive": True},
    "viewer": {"view": True, "create": False, "update": False, "archive": False},
    # futuros roles: editor, manager, member, etc.
}

Funciones principales

get_user_role_for_business(user_id, business_id)

Consulta en la tabla login_business_linked_to_user para obtener el rol.

has_perm(user_id, business_id, action)

Devuelve True/False según si el rol permite la acción.

assert_perm_or_raise(user_id, business_id, action)

Lanza PermissionError si el usuario no tiene permiso.

build_can_map(user_id, business_id)

Devuelve un diccionario con todos los permisos:

{"view": true, "create": false, "update": false, "archive": false}


Diagrama de flujo

flowchart TD
    A[Usuario solicita acción] --> B[Obtener business_id de la sesión]
    B --> C[get_user_role_for_business]
    C --> D{Rol encontrado?}
    D -->|No| E[Denegar acceso]
    D -->|Sí| F[Consultar POLICY]
    F --> G{Permiso para acción?}
    G -->|Sí| H[Permitir ejecución]
    G -->|No| E[Denegar acceso]

Ejemplo de uso en una vista

from flask_login import current_user
from core.security.rbac import assert_perm_or_raise

@bp.route("/customers")
def list_customers():
    business_id = session["business_id"]
    assert_perm_or_raise(current_user.id, business_id, "view")
    # continuar con la lógica

Ventajas

  • Centralización: las reglas están en un solo archivo.
  • Flexibilidad: fácil agregar nuevos roles o acciones.
  • Escalabilidad: se aplica de forma uniforme a todos los módulos.
  • Compatibilidad: funciona con ORM (SQLAlchemy) y MySQL crudo.