use anyhow::Result;
use std::path::{Path, PathBuf};
pub fn trusted_repos_file() -> Option<PathBuf> {
dirs::home_dir().map(|h| h.join(".selfware").join("trusted_repos"))
}
fn canonical(path: &Path) -> PathBuf {
std::fs::canonicalize(path).unwrap_or_else(|_| path.to_path_buf())
}
pub fn is_config_trusted(config_path: &Path) -> bool {
match trusted_repos_file() {
Some(f) => is_config_trusted_in(&f, config_path),
None => false,
}
}
fn is_config_trusted_in(trust_file: &Path, config_path: &Path) -> bool {
let Ok(content) = std::fs::read_to_string(trust_file) else {
return false;
};
let target = canonical(config_path);
content.lines().any(|line| {
let line = line.trim();
!line.is_empty() && canonical(Path::new(line)) == target
})
}
pub fn add_trusted_config(config_path: &Path) -> Result<()> {
let file =
trusted_repos_file().ok_or_else(|| anyhow::anyhow!("cannot resolve home directory"))?;
add_trusted_config_to(&file, config_path)
}
fn add_trusted_config_to(trust_file: &Path, config_path: &Path) -> Result<()> {
if is_config_trusted_in(trust_file, config_path) {
return Ok(());
}
if let Some(parent) = trust_file.parent() {
std::fs::create_dir_all(parent)?;
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let _ = std::fs::set_permissions(parent, std::fs::Permissions::from_mode(0o700));
}
}
let mut existing = std::fs::read_to_string(trust_file).unwrap_or_default();
if !existing.is_empty() && !existing.ends_with('\n') {
existing.push('\n');
}
existing.push_str(&canonical(config_path).to_string_lossy());
existing.push('\n');
std::fs::write(trust_file, existing)?;
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let _ = std::fs::set_permissions(trust_file, std::fs::Permissions::from_mode(0o600));
}
Ok(())
}
#[cfg(test)]
#[path = "../../tests/unit/config/trust/trust_test.rs"]
mod tests;