Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/jpbarbatic/webapp/llms.txt

Use this file to discover all available pages before exploring further.

El módulo de Roles y Permisos implementa un sistema de control de acceso basado en roles (RBAC) que determina qué acciones puede realizar cada usuario dentro del panel. Los roles agrupan permisos que se asignan a los usuarios mediante la columna id_rol, y cada permiso puede tener una dependencia jerárquica a través del campo depende_de.

Modelo de datos

El sistema RBAC usa tres tablas interrelacionadas:

Tabla roles

ColumnaTipoNuloDescripción
idint(11) AUTO_INCREMENTNOIdentificador único del rol
nombrechar(50)NONombre del rol (p. ej. admin)
descripcionchar(100)NODescripción legible del rol

Tabla permisos

ColumnaTipoNuloDescripción
idint(11) AUTO_INCREMENTNOIdentificador único del permiso
nombrechar(50)NONombre del permiso en formato recurso.accion
descripcionchar(100)NODescripción legible
depende_deint(11)NOID del permiso padre (0 = sin dependencia)
El campo depende_de permite modelar jerarquías: por ejemplo, usuarios.borrar depende de usuarios.consulta (id=1), lo que indica que para borrar primero hay que poder consultar.

Tabla roles_permisos

Tabla pivote que asigna permisos a roles en relación N:M.
ColumnaTipoDescripción
id_rolint(11)FK → roles.id
id_permisoint(11)FK → permisos.id

Permisos disponibles (datos seed)

Los siguientes permisos están incluidos en esquema.sql:
IDNombredepende_deDescripción
1usuarios.consulta0 (raíz)Consultar el listado de usuarios
2usuarios.crear0 (raíz)Crear nuevos usuarios
3usuarios.borrar1 (usuarios.consulta)Borrar usuarios
4usuarios.actualizar1 (usuarios.consulta)Actualizar datos de usuarios

Funciones PHP (includes/permisos.php)

El archivo includes/permisos.php centraliza todas las operaciones sobre roles y permisos:

obtener_roles($db)

Devuelve todos los roles de la tabla roles.
$roles = obtener_roles($db);
// Devuelve: [['id'=>1,'nombre'=>'admin','descripcion'=>'Administrador'], ...]

obtener_todos_permisos($db)

Devuelve todos los permisos ordenados por nombre.
$permisos = obtener_todos_permisos($db);
// Devuelve: [['id'=>1,'nombre'=>'usuarios.consulta','descripcion'=>'','depende_de'=>0], ...]

obtener_permisos_rol($db, $id_rol)

Devuelve los permisos asignados a un rol concreto, uniendo roles_permisos con permisos.
$permisos_rol = obtener_permisos_rol($db, 1);
// Devuelve: [['id'=>1,'nombre'=>'usuarios.consulta'], ['id'=>2,'nombre'=>'usuarios.crear']]

actualizar_permisos_rol($db, $permisos, $id_rol)

Reemplaza todos los permisos de un rol: primero elimina los existentes con DELETE FROM roles_permisos WHERE id_rol=? y luego inserta los nuevos uno a uno.
// Asignar permisos 1, 2 y 3 al rol 1
actualizar_permisos_rol($db, [1, 2, 3], 1);
Esta operación es destructiva: ejecuta un DELETE FROM roles_permisos WHERE id_rol=? antes de insertar los nuevos permisos. Si la llamada falla a mitad, el rol puede quedar sin permisos. Considera envolver la llamada en una transacción (db_begin / db_commit / db_rollback).

Rutas del módulo

URLMétodoControladorDescripción
roles/GETpublic/roles/index.phpListado paginado de roles
roles/editar.php?id=NGETpublic/roles/editar.phpFormulario de edición con permisos
roles/guardar.phpPOSTpublic/roles/guardar.phpGuarda cambios del rol y sus permisos
permisos/GETpublic/permisos/index.phpDiagnóstico: lista permisos del rol 1

Listado de roles

public/roles/index.php usa paginacion() de includes/utilidades.php y db_select con paginación estándar:
extract(paginacion());
$params = [];
$sql = 'SELECT * FROM roles';
$res = db_select($db, $sql, $params, $items_pagina, $offset, $orden, $orden_dir);
extract($res);

$titulo = 'Roles';
$vista  = 'roles/listado';
require('../../html/plantilla.html.php');

Edición de un rol

public/roles/editar.php recupera el rol con db_get_by_id, carga todos los permisos disponibles con obtener_todos_permisos y los permisos ya asignados al rol con obtener_permisos_rol, luego renderiza la plantilla de edición:
$id          = $_REQUEST['id'];
$rol         = db_get_by_id($db, 'roles', $id);
$permisos    = obtener_todos_permisos($db);
$permisos_rol = obtener_permisos_rol($db, $id);

$titulo = 'Editar rol';
$vista  = 'roles/editar';
require('../../html/plantilla.html.php');
El formulario de edición (html/roles/formulario.html.php) muestra un checkbox por cada permiso, marcando los que ya tiene asignados el rol. Al enviar el formulario, public/roles/guardar.php actualiza el rol y sus permisos:
// public/roles/guardar.php
$id  = $_REQUEST['id'];
$res = db_update($db, 'usuarios', $_REQUEST);  // Bug en el código fuente: debería ser 'roles'
actualizar_permisos_rol($db, $_REQUEST['permisos'], $id);
$_SESSION['mensaje']['ok'] = 'Registro guardado correctamente';
header('Location: editar.php?id=' . $id);
El código fuente de roles/guardar.php llama a db_update($db, 'usuarios', ...) en lugar de db_update($db, 'roles', ...). Este es un bug en el código fuente: la actualización de los campos del rol (nombre, descripción) se dirige erróneamente a la tabla usuarios. Los permisos del rol sí se actualizan correctamente mediante actualizar_permisos_rol.
El formulario HTML usa data-depende para indicar la dependencia de cada permiso:
<input type="checkbox"
       data-depende="<?= $permiso['depende_de'] ?>"
       <?= in_array($permiso['id'], array_column($permisos_rol, 'id')) ? 'checked' : '' ?>
       name="permisos[]"
       value="<?= $permiso['id'] ?>">
<?= $permiso['nombre'] ?>

Verificación de permisos en las vistas

La función es_visible($vista) de includes/utilidades.php comprueba si el usuario tiene algún permiso que empiece por el nombre de la vista. Se usa en html/nav.html.php para mostrar u ocultar elementos del menú:
if (es_visible('usuarios')) {
    // mostrar enlace al módulo de usuarios
}
Internamente usa preg_grep sobre el array $_SESSION['permisos']:
function es_visible($vista) {
    return preg_grep("/^$vista\\.*/", array_column($_SESSION['permisos'], 'nombre'));
}

Endpoint de diagnóstico (permisos/index.php)

public/permisos/index.php es una herramienta de depuración que imprime los permisos del rol 1 y la lista de roles usando print_r:
$db = require_once('../../includes/backend.php');
require_once('../../includes/utilidades.php');
require_once('../../includes/permisos.php');

$permisos = obtener_permisos_rol($db, 1);
print_r($permisos);

$roles = obtener_roles($db);
print_r($roles);
El endpoint permisos/ devuelve datos internos del sistema de permisos en texto plano sin ningún formato de seguridad adicional. Debe eliminarse o protegerse con una comprobación de rol de administrador antes de ir a producción.
Para añadir nuevos permisos al sistema, inserta filas en la tabla permisos y luego asígnalas a los roles correspondientes desde la interfaz de edición de roles o directamente con actualizar_permisos_rol.

Build docs developers (and LLMs) love