Después de varios intentos e ideas, he llegado a una solución que me parece idónea para mi y que por tanto, es posible que le pueda ser útil a alguien más, y como yo he mamado bastante de la "teta" de este portal, me veo en la obligación de compartir mi utilidad por si a alguien le puede ser útil también.
Antes de comenzar, quiero dejar claro que no soy programador profesional y es posible que el código que ponga no sea de un gran nivel, pero les aseguro que está hecho con un gran cariño. Así las cosas, ahí va lo que he hecho.
CONTROL DE ACCESOS EN APLICACIONES HECHAS EN GAMBAS
Introducción
A continuación se intenta plasmar, a modo de resumen, un procedimiento para establecer un control de accesos a nuestras aplicaciones hechas en gambas. La idea inicial la he obtenido de Drupal que utiliza el concepto de roles para controlar los accesos a los distintos contenidos. No se como implementa Drupal dicha gestión pero me he quedado con su filosofía y he desarrollado mi propio sistema.
Conceptos de partida
Antes de entrar en materia conviene repasar los conceptos que se van a utilizar en la explicación posterior
usuarios
Lo primero que debe tener nuestra aplicación es una relación de usuarios que se identificarán mediante un nombre, alias o, como también se suele denominar “nick”, único para cada uno de ellos: pepe22, popeye,...etc
roles
Un rol identifica una capacidad para hacer algo, es decir, en nuestro sistema de control de accesos otorgaremos privilegios a los roles, por tanto deberemos crear roles de acuerdo a los niveles de privilegio o capacidad de acción que consideremos oportuno. Roles, por tanto, pueden ser: administrador, visitante, anónimo, jefes, empleados, secretarias,....etc, etc. Podemos crear tantos roles como consideremos conveniente o necesario.
asignación de roles
Cada usuario pertenecerá a uno o varios roles y de esta forma podrá adquirir los privilegios que le asignemos a cada uno de estos. Debemos tener en cuenta que privilegio de acceso significa la posibilidad de ejecutar una determinada función o procedimiento, abrir un determinado formulario, etc.
tablas
En primer lugar vamos a definir las tablas que necesitaremos para implementar este control de accesos.
tabla asignaroles(r)
El objetivo de esta tabla es asignar a cada usuario los roles que necesite, el formato de esta tabla podrá ser algo así:
id | nick | rol
1 | pepe222 | administrador
2 | popeye | lector
3 | bonita13 | lector
4 | bonita13 | eliminador
Mediante esta tabla lo que hemos hecho es asignar roles a los distintos usuarios de nuestro sistema, y podemos ver que a bonita13 se le han asignado 2 roles distintos por lo que tendrá privilegios para aquello que definamos al rol lector y también para el rol de eliminador. Por otro lado, pepe222 y popeye únicamente tendrán los privilegios que les otorguen sus respectivos roles.
tabla accesos
Mediante la tabla accesos, asignamos los privilegios a cada rol y su aspecto sería algo así como:
id | rol | sitio (o acción permitida)
1 | administrador | frmAgregarUsuario
2 | administrador | InfListaUsuarios
3 | administrador | btnBorrar_click
4 | administrador | frmPresentaDatos
5 | eliminador | btnBorrar_click
6 | lector | frmPresentaDatos
El contenido de esta tabla nos indica que los usuarios que pertenezcan al rol administrador podrán acceder a los formularios para agregar usuarios y presentar datos, también podrá borrar mediante la acción de btnBorrar_click y ver el contenido del informe de lista de usuarios, por el contrario los usuarios que pertenezcan al rol eliminador podrán borrar y los del rol lector, únicamente podrán acceder al formulario de presentación de datos.
Como se puede ver mediante esta técnica podríamos controlar el acceso a todos y cada uno de los rincones de nuestra aplicación
función para comprobar si a un rol se le permite acceso
La siguiente función es la encargada de controlar si un usuario está autorizado a realizar una determinada acción o entrar en un determinado sitio. Los datos de entrada son el nombre del usuario, que obviamente debe ser uno de los nick de la tabla asignaroles y la identificación del sitio o la acción a controlar. La función nos devuelve un valor null si ninguno de los roles a los que pertenece el usuario está autorizado para acceder al sitio o ejecutar la acción y nos devolverá un número con el resultado de la consulta hecha sobre la base de datos.
PUBLIC FUNCTION CompruebaAcceso(Usuario AS String, SitioControlado AS String) AS Boolean
DIM sConsulta AS String
sConsulta = "SELECT a.sitio, r.nick FROM "
sConsulta &= "BD.accesos a JOIN BD.asignaroles r ON a.rol = r.rol "
sConsulta &= "WHERE r.nick = '" & Usuario & "' AND a.sitio ='" & SitioControlado & "'"
ModConexion.rs = ModConexion.db.Exec(sConsulta)
RETURN (ModConexion.rs1.Count)
END
DIM sConsulta AS String
sConsulta = "SELECT a.sitio, r.nick FROM "
sConsulta &= "BD.accesos a JOIN BD.asignaroles r ON a.rol = r.rol "
sConsulta &= "WHERE r.nick = '" & Usuario & "' AND a.sitio ='" & SitioControlado & "'"
ModConexion.rs = ModConexion.db.Exec(sConsulta)
RETURN (ModConexion.rs1.Count)
END
A continuación incluimos el código de módulo ModConexion que es llamado desde la rutina anterior
PUBLIC db AS NEW Connection
PUBLIC rs AS Result
PUBLIC FUNCTION conexion() AS Boolean
db.close() 'cierra cualquier conexión que pudiera haber abierta
db.type = "mysql"
db.Name = ModVariables.BD 'nombre de la base de datos
db.host = ModVariables.IP 'ip en la que se encuentra el servidor
db.login = ModVariables.sUsuario 'identificador del usuario
db.password = ModVariables.sPass 'contraseña de acceso
db.open()
RETURN TRUE
CATCH 'si se produce un error
ModVariables.sUsuario = ""
ModVariables.sPass = ""
Message.Warning("La conexión con la base de datos no ha tenido éxito ")
QUIT 'Si erramos en el usuario y clave salimos de la aplicación.
RETURN FALSE
END
PUBLIC SUB consulta(qry AS String)
rs = db.Exec(qry)
END
PUBLIC rs AS Result
PUBLIC FUNCTION conexion() AS Boolean
db.close() 'cierra cualquier conexión que pudiera haber abierta
db.type = "mysql"
db.Name = ModVariables.BD 'nombre de la base de datos
db.host = ModVariables.IP 'ip en la que se encuentra el servidor
db.login = ModVariables.sUsuario 'identificador del usuario
db.password = ModVariables.sPass 'contraseña de acceso
db.open()
RETURN TRUE
CATCH 'si se produce un error
ModVariables.sUsuario = ""
ModVariables.sPass = ""
Message.Warning("La conexión con la base de datos no ha tenido éxito ")
QUIT 'Si erramos en el usuario y clave salimos de la aplicación.
RETURN FALSE
END
PUBLIC SUB consulta(qry AS String)
rs = db.Exec(qry)
END
La rutina a la que deseo controlar el acceso deberá iniciarse con el siguiente código
El código anterior no se ejecutará si el usuario no pertenece a ningún rol que tenga autorización para ello
Este último código evita que un formulario no sea abierto por un usuario cuyos roles no lo permitan.
Espero haberme explicado bien y que este código le sirva a alguien.
Saludos.