Los módulos y roles es la forma usada para controlar el acceso a las distintas partes de un aplicación. No hay que confundir estos módulos con los usados a nivel de los menús para agrupar funcionalidades.
Los módulos representan permisos que un usuario tiene en una aplicación determinada. Los módulos se asignan cuando se lleva a cabo una asociación entre un usuario y una aplicación, y se cargan en el inicio de la aplicación. Cada módulo tiene un código, una descripción y opcionalmente puede tener un valor. Cada usuario puede tener asignado uno o varios módulos, y para cada uno puede modificar su valor. Algunos usos habituales de módulos son el controlar si un usuario puede acceder a una opción de menú, o si puede ver/editar un campo determinado de una pantalla, o para guardar alguna información necesaria para la aplicación (departamento del usuario, año de la contabilidad, ...). También suelen usarse para definir variables globales para todos los usuarios, aunque en este caso es recomendable asignarlos a roles (ver apartado siguiente).
Ejemplo:
Todos los usuarios que consulten la aplicación PRESUPUESTARIO deben tener el módulo M_CONSUL_PRESUPUESTARIO, es decir, nadie que no tenga ese módulo asociado podrá acceder al apartado de listados de la aplicación
Sólo el personal de la oficina presupuestaria tendrá acceso a la manipulación de datos, es decir el módulo M_MANT_PRESUPUESTARIO
Sólo técnicos y el jefe de la oficina presupuestaria tendrán tendrán acceso a la entrada de menú "control de crédito". Pues serán aquellos usuarios que tengan el módulo M_MANT_PRESUPUESTARIO, con el valor TECNICO o el valor JEFE.
Usuarios:
Sandra (Administrativa de otro departamento que consulta la aplicación): Tiene el módulo M_CONSUL_PRESUPUESTARIO
Juan (Administrativo): Tiene el módulo M_MANT_PRESUPUESTARIO, (bien sin valor, o con el valor PERFIL_ADMD)
Pepe (Técnico): Tiene el módulo M_MANT_PRESUPUESTARIO con valor PERFIL_TECNICO
Pilar (Jefa de la oficina presupuestaria): Tiene el módulo M_MANT_PRESUPUESTARIO con valor PERFIL_JEFE
Módulos:
Nombre: M_CONSUL_PRESUPUESTARIO
Descripción: Módulos de acceso a las consultas de la aplicación de presupuestario
Valores posibles: <COMPLETAR>
Nombre: M_MANT_PRESUPUESTARIO
Descripción: Módulos de acceso a las opciones de mantenimiento de la aplicación de presupuestario
Valores posibles: PERFIL_ADMD, PERFIL_TECNICO o PERFIL_JEFE
Los roles representan el papel que el usuario desempeña en una aplicación y a diferencia de los módulos, cada usuario sólo puede tener uno y no tienen valor. ¿Entonces para que queremos los roles si podemos hacer lo mismo usando módulos sin valor? Podemos ver los módulos como los permisos básicos, y los roles como agrupaciones de módulos. Realmente los roles se utilizan para facilitar la gestión de usuarios. Si sólo usamos módulos y por ejemplo tuviéramos 30 módulos, seria muy difícil clasificar a los usuarios ya que seguramente cada uno tendría una combinación distinta de módulos, y cada vez que hubiera que dar de alta un usuario tendríamos que tener un criterio claro para saber cuales de los módulos asignar. Con roles es más simple, ya que es sencillo ver los permisos de cualquier usuario (viendo el role suele ser suficiente), y para añadir nuevos usuarios normalmente solo necesitaremos saber su role. Para que esto sea fácil de gestionar, tendríamos que tener algún mecanismo que nos permitiera asignar módulos a roles, y que los usuarios con un role "heredaran" estos módulos. Lo más flexible seria tener esta información en tablas aunque también se podría empezar haciéndolo directamente en PHP (o ver abajo módulos dinámicos):
if ($role == 'admin') { // combinacion 1 $modulos[] = array('borrarTodo'=>array('descrip'=>'borra todo',)); $modulos[] = array('verTodo'=>array('descrip'=>'ver todo',)); $modulos[] = array('opcion11'=>array('descrip'=>'opcion 11',)); $modulos[] = array('opcion12'=>array('descrip'=>'opcion 12',)); $modulos[] = array('opcion13'=>array('descrip'=>'opcion 13',)); ... } elseif ($role == 'gestor') { // combinacion 2 $modulos[] = array('verTodo'=>array('descrip'=>'ver todo',)); $modulos[] = array('opcion12'=>array('descrip'=>'opcion 12',)); ... } elseif ($role == '...') { ...
De esta forma, añadir un nuevo usuario de tipo administrador consistiría simplemente en indicar su role, en vez de tener que asignarle los N módulos que tienen los administradores.
La solución más flexible seria usar sólo módulos para controlar cualquier característica que pueda ser configurable por usuario, y asignar los módulos a los roles de forma centralizada (bien en base de datos o en el inicio de la aplicación). De esta forma el programador solo tendría que tratar con los módulos, y el analista con los módulos de cada role.
El ejemplo anterior usando roles podría ser:
módulos: M_CONSUL_PRESUPUESTARIO, M_MANT_PRESUPUESTARIO (ambos sin valor)
roles:
PERFIL_ADMD (módulo M_MANT_PRESUPUESTARIO), asignado a Juan
PERFIL_TECNICO (módulo M_MANT_PRESUPUESTARIO), asignado a Pepe
PERFIL_JEFE (módulo M_MANT_PRESUPUESTARIO), asignado a Pilar
PERFIL_OTROS (módulo M_CONSUL_PRESUPUESTARIO), asignado a Sandra
En este caso las dos soluciones tienen una complejidad similar, aunque las diferencias serán más evidentes conforme aumenten el número de módulos y usuarios. Si por ejemplo decidiéramos que ahora todos los técnicos han de tener un nuevo módulo X, sin usar roles tendríamos que añadir ese módulo a todos los usuarios que tuvieran el módulo M_MANT_PRESUPUESTARIO con valor PERFIL_TECNICO; usando roles seria simplemente añadir el módulo X al role PERFIL_TECNICO.
El primer ejemplo de uso de módulos puede encontrarse en la creación de los ficheros xml que da lugar a la pantalla de inicio de la aplicación, en dichos ficheros se utiliza la etiqueta "controlAcceso" para indicar que módulos necesita tener asignados un usuario para acceder a la opción. Por ejemplo:
<opcion titulo="Prueba del árbol" descripcion="Pues eso... prueba del árbol" urlAbs="phrame.php?action=IgepPruebaArbol__iniciarVentana" imagen="menu/24.gif"> <controlAcceso><moduloPermitido id="M_INTRANET"/></controlAcceso> </opcion>
Con el párrafo anterior de XML, se indica que la entrada de la aplicación "Prueba del árbol" sólo estará disponible para aquellos usuarios que cuenten entre sus módulos el M_INTRANET. También se puede hacer el control usando un role.
Los módulos podemos usarlos en otros sitios, y podemos acceder a ellos a través de
Tabla 6.1. Tabla de metodos 1
método | descripción |
---|---|
IgepSession::hayModulo( <modulo> ) | Devuelve un booleano indicando si el usuario tiene asignado el módulo. |
IgepSession::dameModulo( <modulo> ) | Información del módulo. |
ComunSession::dameModulos() | Todos los módulos (estáticos) asignados al usuario (se recomienda usar el método con el mismo nombre de IgepSession). |
Cuando queremos usar módulos que no estén permanentemente asignados a un usuario, sino que la asignación dependa de otras circunstancias que puedan ir cambiando durante la ejecución de la aplicación, la asignación no la haremos en el inicio de la aplicación. Para poder añadir o eliminar módulos en tiempo de ejecución, y conseguir, entre otras cosas el poder hacer accesibles u ocultar opciones de menú dinámicamente, podemos además usar:
Tabla 6.2. Tabla de metodos 2
método | descripción |
---|---|
IgepSession::anyadeModuloValor( <modulo>, <valor>=null, <descripcion>=null ) | Añade un nuevo módulo al usuario |
IgepSession::quitaModuloValor( <modulo>, <valor>=null ) | Quita el módulo al usuario; si se le pasa valor, sólo lo quita si el valor del módulo coincide con el valor pasado |
IgepSession::hayModuloDinamico( <modulo> ) | Devuelve un booleano indicando si el usuario tiene asignado el módulo dinámico |
IgepSession::dameModuloDinamico( <modulo> ) | Información del módulo dinámico |
IgepSession::dameModulosDinamicos() | Todos los módulos dinámicos asignados al usuario |
IgepSession::dameModulos() | Todos los módulos asignados al usuario |
Estos módulos les llamaremos módulos dinámicos. A efectos del framework, no hay diferencia entre los módulos cargados inicialmente y los módulos dinámicos. El plugin CWPantallaEntrada ya incluye dicha funcionalidad, por lo que si en alguno de los ficheros XML aparece una opción como esta:
<opcion titulo="Prueba de módulo dinamico" descripcion="Ejemplo de activación y descativación de opciones en ejecución" urlAbs="http://www.gvpontis.gva.es" imagen="menu/24.gif"> <controlAcceso><moduloPermitido id="MD_GVA"/></controlAcceso> </opcion>
hasta que en algún punto de nuestro código PHP no realicemos una llamada como esta:
IgepSession::anyadeModuloValor("MD_GVA")
la opción permanecerá oculta.
Si después de habilitarla queremos volver a ocultarla, basta con ejecutar la opción:
IgepSession::quitaModuloValor("MD_GVA")
Podemos obtener el role del usuario con el método IgepSession::dameRol().
Para que los cambios sean efectivos de forma visual en los menús, es necesario que se reinterprete el código XML, cosa que sólo se hace cuando se pasa por la pantalla principal de la aplicación, mientras tanto NO será actualizada la visibilidad/invisibilidad de las distintas ramas, módulos y/o opciones. Por tanto, convendrá también añadir en las acciones que correspondan al menú, comprobación explícita de que se tienen los módulos/roles necesarios para el acceso.