pub mod doctor;
pub mod export;
pub mod init;
pub mod profile;
pub mod recipient;
pub mod run;
pub mod shims;
use std::collections::HashSet;
use std::path::{Path, PathBuf};
use anyhow::Result;
use sshenv_cli_models::Cli;
use sshenv_vault::{CiphertextVault, DataKey, Vault};
use crate::identity::{
discover_private_key_paths, error_no_identity_unlocked_detailed, load_identities_for_vault,
};
pub struct Context {
pub vault_path: PathBuf,
}
impl Context {
#[must_use]
pub fn from_cli(cli: &Cli) -> Self {
let vault_path = cli
.vault
.clone()
.unwrap_or_else(sshenv_vault::default_vault_path);
Self { vault_path }
}
}
pub fn load_and_unlock(vault_path: &Path) -> Result<(Vault, DataKey)> {
let ciphertext = Vault::load_ciphertext(vault_path)?;
let fps: HashSet<String> = ciphertext
.recipients
.iter()
.map(|r| r.fingerprint.clone())
.collect();
let identities = load_identities_for_vault(&fps)?;
if identities.is_empty() {
return Err(error_no_identity_unlocked_detailed(
&discover_private_key_paths(),
&fps,
));
}
Vault::unlock(ciphertext, &identities)
.map_err(|_| error_no_identity_unlocked_detailed(&discover_private_key_paths(), &fps))
}
pub fn load_ciphertext_and_fps(vault_path: &Path) -> Result<(CiphertextVault, HashSet<String>)> {
let ciphertext = Vault::load_ciphertext(vault_path)?;
let fps: HashSet<String> = ciphertext
.recipients
.iter()
.map(|r| r.fingerprint.clone())
.collect();
Ok((ciphertext, fps))
}
pub fn unlock_ciphertext(
ciphertext: CiphertextVault,
recipient_fingerprints: &HashSet<String>,
) -> Result<(Vault, DataKey)> {
let identities = load_identities_for_vault(recipient_fingerprints)?;
if identities.is_empty() {
return Err(error_no_identity_unlocked_detailed(
&discover_private_key_paths(),
recipient_fingerprints,
));
}
Vault::unlock(ciphertext, &identities).map_err(|_| {
error_no_identity_unlocked_detailed(&discover_private_key_paths(), recipient_fingerprints)
})
}