Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 94 additions & 5 deletions src/cortex-tui/src/runner/app_runner/trusted_workspaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,18 @@ use std::path::PathBuf;
// Trusted Workspaces
// ============================================================================

fn trusted_workspaces_dir() -> Option<PathBuf> {
cortex_common::get_cortex_home()
}

fn trusted_workspaces_file() -> Option<PathBuf> {
trusted_workspaces_dir().map(|dir| dir.join("trusted_workspaces.json"))
}

/// Check if a workspace is already trusted.
pub fn is_workspace_trusted(workspace: &std::path::Path) -> bool {
let trusted_file = match dirs::home_dir() {
Some(home) => home.join(".cortex").join("trusted_workspaces.json"),
let trusted_file = match trusted_workspaces_file() {
Some(path) => path,
None => return false,
};

Expand Down Expand Up @@ -41,9 +49,7 @@ pub fn is_workspace_trusted(workspace: &std::path::Path) -> bool {

/// Mark a workspace as trusted.
pub fn mark_workspace_trusted(workspace: &std::path::Path) -> Result<()> {
let cortex_dir = dirs::home_dir()
.map(|h| h.join(".cortex"))
.unwrap_or_else(|| PathBuf::from(".cortex"));
let cortex_dir = trusted_workspaces_dir().unwrap_or_else(|| PathBuf::from(".cortex"));

std::fs::create_dir_all(&cortex_dir)?;

Expand Down Expand Up @@ -74,3 +80,86 @@ pub fn mark_workspace_trusted(workspace: &std::path::Path) -> Result<()> {
std::fs::write(&trusted_file, serde_json::to_string_pretty(&data)?)?;
Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
use std::ffi::{OsStr, OsString};
use std::sync::Mutex;

static ENV_LOCK: Mutex<()> = Mutex::new(());

struct EnvVarGuard {
key: &'static str,
previous: Option<OsString>,
}

impl EnvVarGuard {
fn set(key: &'static str, value: &OsStr) -> Self {
let previous = std::env::var_os(key);
unsafe {
std::env::set_var(key, value);
}
Self { key, previous }
}
}

impl Drop for EnvVarGuard {
fn drop(&mut self) {
unsafe {
if let Some(previous) = &self.previous {
std::env::set_var(self.key, previous);
} else {
std::env::remove_var(self.key);
}
}
}
}

#[test]
fn trusted_workspaces_file_uses_cortex_home_override() {
let _lock = ENV_LOCK.lock().unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let _guard = EnvVarGuard::set("CORTEX_HOME", temp_dir.path().as_os_str());

assert_eq!(
trusted_workspaces_file().unwrap(),
temp_dir.path().join("trusted_workspaces.json")
);
}

#[test]
fn is_workspace_trusted_reads_trust_store_from_cortex_home() {
let _lock = ENV_LOCK.lock().unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let _guard = EnvVarGuard::set("CORTEX_HOME", temp_dir.path().as_os_str());
let workspace = temp_dir.path().join("project");
let trusted_file = temp_dir.path().join("trusted_workspaces.json");

std::fs::write(
&trusted_file,
serde_json::json!({
"version": 1,
"trusted": [workspace.to_string_lossy()]
})
.to_string(),
)
.unwrap();

assert!(is_workspace_trusted(&workspace));
}

#[test]
fn mark_workspace_trusted_writes_trust_store_to_cortex_home() {
let _lock = ENV_LOCK.lock().unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let _guard = EnvVarGuard::set("CORTEX_HOME", temp_dir.path().as_os_str());
let workspace = temp_dir.path().join("project");
let trusted_file = temp_dir.path().join("trusted_workspaces.json");

mark_workspace_trusted(&workspace).unwrap();

assert!(trusted_file.exists());
assert!(is_workspace_trusted(&workspace));
}
}