mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-06 08:07:49 +00:00
fix(trust): keep LightEdit sessions restricted (#857)
LightEdit created its project as trusted and refresh_project_trust skips light projects, so opening a loose notebook detected Python environments in the file's folder and could run a repository-shipped .venv/bin/python without a trust prompt. LightEdit now starts restricted and stays restricted when folder trust changes, since one session can hold files from unrelated folders; notebooks still open and save, while interpreter discovery, kernel execution and external formatting are refused. Opening the folder as a trusted project enables execution as before. Fixes #849 Co-authored-by: kkMihai <59262001+kkMihai@users.noreply.github.com>
This commit is contained in:
@@ -513,7 +513,7 @@ impl Host {
|
||||
sink.clone(),
|
||||
);
|
||||
let project = Arc::new(Project {
|
||||
trusted: Arc::new(AtomicBool::new(true)),
|
||||
trusted: Arc::new(AtomicBool::new(false)),
|
||||
sink,
|
||||
languages,
|
||||
settings,
|
||||
|
||||
@@ -78,3 +78,104 @@ async fn light_windows_ignore_project_scoped_settings() {
|
||||
assert!(!applied.project_scope);
|
||||
assert!(!dir.join(".openidea").exists(), "no project settings next to the file");
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn light_windows_stay_restricted_when_folder_trust_changes() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let root = tmp.path().join("loose");
|
||||
let other = tmp.path().join("other");
|
||||
std::fs::create_dir_all(&root).unwrap();
|
||||
std::fs::create_dir_all(&other).unwrap();
|
||||
std::fs::write(root.join("one.py"), "print(1)\n").unwrap();
|
||||
std::fs::write(other.join("two.js"), "const value = 1;\n").unwrap();
|
||||
let host = host(&tmp.path().join("app"));
|
||||
host.global_settings
|
||||
.set(ide_workspace::SettingsScope::Global, "languages.prettier.prefer", serde_json::json!(true))
|
||||
.unwrap();
|
||||
let light = host.open_light("main", &root.join("one.py")).unwrap();
|
||||
assert!(!light.is_trusted());
|
||||
assert!(light.require_trust().is_err());
|
||||
|
||||
host.set_project_trust(&root, true, false).await.unwrap();
|
||||
assert!(!light.is_trusted());
|
||||
let trusted_folder = host.open_light("second", &root.join("one.py")).unwrap();
|
||||
assert!(!trusted_folder.is_trusted());
|
||||
let again = host.open_light("main", &other.join("two.js")).unwrap();
|
||||
assert!(Arc::ptr_eq(&light, &again));
|
||||
assert!(!again.is_trusted());
|
||||
host.set_project_trust(&root, true, true).await.unwrap();
|
||||
assert!(!light.is_trusted());
|
||||
assert!(!trusted_folder.is_trusted());
|
||||
for command in ["sdk_detect", "sdk_locate_tools", "notebook_execute", "notebook_restart", "run_start"] {
|
||||
assert!(host.authorize_command("main", command).is_err(), "{command}");
|
||||
}
|
||||
|
||||
let doc = ops::doc::open(&host, "main", other.join("two.js")).await.unwrap();
|
||||
let error = ops::lsp::lsp_format(
|
||||
&host,
|
||||
"main",
|
||||
doc.id,
|
||||
None,
|
||||
ide_lsp::types::FormatOptions { tab_size: 2, insert_spaces: true, on_save: false },
|
||||
)
|
||||
.await
|
||||
.unwrap_err();
|
||||
assert_eq!(error.kind, ide_core::error::ErrorKind::Unavailable);
|
||||
assert!(error.message.contains("Restricted Mode"));
|
||||
|
||||
host.set_project_trust(&root, false, false).await.unwrap();
|
||||
assert!(!light.is_trusted());
|
||||
assert!(!trusted_folder.is_trusted());
|
||||
host.set_project_trust(&root, true, false).await.unwrap();
|
||||
let project = host.open_project("main", &root).unwrap();
|
||||
assert!(!project.light);
|
||||
assert!(project.is_trusted());
|
||||
assert!(project.require_trust().is_ok());
|
||||
host.shutdown().await;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn light_notebooks_open_without_interpreter_detection_or_execution() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let root = tmp.path().join("loose");
|
||||
let bin = root.join(".venv").join(if cfg!(windows) { "Scripts" } else { "bin" });
|
||||
std::fs::create_dir_all(&bin).unwrap();
|
||||
std::fs::write(root.join(".venv/pyvenv.cfg"), "home = python\n").unwrap();
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
let python = bin.join("python");
|
||||
std::fs::write(&python, "#!/bin/sh\nprintf probed > \"$0.probed\"\nprintf 'Python 3.12.0\\n'\n").unwrap();
|
||||
std::fs::set_permissions(&python, std::fs::Permissions::from_mode(0o755)).unwrap();
|
||||
}
|
||||
let file = root.join("analysis.ipynb");
|
||||
std::fs::write(
|
||||
&file,
|
||||
r#"{"cells":[{"id":"cell","cell_type":"code","source":["print(1)"],"metadata":{},"outputs":[],"execution_count":null}],"metadata":{},"nbformat":4,"nbformat_minor":5}"#,
|
||||
)
|
||||
.unwrap();
|
||||
let host = host(&tmp.path().join("app"));
|
||||
host.open_light("main", &file).unwrap();
|
||||
let notebook = ops::notebook::open(&host, "main", file.to_string_lossy().into()).await.unwrap();
|
||||
assert!(ops::notebook::save(&host, "main", notebook.id.clone()).await.is_ok());
|
||||
let error = ops::sdk::sdk_detect(&host, "main", ide_sdk::SdkKind::Python).await.unwrap_err();
|
||||
assert!(error.message.contains("Restricted Mode"));
|
||||
assert!(ops::sdk::sdk_python_effective(&host, "main").is_err());
|
||||
assert!(ops::sdk::sdk_locate_tools(&host, "main", vec!["prettier".into()], Some(root)).await.is_err());
|
||||
let error = ops::notebook::restart(&host, "main", notebook.id.clone()).await.unwrap_err();
|
||||
assert!(error.message.contains("Restricted Mode"));
|
||||
let error = ops::notebook::execute(
|
||||
&host,
|
||||
"main",
|
||||
notebook.id,
|
||||
vec![notebook.cells[0].id.clone()],
|
||||
None,
|
||||
ide_core::RequestId(849),
|
||||
ops::Channel::new(|_| {}),
|
||||
)
|
||||
.await
|
||||
.unwrap_err();
|
||||
assert!(error.message.contains("Restricted Mode"));
|
||||
assert!(!bin.join("python.probed").exists());
|
||||
host.shutdown().await;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user