194 lines
5.5 KiB
Markdown
194 lines
5.5 KiB
Markdown
# US-MMD001-006: Aplicar RLS por Taller
|
|
|
|
## Metadata
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **ID** | US-MMD001-006 |
|
|
| **Epica** | EPIC-MMD-001 - Fundamentos |
|
|
| **Modulo** | fundamentos |
|
|
| **Prioridad** | P0 |
|
|
| **Story Points** | 5 |
|
|
| **Sprint** | Sprint 1 |
|
|
| **Estado** | Backlog |
|
|
| **Asignado a** | Por asignar |
|
|
|
|
---
|
|
|
|
## Historia de Usuario
|
|
|
|
**Como** sistema,
|
|
**quiero** aplicar Row-Level Security (RLS) en todas las tablas por workshop_id,
|
|
**para** garantizar que cada taller solo vea y modifique sus propios datos.
|
|
|
|
## Descripcion Detallada
|
|
|
|
RLS (Row-Level Security) es una caracteristica de PostgreSQL que permite filtrar filas automaticamente basandose en el usuario actual. Cada query se filtra automaticamente por el workshop_id del usuario logueado, garantizando aislamiento total de datos entre talleres.
|
|
|
|
---
|
|
|
|
## Criterios de Aceptacion
|
|
|
|
**Escenario 1: Aislamiento de datos entre talleres**
|
|
```gherkin
|
|
DADO que existen 2 talleres: "Diesel Express" y "Mecanica Industrial"
|
|
CUANDO un usuario de "Diesel Express" consulta ordenes de servicio
|
|
ENTONCES solo ve las ordenes de "Diesel Express"
|
|
Y no ve ninguna orden de "Mecanica Industrial"
|
|
```
|
|
|
|
**Escenario 2: Contexto de sesion automatico**
|
|
```gherkin
|
|
DADO que un usuario inicia sesion en "Diesel Express"
|
|
CUANDO el sistema establece la sesion
|
|
ENTONCES se configura automaticamente app.current_workshop_id = 'uuid-diesel-express'
|
|
Y todas las queries filtran por ese workshop_id
|
|
```
|
|
|
|
**Escenario 3: Insercion con workshop_id automatico**
|
|
```gherkin
|
|
DADO que un usuario de "Diesel Express" crea una nueva orden
|
|
CUANDO inserta el registro
|
|
ENTONCES el sistema asigna automaticamente workshop_id del contexto
|
|
Y no se requiere especificar workshop_id manualmente
|
|
```
|
|
|
|
**Escenario 4: Proteccion contra acceso cruzado**
|
|
```gherkin
|
|
DADO que un usuario de "Diesel Express" intenta acceder a orden de "Mecanica Industrial"
|
|
CUANDO hace GET /api/orders/{id-de-mecanica-industrial}
|
|
ENTONCES el sistema retorna 404 Not Found
|
|
Y no revela que el registro existe en otro taller
|
|
```
|
|
|
|
**Escenario 5: SuperAdmin ve todos los talleres**
|
|
```gherkin
|
|
DADO que un SuperAdmin accede al sistema
|
|
CUANDO consulta datos
|
|
ENTONCES puede ver registros de todos los talleres
|
|
Y puede filtrar por taller especifico
|
|
```
|
|
|
|
---
|
|
|
|
## Implementacion Tecnica
|
|
|
|
### Configuracion de Contexto
|
|
|
|
```sql
|
|
-- Funcion para establecer contexto
|
|
CREATE OR REPLACE FUNCTION set_workshop_context(p_workshop_id UUID)
|
|
RETURNS VOID AS $$
|
|
BEGIN
|
|
PERFORM set_config('app.current_workshop_id', p_workshop_id::TEXT, FALSE);
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- Funcion para obtener contexto
|
|
CREATE OR REPLACE FUNCTION get_current_workshop_id()
|
|
RETURNS UUID AS $$
|
|
BEGIN
|
|
RETURN NULLIF(current_setting('app.current_workshop_id', TRUE), '')::UUID;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
```
|
|
|
|
### Politicas RLS por Tabla
|
|
|
|
```sql
|
|
-- Ejemplo: Tabla service_orders
|
|
ALTER TABLE service_management.service_orders ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- Politica de lectura
|
|
CREATE POLICY service_orders_select ON service_management.service_orders
|
|
FOR SELECT
|
|
USING (workshop_id = get_current_workshop_id() OR is_superadmin());
|
|
|
|
-- Politica de insercion
|
|
CREATE POLICY service_orders_insert ON service_management.service_orders
|
|
FOR INSERT
|
|
WITH CHECK (workshop_id = get_current_workshop_id());
|
|
|
|
-- Politica de actualizacion
|
|
CREATE POLICY service_orders_update ON service_management.service_orders
|
|
FOR UPDATE
|
|
USING (workshop_id = get_current_workshop_id());
|
|
|
|
-- Politica de eliminacion
|
|
CREATE POLICY service_orders_delete ON service_management.service_orders
|
|
FOR DELETE
|
|
USING (workshop_id = get_current_workshop_id());
|
|
```
|
|
|
|
---
|
|
|
|
## Tablas a Proteger
|
|
|
|
| Schema | Tabla | RLS |
|
|
|--------|-------|-----|
|
|
| workshop_core | workshops | Solo SuperAdmin |
|
|
| workshop_core | work_bays | Por workshop_id |
|
|
| workshop_core | service_catalog | Por workshop_id |
|
|
| service_management | service_orders | Por workshop_id |
|
|
| service_management | diagnostics | Por workshop_id |
|
|
| parts_management | parts | Por workshop_id |
|
|
| parts_management | movements | Por workshop_id |
|
|
| vehicle_management | vehicles | Por workshop_id |
|
|
|
|
---
|
|
|
|
## Tareas Tecnicas
|
|
|
|
**Database:**
|
|
- [ ] DB-015: Crear funcion set_workshop_context()
|
|
- [ ] DB-016: Crear funcion get_current_workshop_id()
|
|
- [ ] DB-017: Crear funcion is_superadmin()
|
|
- [ ] DB-018: Aplicar RLS a todas las tablas de negocio
|
|
- [ ] DB-019: Crear trigger para auto-asignar workshop_id en INSERT
|
|
|
|
**Backend:**
|
|
- [ ] BE-020: Middleware para establecer contexto al inicio de request
|
|
- [ ] BE-021: Ejecutar set_workshop_context() en cada conexion
|
|
- [ ] BE-022: Tests de penetracion entre tenants
|
|
|
|
**Frontend:**
|
|
- [ ] No aplica (transparente para frontend)
|
|
|
|
---
|
|
|
|
## Dependencias
|
|
|
|
**Depende de:**
|
|
- [ ] US-MMD001-001: Configurar taller
|
|
- [ ] MGN-004 Tenants (Core)
|
|
|
|
**Bloquea:**
|
|
- [ ] Todas las demas US (requieren RLS activo)
|
|
|
|
---
|
|
|
|
## Tests de Seguridad Requeridos
|
|
|
|
| Test | Descripcion | Resultado Esperado |
|
|
|------|-------------|-------------------|
|
|
| Cross-tenant SELECT | Intentar leer datos de otro taller | 0 registros |
|
|
| Cross-tenant UPDATE | Intentar modificar datos de otro taller | 0 registros afectados |
|
|
| Cross-tenant DELETE | Intentar eliminar datos de otro taller | 0 registros afectados |
|
|
| Direct ID access | Acceder por ID a registro de otro taller | 404 Not Found |
|
|
| SuperAdmin access | SuperAdmin accede a cualquier taller | Exito |
|
|
|
|
---
|
|
|
|
## Definition of Done (DoD)
|
|
|
|
- [ ] RLS habilitado en todas las tablas
|
|
- [ ] Contexto se establece automaticamente
|
|
- [ ] Tests de penetracion pasando
|
|
- [ ] SuperAdmin puede ver todo
|
|
- [ ] Documentacion de seguridad
|
|
|
|
---
|
|
|
|
**Creada por:** Requirements-Analyst
|
|
**Fecha:** 2025-12-06
|