From 062f4517d6b92ed0ff0b288355866cc8d29f2da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 12 Mar 2024 13:19:08 +0000 Subject: [PATCH] added cli command for switching active gateway --- clients/native/src/commands/mod.rs | 5 +++ clients/native/src/commands/switch_gateway.rs | 24 +++++++++++++ clients/socks5/src/commands/mod.rs | 5 +++ clients/socks5/src/commands/switch_gateway.rs | 24 +++++++++++++ .../src/backend/fs_backend/error.rs | 3 ++ .../src/backend/fs_backend/manager.rs | 10 ++++++ .../src/backend/fs_backend/mod.rs | 5 +++ .../src/cli_helpers/client_switch_gateway.rs | 35 +++++++++++++++++++ .../ip-packet-router/src/cli/mod.rs | 5 +++ .../src/cli/switch_gateway.rs | 24 +++++++++++++ .../network-requester/src/cli/mod.rs | 5 +++ .../src/cli/switch_gateway.rs | 24 +++++++++++++ 12 files changed, 169 insertions(+) create mode 100644 clients/native/src/commands/switch_gateway.rs create mode 100644 clients/socks5/src/commands/switch_gateway.rs create mode 100644 service-providers/ip-packet-router/src/cli/switch_gateway.rs create mode 100644 service-providers/network-requester/src/cli/switch_gateway.rs diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index b13a09877d..9c7c016580 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -25,6 +25,7 @@ pub(crate) mod import_credential; pub(crate) mod init; mod list_gateways; pub(crate) mod run; +mod switch_gateway; pub(crate) struct CliNativeClient; @@ -76,6 +77,9 @@ pub(crate) enum Commands { /// List all registered with gateways ListGateways(list_gateways::Args), + /// Change the currently active gateway. Note that you must have already registered with the new gateway! + SwitchGateway(switch_gateway::Args), + /// Show build information of this binary BuildInfo(build_info::BuildInfo), @@ -106,6 +110,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), Box run::execute(m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::ListGateways(args) => list_gateways::execute(args).await?, + Commands::SwitchGateway(args) => switch_gateway::execute(args).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), diff --git a/clients/native/src/commands/switch_gateway.rs b/clients/native/src/commands/switch_gateway.rs new file mode 100644 index 0000000000..f7dbcfa65d --- /dev/null +++ b/clients/native/src/commands/switch_gateway.rs @@ -0,0 +1,24 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::commands::CliNativeClient; +use crate::error::ClientError; +use nym_client_core::cli_helpers::client_switch_gateway::{ + switch_gateway, CommonClientSwitchGatewaysArgs, +}; + +#[derive(clap::Args, Clone, Debug)] +pub struct Args { + #[command(flatten)] + common_args: CommonClientSwitchGatewaysArgs, +} + +impl AsRef for Args { + fn as_ref(&self) -> &CommonClientSwitchGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), ClientError> { + switch_gateway::(args).await +} diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index d60b9a8574..d982b86a9e 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -29,6 +29,7 @@ mod import_credential; pub mod init; mod list_gateways; pub(crate) mod run; +mod switch_gateway; pub(crate) struct CliSocks5Client; @@ -80,6 +81,9 @@ pub(crate) enum Commands { /// List all registered with gateways ListGateways(list_gateways::Args), + /// Change the currently active gateway. Note that you must have already registered with the new gateway! + SwitchGateway(switch_gateway::Args), + /// Show build information of this binary BuildInfo(build_info::BuildInfo), @@ -113,6 +117,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), Box run::execute(m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::ListGateways(args) => list_gateways::execute(args).await?, + Commands::SwitchGateway(args) => switch_gateway::execute(args).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), diff --git a/clients/socks5/src/commands/switch_gateway.rs b/clients/socks5/src/commands/switch_gateway.rs new file mode 100644 index 0000000000..6b24fbb6a3 --- /dev/null +++ b/clients/socks5/src/commands/switch_gateway.rs @@ -0,0 +1,24 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::commands::CliSocks5Client; +use crate::error::Socks5ClientError; +use nym_client_core::cli_helpers::client_switch_gateway::{ + switch_gateway, CommonClientSwitchGatewaysArgs, +}; + +#[derive(clap::Args, Clone, Debug)] +pub struct Args { + #[command(flatten)] + common_args: CommonClientSwitchGatewaysArgs, +} + +impl AsRef for Args { + fn as_ref(&self) -> &CommonClientSwitchGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), Socks5ClientError> { + switch_gateway::(args).await +} diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/error.rs b/common/client-core/gateways-storage/src/backend/fs_backend/error.rs index 44cab38a8c..bdcaa0fdb5 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/error.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/error.rs @@ -39,4 +39,7 @@ pub enum StorageError { #[error(transparent)] MalformedGateway(#[from] BadGateway), + + #[error("gateway {gateway_id} does not exist in the storage")] + GatewayDoesNotExist { gateway_id: String }, } diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs index 965ace23f6..58cb451d97 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs @@ -75,6 +75,16 @@ impl StorageManager { Ok(()) } + pub(crate) async fn has_registered_gateway( + &self, + gateway_id: &str, + ) -> Result { + sqlx::query!("SELECT EXISTS (SELECT 1 FROM registered_gateway WHERE gateway_id_bs58 = ?) AS 'exists'", gateway_id) + .fetch_one(&self.connection_pool) + .await + .map(|result| result.exists == 1) + } + pub(crate) async fn maybe_get_registered_gateway( &self, gateway_id: &str, diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs index 7e0fbcdebc..0b93d284f6 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs @@ -49,6 +49,11 @@ impl GatewaysDetailsStore for OnDiskGatewaysDetails { } async fn set_active_gateway(&self, gateway_id: &str) -> Result<(), Self::StorageError> { + if !self.manager.has_registered_gateway(gateway_id).await? { + return Err(StorageError::GatewayDoesNotExist { + gateway_id: gateway_id.to_string(), + }); + } Ok(self.manager.set_active_gateway(Some(gateway_id)).await?) } diff --git a/common/client-core/src/cli_helpers/client_switch_gateway.rs b/common/client-core/src/cli_helpers/client_switch_gateway.rs index 755fb6cc8b..0468575e63 100644 --- a/common/client-core/src/cli_helpers/client_switch_gateway.rs +++ b/common/client-core/src/cli_helpers/client_switch_gateway.rs @@ -1,2 +1,37 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 + +use crate::cli_helpers::{CliClient, CliClientConfig}; +use crate::client::base_client::non_wasm_helpers::setup_fs_gateways_storage; +use crate::client::base_client::storage::helpers::set_active_gateway; +use nym_crypto::asymmetric::identity; + +#[cfg_attr(feature = "cli", derive(clap::Args))] +#[derive(Debug, Clone)] +pub struct CommonClientSwitchGatewaysArgs { + /// Id of client we want to list gateways for. + #[cfg_attr(feature = "cli", clap(long))] + pub id: String, + + /// Id of the gateway we want to switch to. + #[cfg_attr(feature = "cli", clap(long))] + pub gateway_id: identity::PublicKey, +} + +pub async fn switch_gateway(args: A) -> Result<(), C::Error> +where + A: AsRef, + C: CliClient, +{ + let common_args = args.as_ref(); + let id = &common_args.id; + + let config = C::try_load_current_config(id).await?; + let paths = config.common_paths(); + + let details_store = setup_fs_gateways_storage(&paths.gateway_registrations).await?; + + set_active_gateway(&details_store, &common_args.gateway_id.to_base58_string()).await?; + + Ok(()) +} diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index da35a12add..dc04d7e3cb 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -16,6 +16,7 @@ mod init; mod list_gateways; mod run; mod sign; +mod switch_gateway; pub(crate) struct CliIpPacketRouterClient; @@ -69,6 +70,9 @@ pub(crate) enum Commands { /// List all registered with gateways ListGateways(list_gateways::Args), + /// Change the currently active gateway. Note that you must have already registered with the new gateway! + SwitchGateway(switch_gateway::Args), + /// Sign to prove ownership of this network requester Sign(sign::Sign), @@ -123,6 +127,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), IpPacketRouterError> { Commands::Run(m) => run::execute(&m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::ListGateways(args) => list_gateways::execute(args).await?, + Commands::SwitchGateway(args) => switch_gateway::execute(args).await?, Commands::Sign(m) => sign::execute(&m).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), diff --git a/service-providers/ip-packet-router/src/cli/switch_gateway.rs b/service-providers/ip-packet-router/src/cli/switch_gateway.rs new file mode 100644 index 0000000000..4a365a4bdb --- /dev/null +++ b/service-providers/ip-packet-router/src/cli/switch_gateway.rs @@ -0,0 +1,24 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::cli::CliIpPacketRouterClient; +use nym_client_core::cli_helpers::client_switch_gateway::{ + switch_gateway, CommonClientSwitchGatewaysArgs, +}; +use nym_ip_packet_router::error::IpPacketRouterError; + +#[derive(clap::Args, Clone, Debug)] +pub struct Args { + #[command(flatten)] + common_args: CommonClientSwitchGatewaysArgs, +} + +impl AsRef for Args { + fn as_ref(&self) -> &CommonClientSwitchGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), IpPacketRouterError> { + switch_gateway::(args).await +} diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index e721d38614..29057aa523 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -26,6 +26,7 @@ mod init; mod list_gateways; mod run; mod sign; +mod switch_gateway; pub(crate) struct CliNetworkRequesterClient; @@ -82,6 +83,9 @@ pub(crate) enum Commands { /// List all registered with gateways ListGateways(list_gateways::Args), + /// Change the currently active gateway. Note that you must have already registered with the new gateway! + SwitchGateway(switch_gateway::Args), + /// Show build information of this binary BuildInfo(build_info::BuildInfo), @@ -178,6 +182,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), NetworkRequesterError> { Commands::Sign(m) => sign::execute(&m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::ListGateways(args) => list_gateways::execute(args).await?, + Commands::SwitchGateway(args) => switch_gateway::execute(args).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), diff --git a/service-providers/network-requester/src/cli/switch_gateway.rs b/service-providers/network-requester/src/cli/switch_gateway.rs new file mode 100644 index 0000000000..7496fc0018 --- /dev/null +++ b/service-providers/network-requester/src/cli/switch_gateway.rs @@ -0,0 +1,24 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::cli::CliNetworkRequesterClient; +use crate::error::NetworkRequesterError; +use nym_client_core::cli_helpers::client_switch_gateway::{ + switch_gateway, CommonClientSwitchGatewaysArgs, +}; + +#[derive(clap::Args, Clone, Debug)] +pub struct Args { + #[command(flatten)] + common_args: CommonClientSwitchGatewaysArgs, +} + +impl AsRef for Args { + fn as_ref(&self) -> &CommonClientSwitchGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), NetworkRequesterError> { + switch_gateway::(args).await +}