Laboratorio 1 – m – 4 Permisos Granulares

Vamos a hablar de permisos dentro de tu aplicación. Esto entra tanto en Fundamentos como en el Laboratorio, y voy a realizar después pruebas con otras LLM. Como en todo lo que hacemos en este laboratorio, que estamos probando Minimax, nos estaremos enfocando en lo gráfico y lo demás es después.

El repositorio del laboratorio esta en https://github.com/AlfonsoOrozcoAguilarnoNDA/lemkotir 

Uno de los errores más graves que he visto de seguridad en diseño es cargar los permisos del usuario al inicio de la sesión solamente. Imagínate que está logeado desde su casa, no lo sabes. O está en tres máquinas. Lo más sano, aunque cueste recursos, es leer primero el usuario de nuestra sesión, y sobre él un permiso que nos interese. Aparentemente son llamadas en balde, pero la prioridad es siempre la seguridad.

  • Leer el permiso directamente de la base de datos en cada validación es la única forma de garantizar que un “despido” o un “cambio de rol” tenga efecto inmediato, sin esperar a que el usuario cierre sesión.

Vamos a suponer que tienes a un usuario A y un usuario B y C. En USA los llaman Alice, Bob y Charles.

Por default, cuando das de alta a un usuario este no debe tener ningún permiso específico. Ahora bien, imagínate que después decides que hay algo que solo debe ver si tiene el permiso de “Lista de usuarios”. ¿Cómo es eso? Bueno, a lo mejor tienes una exportación de usuarios para fechas de cumpleaños o un reporte, pero no cualquiera debe poder exportar eso.

Mi lógica es:

if (tienepermiso("LISTA USUARIOS")) {
    echo muestralista();
} // lista usuarios

Nota que termino el if con un comentario, eso siempre ayuda por legibilidad.

Así que necesitamos dos tablas de datos:

a) Una tabla que sea la lista de los derechos. b) Otra que sea una liga entre los derechos y el número de los usuarios.

(Prefiero la palabra derechos porque implica responsabilidades).

La idea es que si tu código verifica y no existe ese permiso “Lista usuarios” en la tabla de derechos, que lo inserte. Así no tienes que dar altas, bajas o cambios manuales en una de las tablas.

Y en la otra solo pones una cuadrícula, por decirlo de algún modo. Seleccionas al usuario y del lado izquierdo te aparece en verde el nombre del permiso que tiene, y en rojo el que no tiene. ¿Qué esperamos? Que al dar clic en el verde se vuelva rojo (borrando todos los registros de ese usuario-permiso, por si está duplicado) y si es rojo, lo inserte.

Simple, ¿no? Insertas o quitas de la tabla de permisos y es un permiso granular.

Para terminar la idea, te comento que no se deben sumar jamás los permisos. Suponemos que Bob, el usuario B, es contador y ahora va a ser auditor. Los permisos son diferentes, no se suman.

Suponiendo que Alice sea auditor, B sea contador y C sea contador, podemos borrar primero lospersonos de BOB y después copiar los permisos de Alice a Bob, pero jamás sumarlos.

PROMPT PARA LA IA: LABORATORIO 4 – PERMISOS GRANULARES Y SEGURIDAD DINÁMICA

Identificación Obligatoria: Al inicio del archivo permisos.php y de la función, incluye un comentario PHP que identifique tu modelo y la fecha actual , reconociendo tu papel como co-programador en el experimento de vibecodingmexico.com.

Contexto Técnico:

  • Proyecto: Lemkotir.

  • Entorno: PHP 8.x Procedural, MariaDB (UTF8mb4), Bootstrap 4.6, Font Awesome 5.0.

  • Archivos base: Incluir session_start() e include_once 'config.php'.

PARTE 1: La Lógica de Seguridad (Función Robusta) Crea una función llamada tiene_permiso($nombre_derecho) con estas reglas:

  1. Sanitización Crítica: Antes de cualquier consulta, el parámetro $nombre_derecho debe pasarse a MAYÚSCULAS, eliminar espacios al inicio/final y colapsar múltiples espacios o tabuladores internos en uno solo (usar preg_replace). Ejemplo: " ver sistema " -> "VER SISTEMA".

  2. Auto-Inserción: Si el derecho (limpio) NO existe en la tabla ch_derechos, debe insertarse automáticamente con una descripción genérica.

  3. Validación en Caliente: Consultar la tabla ch_derechosusuarios usando el id del usuario en sesión ($_SESSION['id']). Retornar true si tiene el permiso, false si no.

  4. Estilo de Código: Terminar cada bloque if con un comentario de cierre para legibilidad. Ejemplo: } // termina validacion.

