From 9014f3a8b9f43a1858e79702468f4c7f35ed7fa9 Mon Sep 17 00:00:00 2001 From: Phuong Nguyen Date: Mon, 9 Jan 2023 16:57:41 -0800 Subject: [PATCH] fix: storing credentials (#258) * Fix storing credentials * Fix clippy --- workspaces/src/error/impls.rs | 8 ++++++++ workspaces/src/rpc/tool.rs | 18 +++++++++++------- workspaces/src/types/account.rs | 13 ++++--------- workspaces/tests/create_account.rs | 14 ++++++++++++++ 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/workspaces/src/error/impls.rs b/workspaces/src/error/impls.rs index 4e3d534a..432c2de6 100644 --- a/workspaces/src/error/impls.rs +++ b/workspaces/src/error/impls.rs @@ -28,6 +28,14 @@ impl ErrorKind { Error::message(self, msg) } + pub(crate) fn full(self, msg: T, error: E) -> Error + where + T: Into>, + E: Into>, + { + Error::full(self, msg, error) + } + pub(crate) fn detailed(self, error: ExecutionFailure) -> Error { Error::detailed(self, error) } diff --git a/workspaces/src/rpc/tool.rs b/workspaces/src/rpc/tool.rs index 23b26bac..dd0ceb7e 100644 --- a/workspaces/src/rpc/tool.rs +++ b/workspaces/src/rpc/tool.rs @@ -57,15 +57,20 @@ pub(crate) async fn url_create_account( Ok(()) } -pub(crate) fn write_cred_to_file(path: &Path, id: &AccountId, sk: &SecretKey) { - let mut file = File::create(path).expect("Failed to create / write a key file."); +pub(crate) fn write_cred_to_file(path: &Path, id: &AccountId, sk: &SecretKey) -> Result<()> { + let mut file = File::create(path).map_err(|err| { + ErrorKind::Io.full( + format!("failed to open {path:?} for writing credentials"), + err, + ) + })?; #[cfg(unix)] { use std::os::unix::prelude::PermissionsExt; let mut perm = file .metadata() - .expect("Failed to retrieve key file metadata.") + .map_err(|err| ErrorKind::Io.full("Failed to retrieve key file metadata.", err))? .permissions(); #[cfg(target_os = "macos")] @@ -74,7 +79,7 @@ pub(crate) fn write_cred_to_file(path: &Path, id: &AccountId, sk: &SecretKey) { perm.set_mode(libc::S_IWUSR | libc::S_IRUSR); file.set_permissions(perm) - .expect("Failed to set permissions for a key file."); + .map_err(|err| ErrorKind::Io.full("Failed to set permissions for a key file.", err))?; } let content = serde_json::json!({ @@ -85,7 +90,6 @@ pub(crate) fn write_cred_to_file(path: &Path, id: &AccountId, sk: &SecretKey) { .to_string() .into_bytes(); - if let Err(err) = file.write_all(&content) { - panic!("Failed to write a key file {}", err); - } + file.write_all(&content) + .map_err(|err| ErrorKind::Io.full("Failed to write a key file", err)) } diff --git a/workspaces/src/types/account.rs b/workspaces/src/types/account.rs index 88b9838a..a84ae4ae 100644 --- a/workspaces/src/types/account.rs +++ b/workspaces/src/types/account.rs @@ -180,15 +180,10 @@ impl Account { /// Store the credentials of this account locally in the directory provided. pub async fn store_credentials(&self, save_dir: impl AsRef) -> Result<()> { - let savepath = save_dir.as_ref().to_path_buf(); - std::fs::create_dir_all(save_dir).map_err(|e| ErrorKind::Io.custom(e))?; - - let mut savepath = savepath.join(self.id().to_string()); - savepath.set_extension("json"); - - crate::rpc::tool::write_cred_to_file(&savepath, self.id(), &self.secret_key().0); - - Ok(()) + let savepath = save_dir.as_ref(); + std::fs::create_dir_all(&save_dir).map_err(|e| ErrorKind::Io.custom(e))?; + let savepath = savepath.join(format!("{}.json", self.id())); + crate::rpc::tool::write_cred_to_file(&savepath, self.id(), &self.secret_key().0) } /// Get the keys of this account. The public key can be retrieved from the secret key. diff --git a/workspaces/tests/create_account.rs b/workspaces/tests/create_account.rs index 908ac5d1..5c02e7d3 100644 --- a/workspaces/tests/create_account.rs +++ b/workspaces/tests/create_account.rs @@ -1,6 +1,10 @@ #![recursion_limit = "256"] +use serde_json::{Map, Value}; use test_log::test; +use std::fs::File; +use std::path::Path; + #[test(tokio::test)] async fn test_subaccount_creation() -> anyhow::Result<()> { let worker = workspaces::sandbox().await?; @@ -17,5 +21,15 @@ async fn test_subaccount_creation() -> anyhow::Result<()> { assert_eq!(actual_id, expect_id); + // Check if the stored credentials match with the subaccount created. + let savedir = Path::new("../target/credentials"); + sub.store_credentials(savedir).await?; + let creds = File::open(savedir.join(format!("{}.json", sub.id())))?; + let contents: Map = serde_json::from_reader(creds)?; + assert_eq!( + contents.get("account_id"), + Some(&Value::String(sub.id().to_string())) + ); + Ok(()) }