diff options
| author | Markus Pettersson <markus.pettersson@mullvad.net> | 2023-09-11 15:20:20 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2023-10-09 14:40:03 +0200 |
| commit | c899c1b63858c12c9367318c19120fe899b31394 (patch) | |
| tree | 746ac544c0a7aa35fb6cd9275efd9328deecd7e9 /mullvad-cli/src/cmds | |
| parent | 411f80d4cd227686a57e9dcc39dd30a01f728575 (diff) | |
| download | mullvadvpn-c899c1b63858c12c9367318c19120fe899b31394.tar.xz mullvadvpn-c899c1b63858c12c9367318c19120fe899b31394.zip | |
Add `mullvad proxy api edit` command
Allow a user to edit an existing custom api proxy method
Diffstat (limited to 'mullvad-cli/src/cmds')
| -rw-r--r-- | mullvad-cli/src/cmds/proxy.rs | 106 |
1 files changed, 100 insertions, 6 deletions
diff --git a/mullvad-cli/src/cmds/proxy.rs b/mullvad-cli/src/cmds/proxy.rs index 583accef1e..5a4bf2fdd8 100644 --- a/mullvad-cli/src/cmds/proxy.rs +++ b/mullvad-cli/src/cmds/proxy.rs @@ -1,6 +1,6 @@ use anyhow::{anyhow, Result}; use mullvad_management_interface::MullvadProxyClient; -use mullvad_types::api_access_method::AccessMethod; +use mullvad_types::api_access_method::{AccessMethod, ApiAccessMethodReplace}; use std::net::IpAddr; use clap::{Args, Subcommand}; @@ -25,13 +25,15 @@ impl Proxy { //println!("Adding custom proxy"); Self::add(cmd).await?; } - ApiCommands::Edit(_) => todo!(), + ApiCommands::Edit(cmd) => { + // Transform human-readable index to 0-based indexing. + let index = Self::zero_to_one_based_index(cmd.index)?; + Self::edit(EditCustomCommands { index, ..cmd }).await? + } ApiCommands::Remove(cmd) => { // Transform human-readable index to 0-based indexing. - match cmd.index.checked_sub(1) { - Some(index) => Self::remove(RemoveCustomCommands { index, ..cmd }).await?, - None => println!("Access method 0 does not exist"), - } + let index = Self::zero_to_one_based_index(cmd.index)?; + Self::remove(RemoveCustomCommands { index }).await? } }, }; @@ -71,6 +73,65 @@ impl Proxy { .await .map_err(Into::<anyhow::Error>::into) } + + async fn edit(cmd: EditCustomCommands) -> Result<()> { + let mut rpc = MullvadProxyClient::new().await?; + // Retrieve the access method to edit + let access_method = rpc + .get_api_access_methods() + .await? + .get(cmd.index) + .ok_or(anyhow!(format!( + "Access method {} does not exist", + cmd.index + 1 + )))? + .clone(); + + // Create a new access method combining the new params with the previous values + let edited_access_method: AccessMethod = match access_method { + AccessMethod::Shadowsocks(shadowsocks) => { + let ip = cmd.params.ip.unwrap_or(shadowsocks.peer.ip()).to_string(); + let port = cmd.params.port.unwrap_or(shadowsocks.peer.port()); + let password = cmd.params.password.unwrap_or(shadowsocks.password); + let cipher = cmd.params.cipher.unwrap_or(shadowsocks.cipher); + mullvad_types::api_access_method::Shadowsocks::from_args(ip, port, cipher, password) + .map(|x| x.into()) + } + AccessMethod::Socks5(socks) => match socks { + mullvad_types::api_access_method::Socks5::Local(local) => { + let ip = cmd.params.ip.unwrap_or(local.peer.ip()).to_string(); + let port = cmd.params.port.unwrap_or(local.peer.port()); + let local_port = cmd.params.local_port.unwrap_or(local.port); + mullvad_types::api_access_method::Socks5Local::from_args(ip, port, local_port) + .map(|x| x.into()) + } + mullvad_types::api_access_method::Socks5::Remote(remote) => { + let ip = cmd.params.ip.unwrap_or(remote.peer.ip()).to_string(); + let port = cmd.params.port.unwrap_or(remote.peer.port()); + mullvad_types::api_access_method::Socks5Remote::from_args(ip, port) + .map(|x| x.into()) + } + }, + } + .ok_or(anyhow!( + "Could not edit access method {}, reverting changes.", + cmd.index + ))?; + + rpc.replace_access_method(ApiAccessMethodReplace { + index: cmd.index, + access_method: edited_access_method, + }) + .await?; + + Ok(()) + } + + fn zero_to_one_based_index(index: usize) -> Result<usize> { + index + .checked_sub(1) + .ok_or(anyhow!("Access method 0 does not exist")) + } } #[derive(Subcommand, Debug, Clone)] @@ -80,6 +141,8 @@ pub enum ApiCommands { /// Add a custom API proxy #[clap(subcommand)] Add(AddCustomCommands), + /// Edit an API proxy + Edit(EditCustomCommands), /// Remove an API proxy Remove(RemoveCustomCommands), } @@ -107,6 +170,15 @@ pub enum AddCustomCommands { } #[derive(Args, Debug, Clone)] +pub struct EditCustomCommands { + /// Which API proxy to edit + index: usize, + /// Editing parameters + #[clap(flatten)] + params: EditParams, +} + +#[derive(Args, Debug, Clone)] pub struct RemoveCustomCommands { /// Which API proxy to remove index: usize, @@ -138,6 +210,28 @@ pub enum Socks5AddCommands { }, } +#[derive(Args, Debug, Clone)] +pub struct EditParams { + /// Username for authentication [Shadowsocks] + #[arg(long)] + username: Option<String>, + /// Password for authentication [Shadowsocks] + #[arg(long)] + password: Option<String>, + /// Cipher to use [Shadowsocks] + #[arg(value_parser = SHADOWSOCKS_CIPHERS, long)] + cipher: Option<String>, + /// The IP of the remote proxy server [Socks5 (Local & Remote proxy), Shadowsocks] + #[arg(long)] + ip: Option<IpAddr>, + /// The port of the remote proxy server [Socks5 (Local & Remote proxy), Shadowsocks] + #[arg(long)] + port: Option<u16>, + /// The port that the server on localhost is listening on [Socks5 (Local proxy)] + #[arg(long)] + local_port: Option<u16>, +} + /// Implement conversions from CLI types to Daemon types. /// /// Since these are not supposed to be used outside of the CLI, |
