use std::convert::identity;
use std::path::Path;
use std::process::exit;
use crate::db::Database;
use crate::identity::{unescape, IdKeyData, Identity};
pub fn import_key(db_path: &Path, key: String, insert_anyway: bool) -> anyhow::Result<()> {
// decode the key
let components = key.split("/").collect::<Vec<_>>();
if components.len() != 4 || components[0] != "sage" {
eprintln!("not a sage key (looks like sage/key/name/email");
eprintln!("to import a raw age key without an identity, add it to the database manually");
exit(1);
}
let [_sentinel, key, name, email] = components.as_slice() else { unreachable!() };
let name = unescape(name.to_string())?;
let email = unescape(email.to_string())?;
let keys = match &key[0..3] {
"age" => {
IdKeyData::Peer(key.to_string())
},
"AGE" => {
IdKeyData::Local(key.to_string())
},
_ => {
eprintln!("unsupported age key type; is this a sage key?");
exit(1);
}
};
let identity = Identity {
name,
email,
keys
};
let mut db = Database::load_or_create(db_path)?;
for key in &db.keys {
if key.keys.keyid()? == identity.keys.keyid()? {
println!("key {} already exists in database, skipping", key.keys.keyid()?);
return Ok(());
}
if key.name == identity.name && key.email == identity.email && !insert_anyway {
eprintln!("database already has a key for {:?}", identity);
eprintln!("to import anyway, run again with --import-anyway");
exit(1);
}
}
db.keys.push(identity.clone());
db.write(db_path)?;
println!("imported {:?} (keyid {}) successfully", identity, identity.keys.keyid()?);
Ok(())
}