Saltar al contenido

El ámbito dinámico, en serio

Cuando el usuario elige un fichero, el ámbito tiene que crecer. Cómo se hace, por qué la petición debe venir del sistema y nunca del frontend, y cómo se persiste sin abrir un agujero.

El caso

Rust
use tauri_plugin_fs::FsExt;#[tauri::command]async fn abrir_proyecto(app: tauri::AppHandle) -> Result<Proyecto, ErrorPayload> {    // 1 · el DIÁLOGO DEL SISTEMA devuelve la ruta. No el frontend.    let ruta = app.dialog().file().blocking_pick_file()        .ok_or_else(|| ErrorPayload::cancelado())?;    // 2 · ahora esa ruta concreta entra en el ámbito    app.fs_scope().allow_file(&ruta)?;    // 3 · y ya se puede leer    Ok(Proyecto::leer(&ruta).await?)}

Fíjate en el orden y en quién hace qué: el comando no recibe la ruta, la obtiene. El frontend pide «abre un proyecto» y no dice cuál.

La regla de procedencia

Es la que sostiene todo el mecanismo:

Una ruta solo entra en el ámbito si viene de un gesto del usuario a través del sistema operativo.

El diálogo de fichero, el arrastrar y soltar, un fichero abierto con doble clic que llega como argumento —nivel 25.5—. Los tres tienen en común que el usuario ha señalado esa ruta en una interfaz del sistema, no del frontend.

Y eso importa por una razón que va más allá del modelo de Tauri: en macOS, ese gesto es además lo que concede el permiso del sistema operativo para leer ese fichero. Una ruta obtenida de otra forma puede estar en tu ámbito y aun así fallar por permisos del sistema.

Las tres formas de romperla

La primera es la grave y la más fácil de escribir sin darse cuenta, porque parece una utilidad razonable. Ningún comando que amplíe el ámbito debe aceptar la ruta del frontend. Si tu API tiene algo así, es el equivalente a un comando que lee rutas arbitrarias.

Persistir el ámbito

El ámbito ampliado vive en memoria y se pierde al cerrar —nivel 30.1—. Una aplicación con «documentos recientes» necesita que la próxima vez esos ficheros se puedan abrir sin volver a pedirlos, y ahí aparece la tentación de guardar la lista y reponerla al arrancar.

Se puede, y hay que hacerlo con dos condiciones:

La condición 2 es la que se olvida y la que convierte una comodidad en un agujero: un fichero de rutas permitidas al que el frontend pueda escribir es un ámbito que el frontend controla.

En macOS hay además un mecanismo del sistema para esto —marcadores que conservan el permiso concedido entre sesiones— y usarlo es lo correcto ahí, porque el permiso del sistema tampoco sobrevive solo. El nivel 40 lo trata.

Lo que gana el usuario

Merece decirlo porque el mecanismo suena a fricción: el ámbito dinámico bien hecho es invisible. El usuario abre un fichero con el diálogo de siempre y la aplicación funciona. Lo que no ve es que la aplicación no puede tocar nada más, y que si mañana una dependencia comprometida intenta leer sus claves, se encuentra un ámbito que solo contiene los tres ficheros que él eligió.

Eso es lo que se compra con las tres condiciones de arriba.