From e170c8ef36de9127b292d23cc42d80e6fe5b8632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 13 Feb 2018 00:46:20 +0000 Subject: [PATCH] rpc: generate new account id for imported wallets --- ethcore/src/account_provider/mod.rs | 6 +++--- ethstore/src/ethstore.rs | 7 ++++++- ethstore/src/secret_store.rs | 2 +- rpc/src/v1/impls/parity_accounts.rs | 2 +- rpc/src/v1/tests/mocked/parity_accounts.rs | 22 +++++++++++++++++++++- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/ethcore/src/account_provider/mod.rs b/ethcore/src/account_provider/mod.rs index d31ded682db..74d24e7f50e 100755 --- a/ethcore/src/account_provider/mod.rs +++ b/ethcore/src/account_provider/mod.rs @@ -264,9 +264,9 @@ impl AccountProvider { Ok(Address::from(account.address).into()) } - /// Import a new presale wallet. - pub fn import_wallet(&self, json: &[u8], password: &str) -> Result { - let account = self.sstore.import_wallet(SecretVaultRef::Root, json, password)?; + /// Import a new wallet. + pub fn import_wallet(&self, json: &[u8], password: &str, gen_id: bool) -> Result { + let account = self.sstore.import_wallet(SecretVaultRef::Root, json, password, gen_id)?; if self.blacklisted_accounts.contains(&account.address) { self.sstore.remove_account(&account, password)?; return Err(SSError::InvalidAccount.into()); diff --git a/ethstore/src/ethstore.rs b/ethstore/src/ethstore.rs index 4c6309a1102..40a687fc988 100755 --- a/ethstore/src/ethstore.rs +++ b/ethstore/src/ethstore.rs @@ -166,9 +166,14 @@ impl SecretStore for EthStore { self.insert_account(vault, keypair.secret().clone(), password) } - fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str) -> Result { + fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str, gen_id: bool) -> Result { let json_keyfile = json::KeyFile::load(json).map_err(|_| Error::InvalidKeyFile("Invalid JSON format".to_owned()))?; let mut safe_account = SafeAccount::from_file(json_keyfile, None); + + if gen_id { + safe_account.id = Random::random(); + } + let secret = safe_account.crypto.secret(password).map_err(|_| Error::InvalidPassword)?; safe_account.address = KeyPair::from_secret(secret)?.address(); self.store.import(vault, safe_account) diff --git a/ethstore/src/secret_store.rs b/ethstore/src/secret_store.rs index b46e6f2d817..ebac2f99229 100755 --- a/ethstore/src/secret_store.rs +++ b/ethstore/src/secret_store.rs @@ -116,7 +116,7 @@ pub trait SecretStore: SimpleSecretStore { /// Imports presale wallet fn import_presale(&self, vault: SecretVaultRef, json: &[u8], password: &str) -> Result; /// Imports existing JSON wallet - fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str) -> Result; + fn import_wallet(&self, vault: SecretVaultRef, json: &[u8], password: &str, gen_id: bool) -> Result; /// Copies account between stores and vaults. fn copy_account(&self, new_store: &SimpleSecretStore, new_vault: SecretVaultRef, account: &StoreAccountRef, password: &str, new_password: &str) -> Result<(), Error>; /// Checks if password matches given account. diff --git a/rpc/src/v1/impls/parity_accounts.rs b/rpc/src/v1/impls/parity_accounts.rs index 128415bbd7f..8de8fea900f 100644 --- a/rpc/src/v1/impls/parity_accounts.rs +++ b/rpc/src/v1/impls/parity_accounts.rs @@ -95,7 +95,7 @@ impl ParityAccounts for ParityAccountsClient { let store = self.account_provider()?; store.import_presale(json.as_bytes(), &pass) - .or_else(|_| store.import_wallet(json.as_bytes(), &pass)) + .or_else(|_| store.import_wallet(json.as_bytes(), &pass, true)) .map(Into::into) .map_err(|e| errors::account("Could not create account.", e)) } diff --git a/rpc/src/v1/tests/mocked/parity_accounts.rs b/rpc/src/v1/tests/mocked/parity_accounts.rs index 540bea90394..258310b85a3 100644 --- a/rpc/src/v1/tests/mocked/parity_accounts.rs +++ b/rpc/src/v1/tests/mocked/parity_accounts.rs @@ -480,7 +480,7 @@ fn should_export_account() { // given let tester = setup(); let wallet = r#"{"id":"6a186c80-7797-cff2-bc2e-7c1d6a6cc76e","version":3,"crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"a1c6ff99070f8032ca1c4e8add006373"},"ciphertext":"df27e3db64aa18d984b6439443f73660643c2d119a6f0fa2fa9a6456fc802d75","kdf":"pbkdf2","kdfparams":{"c":10240,"dklen":32,"prf":"hmac-sha256","salt":"ddc325335cda5567a1719313e73b4842511f3e4a837c9658eeb78e51ebe8c815"},"mac":"3dc888ae79cbb226ff9c455669f6cf2d79be72120f2298f6cb0d444fddc0aa3d"},"address":"0042e5d2a662eeaca8a7e828c174f98f35d8925b","name":"parity-export-test","meta":"{\"passwordHint\":\"parity-export-test\",\"timestamp\":1490017814987}"}"#; - tester.accounts.import_wallet(wallet.as_bytes(), "parity-export-test").unwrap(); + tester.accounts.import_wallet(wallet.as_bytes(), "parity-export-test", false).unwrap(); let accounts = tester.accounts.accounts().unwrap(); assert_eq!(accounts.len(), 1); @@ -501,6 +501,26 @@ fn should_export_account() { assert_eq!(result, Some(response.into())); } +#[test] +fn should_import_wallet() { + let tester = setup(); + + let id = "6a186c80-7797-cff2-bc2e-7c1d6a6cc76e"; + let request = r#"{"jsonrpc":"2.0","method":"parity_newAccountFromWallet","params":["{\"id\":\"\",\"version\":3,\"crypto\":{\"cipher\":\"aes-128-ctr\",\"cipherparams\":{\"iv\":\"478736fb55872c1baf01b27b1998c90b\"},\"ciphertext\":\"fe5a63cc0055d7b0b3b57886f930ad9b63f48950d1348145d95996c41e05f4e0\",\"kdf\":\"pbkdf2\",\"kdfparams\":{\"c\":10240,\"dklen\":32,\"prf\":\"hmac-sha256\",\"salt\":\"658436d6738a19731149a98744e5cf02c8d5aa1f8e80c1a43cc9351c70a984e4\"},\"mac\":\"c7384b26ecf25539d942030230062af9b69de5766cbcc4690bffce1536644631\"},\"address\":\"00bac56a8a27232baa044c03f43bf3648c961735\",\"name\":\"hello world\",\"meta\":\"{}\"}", "himom"],"id":1}"#; + let request = request.replace("", id); + let response = r#"{"jsonrpc":"2.0","result":"0x00bac56a8a27232baa044c03f43bf3648c961735","id":1}"#; + + let res = tester.io.handle_request_sync(&request).unwrap(); + + assert_eq!(res, response); + + let account_meta = tester.accounts.account_meta("0x00bac56a8a27232baa044c03f43bf3648c961735".into()).unwrap(); + let account_uuid: String = account_meta.uuid.unwrap().into(); + + // the RPC should import the account with a new id + assert!(account_uuid != id); +} + #[test] fn should_sign_message() { let tester = setup();