PARTE 2: Interfaz de Gestión (El Semáforo) Crea una pantalla llamada permisos.php con la estética “Metro-Metal” de los laboratorios anteriores:

  1. Selector de Usuario: Un dropdown para elegir un usuario de cat_users.

  2. Cuadrícula de Permisos: Mostrar todos los derechos de ch_derechos.

    • Botón VERDE (Success): Si el usuario YA tiene el permiso. Al hacer clic, ejecuta un DELETE (limpiando duplicados) para revocarlo.

    • Botón ROJO (Danger): Si el usuario NO tiene el permiso. Al hacer clic, ejecuta un INSERT para asignarlo.

  3. Clonación de Derechos: Un pequeño formulario donde selecciones un “Usuario Origen” y un “Usuario Destino”. Al procesar: BORRAR PRIMERO todos los permisos del destino y COPIAR los del origen (los permisos no se suman, se reemplazan).

PARTE 3: El Caso de Prueba (Seguridad de Sistema) En un archivo llamado cambiap.php, implementa el siguiente bloque protegido:

  • Si tiene_permiso("VER SISTEMA") es verdadero, mostrar en una card de Bootstrap la información de: php_uname(), PHP_OS, y las variantes 's', 'n', 'r', 'v', 'm'.

  • Si no tiene permiso, mostrar un aviso discreto “No triene permiso para ver sistema”

Estructura de Tablas Referencia (YA CREADAS):

SQL

-- ch_derechos: NUM_DERECHO (PK AI), DESCRIPCION (UNIQUE)
-- ch_derechosusuarios: IDENTIDAD (PK AI), NUM_DERECHO, idUsuario
Estructurade referencia :

CREATE TABLE `ch_derechos` (
`NUM_DERECHO` int(11) NOT NULL AUTO_INCREMENT,
`DESCRIPCION` varchar(50) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
PRIMARY KEY (`NUM_DERECHO`),
UNIQUE KEY `idx_descripcion` (`DESCRIPCION`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE `ch_derechosusuarios` (
`IDENTIDAD` int(11) NOT NULL AUTO_INCREMENT,
`NUM_DERECHO` int(11) DEFAULT NULL,
`idUsuario` int(11) DEFAULT NULL,
PRIMARY KEY (`IDENTIDAD`),
KEY `idx_derecho` (`NUM_DERECHO`),
KEY `idx_usuario` (`idUsuario`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;

CREATE TABLE `cat_users` (
`id` int UNSIGNED NOT NULL,
`Rol` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'N/A',
`username` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NOT NULL,
`first_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
`last_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`PAPELERA` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci DEFAULT 'NO'

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
Recuerda que la tablade usuarios el campo NUMERICO es ID 
y sabemos ya estosdatos quedebes poder mostrar.
 Muestrame nombre username y rol del usuario dame aescoger en un combo de que usuario lo vamosahacer. Agrega una funcion SUSPENDER USUARIO, que lo que hagas es pasar papelera a SI, pero no puedo suspenderme ami mismo, ais que si soy el usuario en $_SESSION['user_id'] = $user['id'] no permitasclick en el boton de suspender usuario usaalgo quese veab ien usando tus esquemasanteriores que hemosvisto ylasventaas de boostrap. Instrucción Final: Genera el código completo, asegurando que el CSS sea consistente con el degradado azul metálico y las sombras suaves de los laboratorios anteriores. ¡Prioriza la seguridad y la limpieza de strings!

FIN DEL PROMPT

Pongo aqui las pantallas de resultados. Minimax sigue siendo coherente y gemini empezó a desvariar un poco, asi que creo que empezaré un nuevo tema con gemini mañana. Porque? a a veces el contexto se le agota. yo sigo con la misma pantalla  de chat together y salio mejor que gemini.

Nota que gemini lo estuve usando solo para las cabeceras de la serie.

Por hacer: ajustar colores de botones.

Se subieron dos archivos. cambiap.php y permisos.php que luego integraremos en algo mayor.

Aviso que nano banana tambien se nego a hacer la imagen pero si el prompt, asi que le pase el contenido de este tema a grok y el hizo en esta ocasion la imagen de cabecera .

Prompt: “A high-end, futuristic digital header for a tech blog post about software security. The style is ‘Techno-Cyberpunk Auditor’. In the foreground, a translucent 3D grid of interface panels floats in perspective over a dark metallic blue gradient background. These panels form a ‘Permissions Grid’ where some cells glow in ‘Success Green’ (representing active rights) and others in ‘Danger Red’ (representing revoked rights). In the center, a stylized, glowing runic symbol is integrated with a modern database icon and a security shield with a padlock. Subtile lines of PHP code, SQL queries, and hexadecimal numbers are blurred and scrolling in the deep background. The overall aesthetic is clean, professional, and high-contrast, symbolizing real-time granular control and dynamic security management. Cinematic lighting, sleek professional look.”

El repositorio del laboratorio esta en https://github.com/AlfonsoOrozcoAguilarnoNDA/lemkotir 

Related Posts

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *