Client: dedup setup gateway during init (#1871)

* clients: dedup gateway setup logic

* nym-connect: extract out print_save_config
This commit is contained in:
Jon Häggblad
2022-12-08 22:59:11 +01:00
committed by GitHub
parent ec60966a85
commit 85515fe16e
5 changed files with 91 additions and 159 deletions
+2
View File
@@ -26,6 +26,8 @@ pub enum ClientCoreError {
NoGatewayWithId(String),
#[error("No gateways on network")]
NoGatewaysOnNetwork,
#[error("Failed to setup gateway")]
FailedToSetupGateway,
#[error("List of validator apis is empty")]
ListOfValidatorApisIsEmpty,
#[error("Could not load existing gateway configuration: {0}")]
+36 -1
View File
@@ -21,7 +21,7 @@ use url::Url;
use crate::{
client::key_manager::KeyManager,
config::{persistence::key_pathfinder::ClientKeyPathfinder, Config},
config::{persistence::key_pathfinder::ClientKeyPathfinder, Config, GatewayEndpointConfig},
error::ClientCoreError,
};
@@ -140,6 +140,41 @@ async fn register_with_gateway(
Ok(shared_keys)
}
pub async fn setup_gateway<T: NymConfig>(
register: bool,
user_chosen_gateway_id: Option<&str>,
config: &Config<T>,
) -> Result<GatewayEndpointConfig, ClientCoreError> {
if register {
// Get the gateway details by querying the validator-api. Either pick one at random or use
// the chosen one if it's among the available ones.
println!("Configuring gateway");
let gateway =
query_gateway_details(config.get_validator_api_endpoints(), user_chosen_gateway_id)
.await?;
log::debug!("Querying gateway gives: {}", gateway);
// Registering with gateway by setting up and writing shared keys to disk
log::trace!("Registering gateway");
register_with_gateway_and_store_keys(gateway.clone(), config).await?;
println!("Saved all generated keys");
Ok(gateway.into())
} else if user_chosen_gateway_id.is_some() {
// Just set the config, don't register or create any keys
// This assumes that the user knows what they are doing, and that the existing keys are
// valid for the gateway being used
println!("Using gateway provided by user, keeping existing keys");
let gateway =
query_gateway_details(config.get_validator_api_endpoints(), user_chosen_gateway_id)
.await?;
log::debug!("Querying gateway gives: {}", gateway);
Ok(gateway.into())
} else {
Err(ClientCoreError::FailedToSetupGateway)
}
}
pub fn get_client_address<T>(config: &Config<T>) -> Result<Recipient, ClientCoreError>
where
T: config::NymConfig,
+19 -48
View File
@@ -134,12 +134,20 @@ pub(crate) async fn execute(args: &Init) {
let override_config_fields = OverrideConfig::from(args.clone());
config = override_config(config, override_config_fields);
let gateway = setup_gateway(id, register_gateway, user_chosen_gateway_id, &config)
let gateway = if !register_gateway && user_chosen_gateway_id.is_none() {
reuse_gateway_config(id)
} else {
client_core::init::setup_gateway(
register_gateway,
user_chosen_gateway_id,
config.get_base(),
)
.await
.unwrap_or_else(|err| {
eprintln!("Failed to setup gateway\nError: {err}");
std::process::exit(1)
});
}
.unwrap_or_else(|err| {
eprintln!("Failed to setup gateway\nError: {err}");
std::process::exit(1)
});
config.get_base_mut().with_gateway_endpoint(gateway);
let config_save_location = config.get_config_file_save_location();
@@ -180,45 +188,11 @@ pub(crate) async fn execute(args: &Init) {
}
}
async fn setup_gateway(
id: &str,
register: bool,
user_chosen_gateway_id: Option<&str>,
config: &Config,
) -> Result<GatewayEndpointConfig, ClientCoreError> {
if register {
// Get the gateway details by querying the validator-api. Either pick one at random or use
// the chosen one if it's among the available ones.
println!("Configuring gateway");
let gateway = client_core::init::query_gateway_details(
config.get_base().get_validator_api_endpoints(),
user_chosen_gateway_id,
)
.await?;
log::debug!("Querying gateway gives: {}", gateway);
// Registering with gateway by setting up and writing shared keys to disk
log::trace!("Registering gateway");
client_core::init::register_with_gateway_and_store_keys(gateway.clone(), config.get_base())
.await?;
println!("Saved all generated keys");
Ok(gateway.into())
} else if user_chosen_gateway_id.is_some() {
// Just set the config, don't register or create any keys
// This assumes that the user knows what they are doing, and that the existing keys are
// valid for the gateway being used
println!("Using gateway provided by user, keeping existing keys");
let gateway = client_core::init::query_gateway_details(
config.get_base().get_validator_api_endpoints(),
user_chosen_gateway_id,
)
.await?;
log::debug!("Querying gateway gives: {}", gateway);
Ok(gateway.into())
} else {
println!("Not registering gateway, will reuse existing config and keys");
let existing_config = Config::load_from_file(Some(id)).map_err(|err| {
fn reuse_gateway_config(id: &str) -> Result<GatewayEndpointConfig, ClientCoreError> {
println!("Not registering gateway, will reuse existing config and keys");
Config::load_from_file(Some(id))
.map(|existing_config| existing_config.get_base().get_gateway_endpoint().clone())
.map_err(|err| {
log::error!(
"Unable to configure gateway: {err}. \n
Seems like the client was already initialized but it was not possible to read \
@@ -227,8 +201,5 @@ async fn setup_gateway(
removing the existing configuration and starting over."
);
ClientCoreError::CouldNotLoadExistingGatewayConfiguration(err)
})?;
Ok(existing_config.get_base().get_gateway_endpoint().clone())
}
})
}
+19 -47
View File
@@ -133,12 +133,20 @@ pub(crate) async fn execute(args: &Init) {
let override_config_fields = OverrideConfig::from(args.clone());
config = override_config(config, override_config_fields);
let gateway = setup_gateway(id, register_gateway, user_chosen_gateway_id, &config)
let gateway = if !register_gateway && user_chosen_gateway_id.is_none() {
reuse_gateway_config(id)
} else {
client_core::init::setup_gateway(
register_gateway,
user_chosen_gateway_id,
config.get_base(),
)
.await
.unwrap_or_else(|err| {
eprintln!("Failed to setup gateway\nError: {err}");
std::process::exit(1)
});
}
.unwrap_or_else(|err| {
eprintln!("Failed to setup gateway\nError: {err}");
std::process::exit(1)
});
config.get_base_mut().with_gateway_endpoint(gateway);
let config_save_location = config.get_config_file_save_location();
@@ -179,45 +187,11 @@ pub(crate) async fn execute(args: &Init) {
println!("\nThe address of this client is: {}\n", address);
}
async fn setup_gateway(
id: &str,
register: bool,
user_chosen_gateway_id: Option<&str>,
config: &Config,
) -> Result<GatewayEndpointConfig, ClientCoreError> {
if register {
// Get the gateway details by querying the validator-api. Either pick one at random or use
// the chosen one if it's among the available ones.
println!("Configuring gateway");
let gateway = client_core::init::query_gateway_details(
config.get_base().get_validator_api_endpoints(),
user_chosen_gateway_id,
)
.await?;
log::debug!("Querying gateway gives: {}", gateway);
// Registering with gateway by setting up and writing shared keys to disk
log::trace!("Registering gateway");
client_core::init::register_with_gateway_and_store_keys(gateway.clone(), config.get_base())
.await?;
println!("Saved all generated keys");
Ok(gateway.into())
} else if user_chosen_gateway_id.is_some() {
// Just set the config, don't register or create any keys
// This assumes that the user knows what they are doing, and that the existing keys are
// valid for the gateway being used
println!("Using gateway provided by user, keeping existing keys");
let gateway = client_core::init::query_gateway_details(
config.get_base().get_validator_api_endpoints(),
user_chosen_gateway_id,
)
.await?;
log::debug!("Querying gateway gives: {}", gateway);
Ok(gateway.into())
} else {
println!("Not registering gateway, will reuse existing config and keys");
let existing_config = Config::load_from_file(Some(id)).map_err(|err| {
fn reuse_gateway_config(id: &str) -> Result<GatewayEndpointConfig, ClientCoreError> {
println!("Not registering gateway, will reuse existing config and keys");
Config::load_from_file(Some(id))
.map(|existing_config| existing_config.get_base().get_gateway_endpoint().clone())
.map_err(|err| {
log::error!(
"Unable to configure gateway: {err}. \n
Seems like the client was already initialized but it was not possible to read \
@@ -226,7 +200,5 @@ async fn setup_gateway(
removing the existing configuration and starting over."
);
ClientCoreError::CouldNotLoadExistingGatewayConfiguration(err)
})?;
Ok(existing_config.get_base().get_gateway_endpoint().clone())
}
})
}
+15 -63
View File
@@ -1,6 +1,5 @@
use std::path::PathBuf;
use client_core::config::GatewayEndpointConfig;
use std::sync::Arc;
use tap::TapFallible;
use tokio::sync::RwLock;
@@ -127,21 +126,31 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str
.set_custom_validator_apis(config_common::parse_validators(&raw_validators));
}
let gateway = setup_gateway(
&id,
let gateway = client_core::init::setup_gateway(
register_gateway,
Some(&chosen_gateway_id),
config.get_socks5(),
config.get_base(),
)
.await?;
config.get_base_mut().with_gateway_endpoint(gateway);
let config_save_location = config.get_socks5().get_config_file_save_location();
config.get_socks5().save_to_file(None).tap_err(|_| {
log::error!("Failed to save the config file");
})?;
log::info!("Saved configuration file to {:?}", config_save_location);
print_save_config(&config);
let address = client_core::init::get_client_address(config.get_base())?;
log::info!("The address of this client is: {}", address);
Ok(())
}
fn print_save_config(config: &Config) {
log::info!(
"Saved configuration file to {:?}",
config.get_socks5().get_config_file_save_location()
);
log::info!("Gateway id: {}", config.get_base().get_gateway_id());
log::info!("Gateway owner: {}", config.get_base().get_gateway_owner());
log::info!(
@@ -158,61 +167,4 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str
config.get_socks5().get_listening_port()
);
log::info!("Client configuration completed.");
let address = client_core::init::get_client_address(config.get_base())?;
println!("\nThe address of this client is: {}\n", address);
Ok(())
}
// TODO: deduplicate with same functions in other client
async fn setup_gateway(
id: &str,
register: bool,
user_chosen_gateway_id: Option<&str>,
config: &Socks5Config,
) -> Result<GatewayEndpointConfig> {
if register {
// Get the gateway details by querying the validator-api. Either pick one at random or use
// the chosen one if it's among the available ones.
println!("Configuring gateway");
let gateway = client_core::init::query_gateway_details(
config.get_base().get_validator_api_endpoints(),
user_chosen_gateway_id,
)
.await?;
log::debug!("Querying gateway gives: {}", gateway);
// Registering with gateway by setting up and writing shared keys to disk
log::trace!("Registering gateway");
client_core::init::register_with_gateway_and_store_keys(gateway.clone(), config.get_base())
.await?;
println!("Saved all generated keys");
Ok(gateway.into())
} else if user_chosen_gateway_id.is_some() {
// Just set the config, don't register or create any keys
// This assumes that the user knows what they are doing, and that the existing keys are
// valid for the gateway being used
println!("Using gateway provided by user, keeping existing keys");
let gateway = client_core::init::query_gateway_details(
config.get_base().get_validator_api_endpoints(),
user_chosen_gateway_id,
)
.await?;
log::debug!("Querying gateway gives: {}", gateway);
Ok(gateway.into())
} else {
println!("Not registering gateway, will reuse existing config and keys");
let existing_config = Socks5Config::load_from_file(Some(id)).map_err(|err| {
log::error!(
"Unable to configure gateway: {err}. \n
Seems like the client was already initialized but it was not possible to read \
the existing configuration file. \n
CAUTION: Consider backing up your gateway keys and try force gateway registration, or \
removing the existing configuration and starting over."
);
BackendError::CouldNotLoadExistingGatewayConfiguration(err)
})?;
Ok(existing_config.get_base().get_gateway_endpoint().clone())
}
}