use crate::db::Database;
use crate::identity::{IdKeyData, Identity, unescape};
use std::path::Path;
use std::process::exit;
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(())
}