fix(file-portal): create parent directories on write

std::fs::write fails when the destination parent does not exist.
Add create_dir_all before the write so apps can store files in
nested paths (e.g. config/sub/settings.json) without pre-creating
directories. Add regression test for the nested-path case.
This commit is contained in:
Marco Allegretti 2026-03-11 18:52:54 +01:00
parent a5846c1317
commit a18f5c7604

View file

@ -142,6 +142,9 @@ fn handle_request(req: Request, allowed: &[PathBuf]) -> Response {
Ok(d) => d,
Err(e) => return Response::err(format!("bad base64: {e}")),
};
if let Some(Err(e)) = p.parent().map(std::fs::create_dir_all) {
return Response::err(e);
}
match std::fs::write(&p, &data) {
Ok(()) => Response::Ok,
Err(e) => Response::err(e),
@ -273,4 +276,27 @@ mod tests {
let _ = fs::remove_dir_all(&dir);
}
#[test]
fn handle_request_write_creates_parent_dirs() {
use std::fs;
let dir = std::env::temp_dir().join(format!("wfp_write_{}", std::process::id()));
let _ = fs::remove_dir_all(&dir);
let nested = dir.join("sub").join("deep").join("file.txt");
let data = base64::Engine::encode(
&base64::engine::general_purpose::STANDARD,
b"nested content",
);
let allowed = vec![dir.clone()];
let resp = handle_request(
Request::Write {
path: nested.to_string_lossy().into(),
data_b64: data,
},
&allowed,
);
assert!(matches!(resp, Response::Ok), "expected Ok response");
assert_eq!(fs::read(&nested).unwrap(), b"nested content");
let _ = fs::remove_dir_all(&dir);
}
}