From 1ec213ca46545d94d4449a8b30597b9253b44cde Mon Sep 17 00:00:00 2001 From: FroVolod Date: Mon, 27 Jan 2025 23:56:43 +0200 Subject: [PATCH] fix: Use legacy keychain as a fallback storage when system keychain is not supported (e.g. WSL, Codespaces, Docker containers, CI) (#439) Resolves #435 ![Screenshot 2025-01-22 at 20 47 36](https://github.com/user-attachments/assets/42e60eef-203d-4e09-9d37-66e41e55a98c) --------- Co-authored-by: FroVolod --- Cargo.toml | 1 + .../save_keypair_to_keychain/mod.rs | 11 +++--- .../add_key/autogenerate_new_keypair/mod.rs | 15 ++++---- .../add_key/autogenerate_new_keypair/mod.rs | 3 +- src/commands/account/import_account/mod.rs | 20 +++++------ src/common.rs | 35 +++++++++++++++++++ 6 files changed, 61 insertions(+), 24 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 23d8a7b46..d91bf46d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -103,6 +103,7 @@ keyring = { version = "3.0.5", features = [ "sync-secret-service", "vendored", ] } + interactive-clap = "0.3" interactive-clap-derive = "0.3" diff --git a/src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_keychain/mod.rs b/src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_keychain/mod.rs index b9032d082..26f43d396 100644 --- a/src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_keychain/mod.rs +++ b/src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_keychain/mod.rs @@ -42,7 +42,9 @@ impl From for crate::commands::ActionContext { } }); let on_before_sending_transaction_callback: crate::transaction_signature_options::OnBeforeSendingTransactionCallback = - std::sync::Arc::new( + std::sync::Arc::new({ + let credentials_home_dir = item.0.global_context.config.credentials_home_dir.clone(); + move |transaction, network_config| { let account_id = match transaction { crate::transaction_signature_options::SignedTransactionOrSignedDelegateAction::SignedTransaction( @@ -52,14 +54,15 @@ impl From for crate::commands::ActionContext { signed_delegate_action, ) => signed_delegate_action.delegate_action.sender_id.clone() }; - crate::common::save_access_key_to_keychain( + crate::common::save_access_key_to_keychain_or_save_to_legacy_keychain( network_config.clone(), + credentials_home_dir.clone(), &serde_json::to_string(&item.0.key_pair_properties)?, &item.0.key_pair_properties.public_key_str, account_id.as_ref(), ) - }, - ); + } + }); Self { global_context: item.0.global_context, diff --git a/src/commands/account/create_account/fund_myself_create_account/add_key/autogenerate_new_keypair/mod.rs b/src/commands/account/create_account/fund_myself_create_account/add_key/autogenerate_new_keypair/mod.rs index 5d3bdd26d..fd523231e 100644 --- a/src/commands/account/create_account/fund_myself_create_account/add_key/autogenerate_new_keypair/mod.rs +++ b/src/commands/account/create_account/fund_myself_create_account/add_key/autogenerate_new_keypair/mod.rs @@ -95,13 +95,14 @@ impl SaveModeContext { SaveModeDiscriminants::SaveToKeychain => { let key_pair_properties_buf = serde_json::to_string(&key_pair_properties)?; - crate::common::save_access_key_to_keychain( - network_config.clone(), - &key_pair_properties_buf, - &key_pair_properties.public_key_str, - new_account_id.as_ref(), - ) - } + crate::common::save_access_key_to_keychain_or_save_to_legacy_keychain( + network_config.clone(), + credentials_home_dir.clone(), + &key_pair_properties_buf, + &key_pair_properties.public_key_str, + new_account_id.as_ref(), + ) + } SaveModeDiscriminants::SaveToLegacyKeychain => { let key_pair_properties_buf = serde_json::to_string(&key_pair_properties)?; diff --git a/src/commands/account/create_account/sponsor_by_faucet_service/add_key/autogenerate_new_keypair/mod.rs b/src/commands/account/create_account/sponsor_by_faucet_service/add_key/autogenerate_new_keypair/mod.rs index ba939a288..f26e9e566 100644 --- a/src/commands/account/create_account/sponsor_by_faucet_service/add_key/autogenerate_new_keypair/mod.rs +++ b/src/commands/account/create_account/sponsor_by_faucet_service/add_key/autogenerate_new_keypair/mod.rs @@ -83,8 +83,9 @@ impl SaveModeContext { SaveModeDiscriminants::SaveToKeychain => { let key_pair_properties_buf = serde_json::to_string(&key_pair_properties)?; - crate::common::save_access_key_to_keychain( + crate::common::save_access_key_to_keychain_or_save_to_legacy_keychain( network_config.clone(), + credentials_home_dir.clone(), &key_pair_properties_buf, &key_pair_properties.public_key_str, &new_account_id_str, diff --git a/src/commands/account/import_account/mod.rs b/src/commands/account/import_account/mod.rs index d6419eb58..a141eb087 100644 --- a/src/commands/account/import_account/mod.rs +++ b/src/commands/account/import_account/mod.rs @@ -118,18 +118,14 @@ fn save_access_key( ) .prompt()?; if let SelectStorage::SaveToKeychain = selection { - let storage_message = crate::common::save_access_key_to_keychain( - network_config, - key_pair_properties_buf, - public_key_str, - account_id.as_ref(), - ) - .wrap_err_with(|| { - format!( - "Failed to save the access key <{}> to the keychain", - public_key_str - ) - })?; + let storage_message = + crate::common::save_access_key_to_keychain_or_save_to_legacy_keychain( + network_config, + credentials_home_dir, + key_pair_properties_buf, + public_key_str, + account_id.as_ref(), + )?; eprintln!("{}", storage_message); return Ok(()); } diff --git a/src/common.rs b/src/common.rs index 1d3636e20..0d69425f2 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1332,6 +1332,41 @@ pub fn print_transaction_status( return_value } +pub fn save_access_key_to_keychain_or_save_to_legacy_keychain( + network_config: crate::config::NetworkConfig, + credentials_home_dir: std::path::PathBuf, + key_pair_properties_buf: &str, + public_key_str: &str, + account_id: &str, +) -> color_eyre::eyre::Result { + match save_access_key_to_keychain( + network_config.clone(), + key_pair_properties_buf, + public_key_str, + account_id, + ) { + Ok(message) => Ok(message), + Err(err) => { + eprintln!( + "\n{}\n{}\n", + format!( + "Failed to save the access key <{}> to the keychain.\n{}", + public_key_str, err + ) + .red(), + "The data for the access key will be stored in the legacy keychain.".red() + ); + save_access_key_to_legacy_keychain( + network_config.clone(), + credentials_home_dir, + key_pair_properties_buf, + public_key_str, + account_id, + ) + } + } +} + pub fn save_access_key_to_keychain( network_config: crate::config::NetworkConfig, key_pair_properties_buf: &str,