use crate::error::{FnoxError, Result};
use std::env;
use std::fs;
use std::io::Write;
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;
use std::time::{SystemTime, UNIX_EPOCH};
use tempfile::NamedTempFile;
pub fn create_ephemeral_secret_file(key: &str, value: &str) -> Result<NamedTempFile> {
let mut temp_file = NamedTempFile::new().map_err(|e| {
FnoxError::Config(format!(
"Failed to create temporary file for secret '{}': {}",
key, e
))
})?;
#[cfg(unix)]
{
let metadata = temp_file.as_file().metadata().map_err(|e| {
FnoxError::Config(format!(
"Failed to get metadata for temporary file of secret '{}': {}",
key, e
))
})?;
let mut permissions = metadata.permissions();
permissions.set_mode(0o600);
fs::set_permissions(temp_file.path(), permissions).map_err(|e| {
FnoxError::Config(format!(
"Failed to set permissions for temporary file of secret '{}': {}",
key, e
))
})?;
}
temp_file.write_all(value.as_bytes()).map_err(|e| {
FnoxError::Config(format!(
"Failed to write secret '{}' to temporary file: {}",
key, e
))
})?;
temp_file.flush().map_err(|e| {
FnoxError::Config(format!(
"Failed to flush temporary file for secret '{}': {}",
key, e
))
})?;
Ok(temp_file)
}
pub fn create_persistent_secret_file(prefix: &str, key: &str, value: &str) -> Result<String> {
let temp_dir = env::temp_dir();
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_err(|e| {
FnoxError::Config(format!(
"Failed to get system time for secret '{}': {}",
key, e
))
})?
.as_nanos();
let pid = std::process::id();
let filename = format!("{}{}-{}-{}", prefix, key, pid, timestamp);
let file_path = temp_dir.join(filename);
let mut file = fs::File::create(&file_path).map_err(|e| {
FnoxError::Config(format!(
"Failed to create persistent file for secret '{}': {}",
key, e
))
})?;
#[cfg(unix)]
{
let metadata = file.metadata().map_err(|e| {
FnoxError::Config(format!(
"Failed to get metadata for persistent file of secret '{}': {}",
key, e
))
})?;
let mut permissions = metadata.permissions();
permissions.set_mode(0o600);
fs::set_permissions(&file_path, permissions).map_err(|e| {
FnoxError::Config(format!(
"Failed to set permissions for persistent file of secret '{}': {}",
key, e
))
})?;
}
file.write_all(value.as_bytes()).map_err(|e| {
FnoxError::Config(format!(
"Failed to write secret '{}' to persistent file: {}",
key, e
))
})?;
file.flush().map_err(|e| {
FnoxError::Config(format!(
"Failed to flush persistent file for secret '{}': {}",
key, e
))
})?;
Ok(file_path.to_string_lossy().to_string())
}