mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-10-17 15:21:39 +02:00
Rework directory checks/setups at launch (#318)
* rework setup code to ensure --top_level_dir flag works and all files are only output into the desired directory * check for existence of wallet configuration file in target directory before asking recovery phrase and password * test fixes and add test_mode flag to parse_init_args
This commit is contained in:
+54
-19
@@ -42,7 +42,10 @@ pub const API_SECRET_FILE_NAME: &'static str = ".api_secret";
|
||||
/// Owner API secret
|
||||
pub const OWNER_API_SECRET_FILE_NAME: &'static str = ".owner_api_secret";
|
||||
|
||||
fn get_grin_path(chain_type: &global::ChainTypes) -> Result<PathBuf, ConfigError> {
|
||||
fn get_grin_path(
|
||||
chain_type: &global::ChainTypes,
|
||||
create_path: bool,
|
||||
) -> Result<PathBuf, ConfigError> {
|
||||
// Check if grin dir exists
|
||||
let mut grin_path = match dirs::home_dir() {
|
||||
Some(p) => p,
|
||||
@@ -51,10 +54,17 @@ fn get_grin_path(chain_type: &global::ChainTypes) -> Result<PathBuf, ConfigError
|
||||
grin_path.push(GRIN_HOME);
|
||||
grin_path.push(chain_type.shortname());
|
||||
// Create if the default path doesn't exist
|
||||
if !grin_path.exists() {
|
||||
if !grin_path.exists() && create_path {
|
||||
fs::create_dir_all(grin_path.clone())?;
|
||||
}
|
||||
Ok(grin_path)
|
||||
|
||||
if !grin_path.exists() {
|
||||
return Err(ConfigError::PathNotFoundError(String::from(
|
||||
grin_path.to_str().unwrap(),
|
||||
)));
|
||||
} else {
|
||||
Ok(grin_path)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_config_current_dir(path: &str) -> Option<PathBuf> {
|
||||
@@ -72,6 +82,13 @@ fn check_config_current_dir(path: &str) -> Option<PathBuf> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Whether a config file exists at the given directory
|
||||
pub fn config_file_exists(path: &str) -> bool {
|
||||
let mut path = PathBuf::from(path);
|
||||
path.push(WALLET_CONFIG_FILE_NAME);
|
||||
path.exists()
|
||||
}
|
||||
|
||||
/// Create file with api secret
|
||||
pub fn init_api_secret(api_secret_path: &PathBuf) -> Result<(), ConfigError> {
|
||||
let mut api_secret_file = File::create(api_secret_path)?;
|
||||
@@ -104,7 +121,7 @@ fn check_api_secret_file(
|
||||
) -> Result<(), ConfigError> {
|
||||
let grin_path = match data_path {
|
||||
Some(p) => p,
|
||||
None => get_grin_path(chain_type)?,
|
||||
None => get_grin_path(chain_type, false)?,
|
||||
};
|
||||
let mut api_secret_path = grin_path.clone();
|
||||
api_secret_path.push(file_name);
|
||||
@@ -119,17 +136,23 @@ fn check_api_secret_file(
|
||||
pub fn initial_setup_wallet(
|
||||
chain_type: &global::ChainTypes,
|
||||
data_path: Option<PathBuf>,
|
||||
create_path: bool,
|
||||
) -> Result<GlobalWalletConfig, ConfigError> {
|
||||
check_api_secret_file(chain_type, data_path.clone(), OWNER_API_SECRET_FILE_NAME)?;
|
||||
check_api_secret_file(chain_type, data_path.clone(), API_SECRET_FILE_NAME)?;
|
||||
if create_path {
|
||||
if let Some(p) = data_path.clone() {
|
||||
fs::create_dir_all(p)?;
|
||||
}
|
||||
}
|
||||
// Use config file if current directory if it exists, .grin home otherwise
|
||||
if let Some(p) = check_config_current_dir(WALLET_CONFIG_FILE_NAME) {
|
||||
GlobalWalletConfig::new(p.to_str().unwrap())
|
||||
let (path, config) = if let Some(p) = check_config_current_dir(WALLET_CONFIG_FILE_NAME) {
|
||||
let mut path = p.clone();
|
||||
path.pop();
|
||||
(path, GlobalWalletConfig::new(p.to_str().unwrap())?)
|
||||
} else {
|
||||
// Check if grin dir exists
|
||||
let grin_path = match data_path {
|
||||
let grin_path = match data_path.clone() {
|
||||
Some(p) => p,
|
||||
None => get_grin_path(chain_type)?,
|
||||
None => get_grin_path(chain_type, create_path)?,
|
||||
};
|
||||
|
||||
// Get path to default config file
|
||||
@@ -137,16 +160,28 @@ pub fn initial_setup_wallet(
|
||||
config_path.push(WALLET_CONFIG_FILE_NAME);
|
||||
|
||||
// Return defaults if file doesn't exist
|
||||
if !config_path.exists() {
|
||||
let mut default_config = GlobalWalletConfig::for_chain(chain_type);
|
||||
default_config.config_file_path = Some(config_path);
|
||||
// update paths relative to current dir
|
||||
default_config.update_paths(&grin_path);
|
||||
Ok(default_config)
|
||||
} else {
|
||||
GlobalWalletConfig::new(config_path.to_str().unwrap())
|
||||
match config_path.clone().exists() {
|
||||
false => {
|
||||
let mut default_config = GlobalWalletConfig::for_chain(chain_type);
|
||||
default_config.config_file_path = Some(config_path);
|
||||
// update paths relative to current dir
|
||||
default_config.update_paths(&grin_path);
|
||||
(grin_path, default_config)
|
||||
}
|
||||
true => {
|
||||
let mut path = config_path.clone();
|
||||
path.pop();
|
||||
(
|
||||
path,
|
||||
GlobalWalletConfig::new(config_path.to_str().unwrap())?,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
check_api_secret_file(chain_type, Some(path.clone()), OWNER_API_SECRET_FILE_NAME)?;
|
||||
check_api_secret_file(chain_type, Some(path), API_SECRET_FILE_NAME)?;
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
impl Default for GlobalWalletConfigMembers {
|
||||
|
||||
+3
-1
@@ -30,7 +30,9 @@ mod comments;
|
||||
pub mod config;
|
||||
pub mod types;
|
||||
|
||||
pub use crate::config::{initial_setup_wallet, GRIN_WALLET_DIR, WALLET_CONFIG_FILE_NAME};
|
||||
pub use crate::config::{
|
||||
config_file_exists, initial_setup_wallet, GRIN_WALLET_DIR, WALLET_CONFIG_FILE_NAME,
|
||||
};
|
||||
pub use crate::types::{
|
||||
ConfigError, GlobalWalletConfig, GlobalWalletConfigMembers, TorConfig, WalletConfig,
|
||||
};
|
||||
|
||||
@@ -115,6 +115,9 @@ pub enum ConfigError {
|
||||
|
||||
/// Error serializing config values
|
||||
SerializationError(String),
|
||||
|
||||
/// Path doesn't exist
|
||||
PathNotFoundError(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for ConfigError {
|
||||
@@ -134,6 +137,7 @@ impl fmt::Display for ConfigError {
|
||||
ConfigError::SerializationError(ref message) => {
|
||||
write!(f, "Error serializing configuration: {}", message)
|
||||
}
|
||||
ConfigError::PathNotFoundError(ref message) => write!(f, "Path not found: {}", message),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+29
-3
@@ -19,6 +19,7 @@ extern crate clap;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
use crate::config::ConfigError;
|
||||
use crate::core::global;
|
||||
use crate::util::init_logger;
|
||||
use clap::App;
|
||||
@@ -27,6 +28,7 @@ use grin_wallet_impls::HTTPNodeClient;
|
||||
use grin_wallet_util::grin_core as core;
|
||||
use grin_wallet_util::grin_util as util;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use grin_wallet::cmd;
|
||||
|
||||
@@ -80,6 +82,19 @@ fn real_main() -> i32 {
|
||||
};
|
||||
|
||||
let mut current_dir = None;
|
||||
let mut create_path = false;
|
||||
|
||||
if args.is_present("top_level_dir") {
|
||||
let res = args.value_of("top_level_dir");
|
||||
match res {
|
||||
Some(d) => {
|
||||
current_dir = Some(PathBuf::from(d));
|
||||
}
|
||||
None => {
|
||||
warn!("Argument --top_level_dir needs a value. Defaulting to current directory")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// special cases for certain lifecycle commands
|
||||
match args.subcommand() {
|
||||
@@ -89,15 +104,26 @@ fn real_main() -> i32 {
|
||||
panic!("Error creating config file: {}", e);
|
||||
}));
|
||||
}
|
||||
create_path = true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Load relevant config, try and load a wallet config file
|
||||
// Use defaults for configuration if config file not found anywhere
|
||||
let mut config = config::initial_setup_wallet(&chain_type, current_dir).unwrap_or_else(|e| {
|
||||
panic!("Error loading wallet configuration: {}", e);
|
||||
});
|
||||
let mut config = match config::initial_setup_wallet(&chain_type, current_dir, create_path) {
|
||||
Ok(c) => c,
|
||||
Err(e) => match e {
|
||||
ConfigError::PathNotFoundError(m) => {
|
||||
println!("Wallet configuration not found at {}. (Run `grin-wallet init` to create a new wallet)", m);
|
||||
return 0;
|
||||
}
|
||||
m => {
|
||||
println!("Unable to load wallet configuration: {} (Run `grin-wallet init` to create a new wallet)", m);
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
//config.members.as_mut().unwrap().wallet.chain_type = Some(chain_type);
|
||||
|
||||
|
||||
+10
-2
@@ -19,7 +19,7 @@ use crate::util::{Mutex, ZeroingString};
|
||||
/// Argument parsing and error handling for wallet commands
|
||||
use clap::ArgMatches;
|
||||
use failure::Fail;
|
||||
use grin_wallet_config::{TorConfig, WalletConfig};
|
||||
use grin_wallet_config::{config_file_exists, TorConfig, WalletConfig};
|
||||
use grin_wallet_controller::command;
|
||||
use grin_wallet_controller::{Error, ErrorKind};
|
||||
use grin_wallet_impls::tor::config::is_tor_address;
|
||||
@@ -58,6 +58,8 @@ pub enum ParseError {
|
||||
ArgumentError(String),
|
||||
#[fail(display = "Parsing IO error: {}", _0)]
|
||||
IOError(String),
|
||||
#[fail(display = "Wallet configuration already exists: {}", _0)]
|
||||
WalletExists(String),
|
||||
#[fail(display = "User Cancelled")]
|
||||
CancelledError,
|
||||
}
|
||||
@@ -298,6 +300,7 @@ pub fn parse_init_args<L, C, K>(
|
||||
config: &WalletConfig,
|
||||
g_args: &command::GlobalArgs,
|
||||
args: &ArgMatches,
|
||||
test_mode: bool,
|
||||
) -> Result<command::InitArgs, ParseError>
|
||||
where
|
||||
DefaultWalletImpl<'static, C>: WalletInst<'static, L, C, K>,
|
||||
@@ -305,6 +308,10 @@ where
|
||||
C: NodeClient + 'static,
|
||||
K: keychain::Keychain + 'static,
|
||||
{
|
||||
if config_file_exists(&config.data_file_dir) && !test_mode {
|
||||
return Err(ParseError::WalletExists(config.data_file_dir.clone()));
|
||||
}
|
||||
|
||||
let list_length = match args.is_present("short_wordlist") {
|
||||
false => 32,
|
||||
true => 16,
|
||||
@@ -951,7 +958,8 @@ where
|
||||
wallet.clone(),
|
||||
&wallet_config,
|
||||
&global_wallet_args,
|
||||
&args
|
||||
&args,
|
||||
test_mode,
|
||||
));
|
||||
command::init(wallet, &global_wallet_args, a)
|
||||
}
|
||||
|
||||
+1
-1
@@ -308,7 +308,7 @@ where
|
||||
{
|
||||
let args = app.clone().get_matches_from(arg_vec);
|
||||
let _ = get_wallet_subcommand(test_dir, wallet_name, args.clone());
|
||||
let config = config::initial_setup_wallet(&ChainTypes::AutomatedTesting, None).unwrap();
|
||||
let config = config::initial_setup_wallet(&ChainTypes::AutomatedTesting, None, true).unwrap();
|
||||
let mut wallet_config = config.clone().members.unwrap().wallet;
|
||||
wallet_config.chain_type = None;
|
||||
wallet_config.api_secret_path = None;
|
||||
|
||||
Reference in New Issue
Block a user