From 14c7a96c282e20ff0d5343a7a378554f34983d21 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Thu, 23 Nov 2023 15:04:47 +0100 Subject: extract setup logic --- src/future_rest_admin_api.txt | 174 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 src/future_rest_admin_api.txt (limited to 'src/future_rest_admin_api.txt') diff --git a/src/future_rest_admin_api.txt b/src/future_rest_admin_api.txt new file mode 100644 index 0000000..19ece27 --- /dev/null +++ b/src/future_rest_admin_api.txt @@ -0,0 +1,174 @@ + Command::FirstLogin { + creds, + user_secrets, + } => { + let creds = make_storage_creds(creds); + let user_secrets = make_user_secrets(user_secrets); + + println!("Please enter your password for key decryption."); + println!("If you are using LDAP login, this must be your LDAP password."); + println!("If you are using the static login provider, enter any password, and this will also become your password for local IMAP access."); + let password = rpassword::prompt_password("Enter password: ")?; + let password_confirm = rpassword::prompt_password("Confirm password: ")?; + if password != password_confirm { + bail!("Passwords don't match."); + } + + CryptoKeys::init(&creds, &user_secrets, &password).await?; + + println!(""); + println!("Cryptographic key setup is complete."); + println!(""); + println!("If you are using the static login provider, add the following section to your .toml configuration file:"); + println!(""); + dump_config(&password, &creds); + } + Command::InitializeLocalKeys { creds } => { + let creds = make_storage_creds(creds); + + println!("Please enter a password for local IMAP access."); + println!("This password is not used for key decryption, your keys will be printed below (do not lose them!)"); + println!( + "If you plan on using LDAP login, stop right here and use `first-login` instead" + ); + let password = rpassword::prompt_password("Enter password: ")?; + let password_confirm = rpassword::prompt_password("Confirm password: ")?; + if password != password_confirm { + bail!("Passwords don't match."); + } + + let master = gen_key(); + let (_, secret) = gen_keypair(); + let keys = CryptoKeys::init_without_password(&creds, &master, &secret).await?; + + println!(""); + println!("Cryptographic key setup is complete."); + println!(""); + println!("Add the following section to your .toml configuration file:"); + println!(""); + dump_config(&password, &creds); + dump_keys(&keys); + } + Command::AddPassword { + creds, + user_secrets, + gen, + } => { + let creds = make_storage_creds(creds); + let user_secrets = make_user_secrets(user_secrets); + + let existing_password = + rpassword::prompt_password("Enter existing password to decrypt keys: ")?; + let new_password = if gen { + let password = base64::encode_config( + &u128::to_be_bytes(thread_rng().gen())[..10], + base64::URL_SAFE_NO_PAD, + ); + println!("Your new password: {}", password); + println!("Keep it safe!"); + password + } else { + let password = rpassword::prompt_password("Enter new password: ")?; + let password_confirm = rpassword::prompt_password("Confirm new password: ")?; + if password != password_confirm { + bail!("Passwords don't match."); + } + password + }; + + let keys = CryptoKeys::open(&creds, &user_secrets, &existing_password).await?; + keys.add_password(&creds, &user_secrets, &new_password) + .await?; + println!(""); + println!("New password added successfully."); + } + Command::DeletePassword { + creds, + user_secrets, + allow_delete_all, + } => { + let creds = make_storage_creds(creds); + let user_secrets = make_user_secrets(user_secrets); + + let existing_password = rpassword::prompt_password("Enter password to delete: ")?; + + let keys = match allow_delete_all { + true => Some(CryptoKeys::open(&creds, &user_secrets, &existing_password).await?), + false => None, + }; + + CryptoKeys::delete_password(&creds, &existing_password, allow_delete_all).await?; + + println!(""); + println!("Password was deleted successfully."); + + if let Some(keys) = keys { + println!("As a reminder, here are your cryptographic keys:"); + dump_keys(&keys); + } + } + Command::ShowKeys { + creds, + user_secrets, + } => { + let creds = make_storage_creds(creds); + let user_secrets = make_user_secrets(user_secrets); + + let existing_password = rpassword::prompt_password("Enter key decryption password: ")?; + + let keys = CryptoKeys::open(&creds, &user_secrets, &existing_password).await?; + dump_keys(&keys); + } + } + + Ok(()) +} + +fn make_storage_creds(c: StorageCredsArgs) -> StorageCredentials { + let s3_region = Region { + name: c.region.clone(), + endpoint: c.s3_endpoint, + }; + let k2v_region = Region { + name: c.region, + endpoint: c.k2v_endpoint, + }; + StorageCredentials { + k2v_region, + s3_region, + aws_access_key_id: c.aws_access_key_id, + aws_secret_access_key: c.aws_secret_access_key, + bucket: c.bucket, + } +} + +fn make_user_secrets(c: UserSecretsArgs) -> UserSecrets { + UserSecrets { + user_secret: c.user_secret, + alternate_user_secrets: c + .alternate_user_secrets + .split(',') + .map(|x| x.trim()) + .filter(|x| !x.is_empty()) + .map(|x| x.to_string()) + .collect(), + } +} + +fn dump_config(password: &str, creds: &StorageCredentials) { + println!("[login_static.users.]"); + println!( + "password = \"{}\"", + hash_password(password).expect("unable to hash password") + ); + println!("aws_access_key_id = \"{}\"", creds.aws_access_key_id); + println!( + "aws_secret_access_key = \"{}\"", + creds.aws_secret_access_key + ); +} + +fn dump_keys(keys: &CryptoKeys) { + println!("master_key = \"{}\"", base64::encode(&keys.master)); + println!("secret_key = \"{}\"", base64::encode(&keys.secret)); +} -- cgit v1.2.3