keys import (#1240)
* pattern importing * tests for import * cli options for account import * [options] for import also * removed globbing * removed glob crate refs
This commit is contained in:
parent
be435cde99
commit
b4b883b341
@ -23,7 +23,8 @@ Parity. Ethereum Client.
|
|||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
parity daemon <pid-file> [options]
|
parity daemon <pid-file> [options]
|
||||||
parity account (new | list) [options]
|
parity account (new | list ) [options]
|
||||||
|
parity account import <path>... [options]
|
||||||
parity import [ <file> ] [options]
|
parity import [ <file> ] [options]
|
||||||
parity export [ <file> ] [options]
|
parity export [ <file> ] [options]
|
||||||
parity signer new-token [options]
|
parity signer new-token [options]
|
||||||
@ -212,6 +213,7 @@ pub struct Args {
|
|||||||
pub cmd_new_token: bool,
|
pub cmd_new_token: bool,
|
||||||
pub arg_pid_file: String,
|
pub arg_pid_file: String,
|
||||||
pub arg_file: Option<String>,
|
pub arg_file: Option<String>,
|
||||||
|
pub arg_path: Vec<String>,
|
||||||
pub flag_chain: String,
|
pub flag_chain: String,
|
||||||
pub flag_db_path: String,
|
pub flag_db_path: String,
|
||||||
pub flag_identity: String,
|
pub flag_identity: String,
|
||||||
|
@ -482,6 +482,11 @@ fn execute_account_cli(conf: Configuration) {
|
|||||||
for &(addr, _) in &secret_store.accounts().unwrap() {
|
for &(addr, _) in &secret_store.accounts().unwrap() {
|
||||||
println!("{:?}", addr);
|
println!("{:?}", addr);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if conf.args.cmd_import {
|
||||||
|
let imported = util::keys::import_keys_paths(&mut secret_store, &conf.args.arg_path).unwrap();
|
||||||
|
println!("Imported {} keys", imported);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
21
util/res/pat/p1.json
Normal file
21
util/res/pat/p1.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"address": "3f49624084b67849c7b4e805c5988c21a430f9d9",
|
||||||
|
"Crypto": {
|
||||||
|
"cipher": "aes-128-ctr",
|
||||||
|
"ciphertext": "9f27e3dd4fc73e7103ed61e5493662189a3eb52223ae49e3d1deacc04c889eae",
|
||||||
|
"cipherparams": {
|
||||||
|
"iv": "457494bf05f2618c397dc74dbb5181c0"
|
||||||
|
},
|
||||||
|
"kdf": "scrypt",
|
||||||
|
"kdfparams": {
|
||||||
|
"dklen": 32,
|
||||||
|
"n": 262144,
|
||||||
|
"p": 1,
|
||||||
|
"r": 8,
|
||||||
|
"salt": "db14edb18c41ee7f5ec4397df89c3a2ae4d0af60884c52bb54ce490574f8df33"
|
||||||
|
},
|
||||||
|
"mac": "572d24532438d31fdf513c744a3ff26c933ffda5744ee42bc71661cbe3f2112e"
|
||||||
|
},
|
||||||
|
"id": "62a0ad73-556d-496a-8e1c-0783d30d3ace",
|
||||||
|
"version": 3
|
||||||
|
}
|
21
util/res/pat/p2.json
Normal file
21
util/res/pat/p2.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"address": "5ba4dcf897e97c2bdf8315b9ef26c13c085988cf",
|
||||||
|
"Crypto": {
|
||||||
|
"cipher": "aes-128-ctr",
|
||||||
|
"ciphertext": "d4a08ec930163778273920f6ad1d49b71836337be6fd9863993ac700a612fddd",
|
||||||
|
"cipherparams": {
|
||||||
|
"iv": "89ce5ec129fc27cd5bcbeb8c92bdad50"
|
||||||
|
},
|
||||||
|
"kdf": "scrypt",
|
||||||
|
"kdfparams": {
|
||||||
|
"dklen": 32,
|
||||||
|
"n": 262144,
|
||||||
|
"p": 1,
|
||||||
|
"r": 8,
|
||||||
|
"salt": "612ab108dc37e69ee8af37a7b24bf7f2234086d7bbf945bacdeccce331f7f84a"
|
||||||
|
},
|
||||||
|
"mac": "4152caa7444e06784223d735cea80cd2690b4c587ad8db3d5529442227b25695"
|
||||||
|
},
|
||||||
|
"id": "35086353-fb12-4029-b56b-033cd61ce35b",
|
||||||
|
"version": 3
|
||||||
|
}
|
@ -80,9 +80,10 @@ pub fn import_geth_key(secret_store: &mut SecretStore, geth_keyfile_path: &Path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Imports all geth keys in the directory
|
/// Imports all geth keys in the directory
|
||||||
pub fn import_geth_keys(secret_store: &mut SecretStore, geth_keyfiles_directory: &Path) -> Result<(), ImportError> {
|
pub fn import_geth_keys(secret_store: &mut SecretStore, geth_keyfiles_directory: &Path) -> Result<usize, ImportError> {
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
let geth_files = try!(enumerate_geth_keys(geth_keyfiles_directory));
|
let geth_files = try!(enumerate_geth_keys(geth_keyfiles_directory));
|
||||||
|
let mut total = 0;
|
||||||
for &(ref address, ref file_path) in &geth_files {
|
for &(ref address, ref file_path) in &geth_files {
|
||||||
let mut path = PathBuf::new();
|
let mut path = PathBuf::new();
|
||||||
path.push(geth_keyfiles_directory);
|
path.push(geth_keyfiles_directory);
|
||||||
@ -90,18 +91,45 @@ pub fn import_geth_keys(secret_store: &mut SecretStore, geth_keyfiles_directory:
|
|||||||
if let Err(e) = import_geth_key(secret_store, Path::new(&path)) {
|
if let Err(e) = import_geth_key(secret_store, Path::new(&path)) {
|
||||||
warn!("Skipped geth address {}, error importing: {:?}", address, e)
|
warn!("Skipped geth address {}, error importing: {:?}", address, e)
|
||||||
}
|
}
|
||||||
|
else { total = total + 1}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(total)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Gets the default geth keystore directory.
|
/// Gets the default geth keystore directory.
|
||||||
///
|
|
||||||
/// Based on https://github.com/ethereum/go-ethereum/blob/e553215/common/path.go#L75
|
|
||||||
pub fn keystore_dir(is_testnet: bool) -> PathBuf {
|
pub fn keystore_dir(is_testnet: bool) -> PathBuf {
|
||||||
path::ethereum::with_default(if is_testnet {"testnet/keystore"} else {"keystore"})
|
path::ethereum::with_default(if is_testnet {"testnet/keystore"} else {"keystore"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Imports key(s) from provided file/directory
|
||||||
|
pub fn import_keys_path(secret_store: &mut SecretStore, path: &str) -> Result<usize, ImportError> {
|
||||||
|
// check if it is just one file or directory
|
||||||
|
if let Ok(meta) = fs::metadata(path) {
|
||||||
|
if meta.is_file() {
|
||||||
|
try!(import_geth_key(secret_store, Path::new(path)));
|
||||||
|
return Ok(1);
|
||||||
|
}
|
||||||
|
else if meta.is_dir() {
|
||||||
|
return Ok(try!(fs::read_dir(path)).fold(
|
||||||
|
0,
|
||||||
|
|total, p|
|
||||||
|
total +
|
||||||
|
match p {
|
||||||
|
Ok(dir_entry) => import_keys_path(secret_store, dir_entry.path().to_str().unwrap()).unwrap_or_else(|_| 0),
|
||||||
|
Err(e) => { warn!("Error importing dir entry: {:?}", e); 0 },
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Imports all keys from list of provided files/directories
|
||||||
|
pub fn import_keys_paths(secret_store: &mut SecretStore, path: &[String]) -> Result<usize, ImportError> {
|
||||||
|
Ok(path.iter().fold(0, |total, ref p| total + import_keys_path(secret_store, &p).unwrap_or_else(|_| 0)))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -115,10 +143,21 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pat_path() -> &'static str {
|
||||||
|
match ::std::fs::metadata("res") {
|
||||||
|
Ok(_) => "res/pat",
|
||||||
|
Err(_) => "util/res/pat"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn test_path_param(param_val: &'static str) -> String {
|
fn test_path_param(param_val: &'static str) -> String {
|
||||||
test_path().to_owned() + param_val
|
test_path().to_owned() + param_val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pat_path_param(param_val: &'static str) -> String {
|
||||||
|
pat_path().to_owned() + param_val
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_enumerate() {
|
fn can_enumerate() {
|
||||||
let keys = enumerate_geth_keys(Path::new(test_path())).unwrap();
|
let keys = enumerate_geth_keys(Path::new(test_path())).unwrap();
|
||||||
@ -191,4 +230,32 @@ mod tests {
|
|||||||
assert!(val.is_ok());
|
assert!(val.is_ok());
|
||||||
assert_eq!(32, val.unwrap().len());
|
assert_eq!(32, val.unwrap().len());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_import_by_filename() {
|
||||||
|
let temp = ::devtools::RandomTempPath::create_dir();
|
||||||
|
let mut secret_store = SecretStore::new_in(temp.as_path());
|
||||||
|
|
||||||
|
let amount = import_keys_path(&mut secret_store, &pat_path_param("/p1.json")).unwrap();
|
||||||
|
assert_eq!(1, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_import_by_dir() {
|
||||||
|
let temp = ::devtools::RandomTempPath::create_dir();
|
||||||
|
let mut secret_store = SecretStore::new_in(temp.as_path());
|
||||||
|
|
||||||
|
let amount = import_keys_path(&mut secret_store, pat_path()).unwrap();
|
||||||
|
assert_eq!(2, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_import_mulitple() {
|
||||||
|
let temp = ::devtools::RandomTempPath::create_dir();
|
||||||
|
let mut secret_store = SecretStore::new_in(temp.as_path());
|
||||||
|
|
||||||
|
let amount = import_keys_paths(&mut secret_store, &[pat_path_param("/p1.json"), pat_path_param("/p2.json")]).unwrap();
|
||||||
|
assert_eq!(2, amount);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,3 +23,4 @@ mod test_account_provider;
|
|||||||
|
|
||||||
pub use self::store::AccountProvider;
|
pub use self::store::AccountProvider;
|
||||||
pub use self::test_account_provider::{TestAccount, TestAccountProvider};
|
pub use self::test_account_provider::{TestAccount, TestAccountProvider};
|
||||||
|
pub use self::geth_import::import_keys_paths;
|
||||||
|
Loading…
Reference in New Issue
Block a user