Permisos
Sistema de Permisos - Agregar un feature a la DB
El sistema funciona con intersección de permisos. Un usuario puede hacer algo solo si TANTO su tipo de usuario COMO su rol específico lo permiten.
Tablas principales
funcionalidades_plataforma- Define los features de la plataforma (actividades, ensayos, stocks, etc.)funcionalidades- Define todos los permisos de los features (leer, escribir, borrar, etc.)tipo_usuario- Define límites máximos de permisos por tipo de usuario (Free, Pro, etc.)roles- Define conjuntos de permisos asignables (Admin, Editor, Solo lectura, etc.)permisos- Asigna roles a usuarios en lotes específicospermisos_estancias- Asigna roles a usuarios en campos específicosfuncionalidades_plataforma_espacios- Define qué funcionalidades están habilitadas por espacio
Agregar nuevo feature
Paso 1: Crear el feature
Agregar el feature en la tabla funcionalidades_plataforma. El parámetro "base" indica si se agrega automáticamente a nuevos espacios.
INSERT INTO funcionalidades_plataforma (funcionalidad, base)
VALUES ('trials', true);
-- Supongamos que se creó con ID 10
Paso 2: Habilitarlo en espacios
Agregar el feature a los espacios donde debe estar disponible.
UPDATE funcionalidades_plataforma_espacios
SET funcionalidades = funcionalidades || ARRAY[10]
WHERE workspace_id = 1;
Paso 3: Agregarlo al tipo de usuario
El tipo de usuario debe tener el feature habilitado en funcionalidades_plataforma.
UPDATE tipo_usuario
SET funcionalidades_plataforma = funcionalidades_plataforma || ARRAY[10]
WHERE id = 204; -- Usuario Auravant Pro
Agregar permisos del feature
Definir los permisos específicos (crear, leer, editar, eliminar).
Paso 1: Definir los permisos
Insertar las funcionalidades básicas. Los campos son: id, nombre, tipo de permiso (A=Agregar, L=Leer, M=Editar, B=Borrar), código del permiso, habilitado para aurapps, y entity.
INSERT INTO funcionalidades VALUES
(370, 'Crear ensayos', 'A', 'TA', false, 'Trials'),
(371, 'Leer ensayos', 'L', 'TL', false, 'Trials'),
(372, 'Modificar ensayos', 'M', 'TM', false, 'Trials'),
(373, 'Eliminar ensayos', 'B', 'TB', false, 'Trials');
Paso 2: Agregarlos al tipo de usuario
El tipo de usuario debe tener estos permisos en permisos_default:
UPDATE tipo_usuario
SET permisos_default = permisos_default || ARRAY[370,371,372,373]
WHERE id = 204; -- Usuario Pro
Paso 3: Agregarlos a los roles
Asignar los permisos a cada rol según corresponda:
-- Rol Admin: todos los permisos
UPDATE roles
SET permisos_default = permisos_default || ARRAY[370,371,372,373]
WHERE id = 1;
-- Rol Editor: crear, leer, editar (sin eliminar)
UPDATE roles
SET permisos_default = permisos_default || ARRAY[370,371,372]
WHERE id = 3;
-- Rol Solo lectura: solo leer
UPDATE roles
SET permisos_default = permisos_default || ARRAY[371]
WHERE id = 2;
-- Rol Agregado: crear y leer (sin editar ni eliminar)
UPDATE roles
SET permisos_default = permisos_default || ARRAY[370,371]
WHERE id = 4;
Cómo llegan los permisos al frontend
Los permisos llegan al front a través de dos endpoints principales:
getUserData - Permisos generales
Devuelve los permisos generales del usuario calculados como intersección entre su tipo de usuario y roles. Tambien devuelve los features habilitados haciendo una intersección entre los de su tipo de usuario y los del espacio:
{
"funcionalidades": [1, 2, 3, 45, 370, 371, 372],
"funcionalidades_plataforma": [10, 15, 20],
"uid": 141555,
}
getFields - Permisos específicos por campo y lote
Devuelve los permisos específicos que tiene el usuario sobre cada campo y lote, considerando su rol en cada lugar:
{
"user": {
"farms": {
"226055": {
"name": "Campo 1",
"permissions": [1, 2, 3, 370, 371],
"fields": {
"777169": {
"name": "Lote 1",
"permissions": [1, 2, 3, 370, 371, 372, 373]
}
}
}
}
}
}
Diferencias importantes:
getUserData: permisos generales del usuariogetFields: permisos específicos por campo/lote- Los permisos pueden variar según el rol del usuario en cada ubicación
Validar permisos en el backend
Para validar permisos en el backend se usa la clase Permissions que busca automáticamente los permisos del usuario.
Validar permiso en lote específico:
from commons.permisos import Permissions
# Verificar si el usuario puede crear ensayos en un lote
user_permissions = Permissions.fields(user_id=141555, fields=777169)
if 370 in user_permissions.get(777169, []):
# Usuario puede crear ensayos en este lote
pass
else:
raise ApiErr(2, "Sin permisos para crear ensayos")
Validar permiso en múltiples lotes:
# Verificar permisos en varios lotes
field_ids = [777169, 777170, 777171]
user_permissions = Permissions.fields(user_id=141555, fields=field_ids)
for field_id in field_ids:
if 370 not in user_permissions.get(field_id, []):
raise ApiErr(2, "Sin permisos en lote {}".format(field_id))
Validar permiso usando helper:
from commons.permisos import validar_permisos
# Validar usando código del permiso
if not validar_permisos(user_id=141555, codigo="TA", lote=777169):
raise ApiErr(2, "Sin permisos para crear ensayos")