keyman/src/input.rs

115 lines
3.1 KiB
Rust

use anyhow::Result;
use crate::{ platform::{ Platform, PlatformKey }, config::{ ConfigManager, Host } };
use dialoguer::{ Select, FuzzySelect, Input, theme::ColorfulTheme };
use ssh_key::PrivateKey;
use std::fs;
use std::path::PathBuf;
pub fn get_host(config: &mut ConfigManager) -> Result<Host> {
if config.configs.len() < 1 {
let _ = config.new_host()?;
}
let hosts = config.configs.to_owned();
let hosts: Vec<Host> = hosts.into_iter().collect();
let theme = ColorfulTheme::default();
let mut select = Select::with_theme(&theme);
select.with_prompt("Host")
.items(hosts.as_slice())
.item("New host definition...")
.default(0);
Ok({
let c = select.interact()?;
if c == hosts.len() {
config.new_host()?
} else {
hosts.get(c).unwrap().to_owned()
}
})
}
pub fn get_platform() -> Result<Platform> {
let platforms = Platform::all();
let c = Select::with_theme(&ColorfulTheme::default())
.with_prompt("Platform")
.items(platforms.as_slice())
.default(0)
.interact()?;
Ok(platforms.get(c).unwrap().to_owned())
}
pub fn get_key(config: &ConfigManager, platform: Platform) -> Result<PlatformKey> {
let keys: Vec<PlatformKey> = platform.get_keys(config);
let c = FuzzySelect::with_theme(&ColorfulTheme::default())
.with_prompt("Key")
.items(keys.as_slice())
.item("Other...")
.default(0)
.interact()?;
match c == keys.len() {
true => get_custom_key(),
false => Ok(keys.get(c).unwrap().to_owned()),
}
}
pub fn get_custom_key() -> Result<PlatformKey> {
let theme = ColorfulTheme::default();
let mut input = Input::with_theme(&theme);
input.with_prompt("Path").with_initial_text(dirs::home_dir().unwrap().join(".ssh/").to_string_lossy().to_string());
Ok(loop {
let buffer: String = input.interact_text()?;
if fs::try_exists(buffer.to_owned()).unwrap_or(false) {
break match PrivateKey::read_openssh_file(&PathBuf::from(buffer.to_owned())) {
Ok(p) => PlatformKey {
file: buffer.to_owned(),
display: format!("{}: {}", p.fingerprint(ssh_key::HashAlg::Sha256), buffer)
},
Err(_) => {
println!("File is not SSH private key");
continue;
},
}
} else {
println!("File doesn't exist")
}
})
}
fn edit_temp(temp: &mktemp::Temp) -> Result<()> {
let editor = std::env::var("EDITOR").expect("EDITOR is not set");
std::process::Command::new(editor)
.arg(&temp.to_str().unwrap())
.spawn()?.wait()?;
Ok(())
}
pub fn edit_temp_from_string(data: &String) -> Result<mktemp::Temp> {
let t = mktemp::Temp::new_file()?;
fs::write(&t, data)?;
edit_temp(&t)?;
Ok(t)
}
pub fn edit_temp_from_file(file: &String) -> Result<mktemp::Temp> {
let t = mktemp::Temp::new_file()?;
fs::copy(file, &t)?;
edit_temp(&t)?;
Ok(t)
}