use dialoguer::Input;
use std::io::{self, IsTerminal};
use crate::cli::output;
use crate::core::config::Config;
use crate::core::domain::Identity;
use crate::core::vault::validate_member_name;
use crate::error::Result;
pub fn execute(name: Option<String>, vault: Option<String>) -> Result<()> {
let vault_name = crate::cli::resolve::resolve_vault(vault.as_deref())?;
if !Identity::has_global()? {
output::error("no identity found");
output::hint("run: dugout setup");
return Err(
crate::error::StoreError::NoPrivateKey("~/.dugout/identity".to_string()).into(),
);
}
if Config::exists_for(vault_name.as_deref()) {
let config = Config::load_from(vault_name.as_deref())?;
let pubkey = Identity::load_global_pubkey()?;
if config.recipients.values().any(|k| k == &pubkey) {
output::warn("you already have access");
return Ok(());
}
}
let name = if let Some(n) = name {
n
} else if io::stdin().is_terminal() {
Input::new()
.with_prompt("What's your name?")
.interact_text()?
} else {
output::error("name required in non-interactive mode");
return Err(crate::error::ValidationError::EmptyKey.into());
};
validate_member_name(&name)?;
let pubkey = Identity::load_global_pubkey()?;
let request_dir = crate::core::constants::request_dir(vault_name.as_deref());
std::fs::create_dir_all(&request_dir)?;
let request_path = request_dir.join(format!("{}.pub", name));
if request_path.exists() {
let existing = std::fs::read_to_string(&request_path)?;
let existing_key = existing.trim();
if existing_key == pubkey {
output::warn("request already exists with your key");
return Ok(());
} else {
output::error(&format!(
"request '{}' already exists with a different key",
name
));
output::hint("use a different name or contact an admin");
return Err(crate::error::Error::Other(format!(
"request file '{}' already exists with different key",
name
)));
}
}
std::fs::write(&request_path, format!("{}\n", pubkey))?;
output::success("created access request");
let display_path = request_path.display().to_string().replace('\\', "/");
output::hint(&format!("share {} with an admin", display_path));
Ok(())
}