pub mod create;
pub mod document;
use crate::error::JacsError;
use crate::storage::MultiStorage;
use std::path::Path;
pub fn read_password_file_checked(path: &Path) -> Result<String, String> {
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let metadata = std::fs::metadata(path)
.map_err(|e| format!("Failed to read password file '{}': {}", path.display(), e))?;
let mode = metadata.permissions().mode() & 0o777;
if mode & 0o077 != 0 {
return Err(format!(
"Password file '{}' has insecure permissions (mode {:04o}). \
File must not be group-readable or world-readable. \
Fix with: chmod 600 '{}'",
path.display(),
mode,
path.display(),
));
}
}
let raw = std::fs::read_to_string(path)
.map_err(|e| format!("Failed to read password file '{}': {}", path.display(), e))?;
let password = raw.trim_end_matches(|c| c == '\n' || c == '\r');
if password.is_empty() {
return Err(format!("Password file '{}' is empty.", path.display()));
}
Ok(password.to_string())
}
pub fn default_set_file_list(
filename: Option<&String>,
directory: Option<&String>,
attachments: Option<&str>,
) -> Result<Vec<String>, JacsError> {
let storage: MultiStorage = get_storage_default_for_cli()?;
set_file_list(&storage, filename, directory, attachments)
}
fn set_file_list(
storage: &MultiStorage,
filename: Option<&String>,
directory: Option<&String>,
attachments: Option<&str>,
) -> Result<Vec<String>, JacsError> {
if let Some(file) = filename {
Ok(vec![file.clone()])
} else if let Some(dir) = directory {
let prefix = if dir.ends_with('/') {
dir.clone()
} else {
format!("{}/", dir)
};
let files = storage.list(&prefix, None)?;
Ok(files.into_iter().filter(|f| f.ends_with(".json")).collect())
} else if attachments.is_some() {
Ok(Vec::new())
} else {
Err("You must specify either a filename, a directory, or attachments.".into())
}
}
pub fn get_storage_default_for_cli() -> Result<MultiStorage, JacsError> {
let storage: Option<MultiStorage> =
Some(MultiStorage::default_new().expect("Failed to initialize storage"));
if let Some(storage) = storage {
Ok(storage)
} else {
Err("Storage not initialized".into())
}
}