CreaRack-SL

Import Visio v2: motor asíncrono .vsdx/.vsd → SVG + sanitización

Resumen

Primera entrega de un plan de 3 PRs para importar stencils de Visio modernos (.vsdx, .vsd) en CreaRack. Este PR 1 entrega:

  1. Motor de conversión asíncrono (libvisio-ng 0.6.1 en worker Huey) — .vsdx/.vsd → SVG por página
  2. Sanitizador SVG central (allowlist con defusedxml) — bloquea XSS en geometría embebida
  3. Tres fixes de seguridad (s220): permisos en confirm, cierre de path-traversal, límite de subida

La UI y QA con ficheros reales de fabricante (Cisco/APC/Schneider) llegan en PRs 2 y 3.

Cambios

Motor asíncrono

  • Endpoint POST /api/racks/visio/analyze ahora acepta .vsdx/.vsd (además de .vssx, .vdx, .vss, .svg)
  • La conversión corre en el worker Huey (@db_task), no en el request
  • Nuevo endpoint GET /api/racks/visio/session/{id} para polling del estado (processing → done/error)
  • El estado vive en un JSON transitorio (temp/{session_id}/visio_session.json), sin modelo nuevo

Sanitizador SVG

  • Nueva utilidad racks/utils/svg_sanitizer.py: allowlist estricta (defusedxml, 0 dependencias nuevas)
    • Elementos bloqueados: <script>, <foreignObject>, atributos on*, href externo, <style>
    • Permitidos: geometría (<path>, <rect>, <circle>, etc.), defs, <use #internal>, <image data:image/>
    • Aplicado en 3 puntos: SVG subido directo, SVGs generados por Visio, gate final en confirm (defensa en profundidad)

Fixes de seguridad

  • Permisos confirm (s220): /api/racks/visio/confirm ahora exige require_perm(..., "racks", "admin") (estaba abierto a cualquier usuario autenticado)
  • Path-traversal (s220): image_path con ../ no puede escalar fuera de MEDIA_ROOT (guard con realpath + prefijo)
  • Límite de subida: máx 50 MB

Dependencia

  • libvisio-ng 0.6.1 — Python puro (wheel universal), GPL-3.0 aceptada por Edu para uso SaaS no distribuido, registrada en core/licenses_data

Testing

  • Nuevo suite tests/api/test_visio_import_v2.py: 10 casos (sanitizador ×4, async conversion, session polling, path-traversal, permisos)
  • Migración de test existente: test_racks_visio_confirm.py actualizado para fixture admin_user (confirm ahora exige admin)
  • CI instala la dependencia real

Visibilidad para usuario

  • Ninguna visible aún: el endpoint analiza en background pero la UI para elegir shapes, renombrarlos y asignar categoría no existe todavía (PR 2)
  • Fin honesto: la calidad de conversión con ficheros reales de Cisco/APC/Schneider será testada en PR 3

Véase también

  • [[entity—racks—service—svg-sanitizer]]
  • [[entity—racks—service—convert-visio-async]]
  • [[entity—racks—endpoint—visio-session-status]]
  • [[decision—20260713—visio-confirm-hardening]]
  • [[entity—racks—model—stencil]]