openxava / documentación / Restringir datos por usuario/rol

×Novedad: OpenXava con IA - Refinar la UI (Parte 2) - 1 de diciembre · Leer más

Tabla de contenidos

Restringir datos por usuario/rol
Filtrar datos por usuario en la lista
Restringir datos en modo detalle
Valor por defecto para usuario
Restringir datos por rol (nuevo en v7.6)

En muchas aplicaciones empresariales es necesario que cada usuario vea solo los datos que le corresponden, como sus pedidos, facturas o tareas. Este control es esencial para agilizar el trabajo y también para proteger la información. Sería lo que se conoce como seguridad a nivel de fila en el mundo de las bases de datos.

OpenXava resuelve este problema de forma sencilla mediante filtros y condiciones base en las listas, lo que permite restringir la visibilidad de los datos según el usuario conectado o su rol.

Filtrar datos por usuario en la lista

Basta con definir una baseCondition en el @Tab por la propiedad que contenga el nombre del usuario, usando UserFilter como filtro. Por ejemplo, si tenemos una entidad Tarea con una propiedad usuario que almacena el usuario que tiene asignada la tarea, podríamos definir el @Tab de esta forma:

import org.openxava.filters.UserFilter;

@Entity
@Tab(filter=UserFilter.class, baseCondition="${usuario} = ?")
public class Tarea {
    
    @Column(length=50, name="USERNAME")
    private String usuario;
    
    // Resto de propiedades y métodos
}

En este ejemplo, la anotación @Tab(filter=UserFilter.class, baseCondition="${usuario} = ?") establece una condición base que filtra automáticamente los datos por el usuario identificado actualmente en la aplicación. El UserFilter es un filtro predefinido en OpenXava que proporciona el nombre del usuario conectado, mientras que la expresión ${usuario} hace referencia a la propiedad usuario de la entidad. El signo de interrogación ? será reemplazado por el valor que devuelva el filtro, es decir, el nombre del usuario que ha iniciado sesión.

Con esta configuración, cada usuario solo verá sus propias tareas en la lista.

Restringir datos en modo detalle

Desde la versión 7.4.2 de OpenXava, el framework automáticamente impide que se acceda en modo detalle a datos que no están incluidos en la lista. Esto significa que si has configurado una UserFilter en tu @Tab como se explicó en la sección anterior, no necesitas hacer nada adicional para restringir el acceso a los datos en modo detalle.

Este comportamiento funciona tanto con los enlaces permanentes (permalinks) como con la acción de búsqueda estándar, garantizando que los usuarios solo puedan ver en detalle los registros que les corresponden según los filtros aplicados.

Si estás utilizando una versión anterior a la 7.4.2, deberías implementar tu propia acción de búsqueda (usando XAVA_SEARCH_ACTION) con la lógica necesaria para impedir la consulta de datos que no pertenecen al usuario actual. Para más información sobre cómo sobreescribir la búsqueda por defecto, consulta la sección Sobreescribir búsqueda por defecto en la documentación de controladores.

Valor por defecto para usuario

Para asignar automáticamente el usuario actual a los nuevos registros, existen dos opciones principales dependiendo de si quieres que el campo de usuario sea visible o no en la interfaz de usuario.

Opción 1: Usuario visible pero no editable

Si deseas que el campo de usuario sea visible en la interfaz pero no editable:

@DefaultValueCalculator(CurrentUserCalculator.class)
@ReadOnly
@Column(length=50, name="USERNAME")
private String usuario;

En este caso, @DefaultValueCalculator(CurrentUserCalculator.class) asigna automáticamente el nombre del usuario actual cuando se crea un nuevo registro, mientras que @ReadOnly impide que el usuario pueda modificar este valor.

Recuerda importar la clase CurrentUserCalculator:

import org.openxava.calculators.CurrentUserCalculator;

Opción 2: Usuario oculto

Si prefieres que el campo de usuario no sea visible en la interfaz:

@Hidden
@Column(length=50, name="USERNAME")
private String usuario;

@PrePersist
public void asignarUsuarioActual() {
    this.usuario = Users.getCurrent();
}

En esta opción, la anotación @Hidden oculta el campo en la interfaz de usuario, y el método anotado con @PrePersist se ejecuta automáticamente antes de persistir la entidad, asignando el usuario actual mediante Users.getCurrent().

Esta segunda opción es útil cuando el usuario no necesita ver quién es el propietario del registro, ya que siempre será él mismo, y simplifica la interfaz al ocultar campos que no requieren interacción.

Recuerda importar la clase Users si utilizas la segunda opción:

import org.openxava.util.Users;

Restringir datos por rol (nuevo en v7.6)

Esta funcionalidad solo está disponible en XavaPro

En XavaPro, un usuario puede tener asociado un grupo de roles. El framework proporciona un filtro llamado RolesFilter que permite restringir el acceso a los datos según los roles del usuario actual. Este filtro funciona comparando los roles del usuario con una propiedad de la entidad que contiene un nombre de rol.

Para implementar esta restricción, sigue estos pasos:

1. Define una propiedad para el rol en tu entidad

@Column(length=30, columnDefinition = "VARCHAR(30) DEFAULT 'user'")
private String rol;

Esta propiedad almacenará el nombre del rol que tiene permiso para acceder al registro. Puedes establecer un valor por defecto si lo deseas, como en el ejemplo anterior donde el valor predeterminado es 'user'.

2. Configura el filtro en la anotación @Tab

@Tab(baseCondition = "${rol} IN (?)",
    filter=com.openxava.naviox.filters.RolesFilter.class,
    properties="anyo, numero, fecha, cliente.numero, cliente.nombre, ...")

La condición base ${rol} IN (?) indica que se filtrarán los registros donde el valor de la propiedad rol esté incluido en la lista de roles del usuario actual. El filtro RolesFilter proporciona automáticamente esta lista de roles.

3. Cómo funciona

Cuando un usuario accede a la lista, el filtro RolesFilter obtiene todos los roles asignados al usuario actual y los utiliza para filtrar los datos. Por ejemplo:

Esto permite implementar un sistema de acceso a datos basado en roles, donde diferentes tipos de usuarios pueden ver diferentes conjuntos de datos según sus roles asignados.

Recuerda importar las clases necesarias:

import com.openxava.naviox.filters.RolesFilter; // Nota: paquete com.openxava.naviox, no org.openxava