Removed redundant remoteOpts struct; use FileTransferParams only

This commit is contained in:
veeso
2021-07-23 14:31:29 +02:00
parent c722982c39
commit f36bb65b45
6 changed files with 75 additions and 164 deletions

View File

@@ -26,7 +26,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
// Deps // Deps
use crate::filetransfer::FileTransferProtocol; use crate::filetransfer::{FileTransferParams, FileTransferProtocol};
use crate::host::{HostError, Localhost}; use crate::host::{HostError, Localhost};
use crate::system::config_client::ConfigClient; use crate::system::config_client::ConfigClient;
use crate::system::environment; use crate::system::environment;
@@ -35,7 +35,7 @@ use crate::ui::activities::{
auth::AuthActivity, filetransfer::FileTransferActivity, setup::SetupActivity, Activity, auth::AuthActivity, filetransfer::FileTransferActivity, setup::SetupActivity, Activity,
ExitReason, ExitReason,
}; };
use crate::ui::context::{Context, FileTransferParams}; use crate::ui::context::Context;
// Namespaces // Namespaces
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@@ -87,27 +87,9 @@ impl ActivityManager {
/// ### set_filetransfer_params /// ### set_filetransfer_params
/// ///
/// Set file transfer params /// Set file transfer params
pub fn set_filetransfer_params( pub fn set_filetransfer_params(&mut self, params: FileTransferParams) {
&mut self,
address: String,
port: u16,
protocol: FileTransferProtocol,
username: Option<String>,
password: Option<String>,
entry_directory: Option<PathBuf>,
) {
// Put params into the context // Put params into the context
self.context self.context.as_mut().unwrap().set_ftparams(params);
.as_mut()
.unwrap()
.set_ftparams(FileTransferParams {
address,
port,
protocol,
username,
password,
entry_directory,
});
} }
/// ### run /// ### run

View File

@@ -34,9 +34,12 @@ use thiserror::Error;
use wildmatch::WildMatch; use wildmatch::WildMatch;
// exports // exports
pub mod ftp_transfer; pub mod ftp_transfer;
pub mod params;
pub mod scp_transfer; pub mod scp_transfer;
pub mod sftp_transfer; pub mod sftp_transfer;
pub use params::FileTransferParams;
/// ## FileTransferProtocol /// ## FileTransferProtocol
/// ///
/// This enum defines the different transfer protocol available in termscp /// This enum defines the different transfer protocol available in termscp

View File

@@ -56,7 +56,7 @@ mod utils;
// namespaces // namespaces
use activity_manager::{ActivityManager, NextActivity}; use activity_manager::{ActivityManager, NextActivity};
use filetransfer::FileTransferProtocol; use filetransfer::FileTransferParams;
use system::logging; use system::logging;
enum Task { enum Task {
@@ -97,12 +97,7 @@ struct Args {
} }
struct RunOpts { struct RunOpts {
address: Option<String>, remote: Option<FileTransferParams>,
port: u16,
username: Option<String>,
password: Option<String>,
remote_wrkdir: Option<PathBuf>,
protocol: FileTransferProtocol,
ticks: Duration, ticks: Duration,
log_enabled: bool, log_enabled: bool,
task: Task, task: Task,
@@ -111,12 +106,7 @@ struct RunOpts {
impl Default for RunOpts { impl Default for RunOpts {
fn default() -> Self { fn default() -> Self {
Self { Self {
address: None, remote: None,
port: 22,
username: None,
password: None,
remote_wrkdir: None,
protocol: FileTransferProtocol::Sftp,
ticks: Duration::from_millis(10), ticks: Duration::from_millis(10),
log_enabled: true, log_enabled: true,
task: Task::Activity(NextActivity::Authentication), task: Task::Activity(NextActivity::Authentication),
@@ -176,10 +166,6 @@ fn parse_args(args: Args) -> Result<RunOpts, String> {
if args.quiet { if args.quiet {
run_opts.log_enabled = false; run_opts.log_enabled = false;
} }
// Match password
if let Some(passwd) = args.password {
run_opts.password = Some(passwd);
}
// Match ticks // Match ticks
run_opts.ticks = Duration::from_millis(args.ticks); run_opts.ticks = Duration::from_millis(args.ticks);
// @! extra modes // @! extra modes
@@ -191,13 +177,13 @@ fn parse_args(args: Args) -> Result<RunOpts, String> {
if let Some(remote) = args.positional.get(0) { if let Some(remote) = args.positional.get(0) {
// Parse address // Parse address
match utils::parser::parse_remote_opt(remote.as_str()) { match utils::parser::parse_remote_opt(remote.as_str()) {
Ok(host_opts) => { Ok(mut remote) => {
// If password is provided, set password
if let Some(passwd) = args.password {
remote = remote.password(Some(passwd));
}
// Set params // Set params
run_opts.address = Some(host_opts.hostname); run_opts.remote = Some(remote);
run_opts.port = host_opts.port;
run_opts.protocol = host_opts.protocol;
run_opts.username = host_opts.username;
run_opts.remote_wrkdir = host_opts.wrkdir;
// In this case the first activity will be FileTransfer // In this case the first activity will be FileTransfer
run_opts.task = Task::Activity(NextActivity::FileTransfer); run_opts.task = Task::Activity(NextActivity::FileTransfer);
} }
@@ -222,11 +208,11 @@ fn parse_args(args: Args) -> Result<RunOpts, String> {
/// Read password from tty if address is specified /// Read password from tty if address is specified
fn read_password(run_opts: &mut RunOpts) -> Result<(), String> { fn read_password(run_opts: &mut RunOpts) -> Result<(), String> {
// Initialize client if necessary // Initialize client if necessary
if run_opts.address.is_some() { if let Some(remote) = run_opts.remote.as_mut() {
debug!("User has specified remote options: address: {:?}, port: {:?}, protocol: {:?}, user: {:?}, password: {}", run_opts.address, run_opts.port, run_opts.protocol, run_opts.username, utils::fmt::shadow_password(run_opts.password.as_deref().unwrap_or(""))); debug!("User has specified remote options: address: {:?}, port: {:?}, protocol: {:?}, user: {:?}, password: {}", remote.address, remote.port, remote.protocol, remote.username, utils::fmt::shadow_password(remote.password.as_deref().unwrap_or("")));
if run_opts.password.is_none() { if remote.password.is_none() {
// Ask password if unspecified // Ask password if unspecified
run_opts.password = match rpassword::read_password_from_tty(Some("Password: ")) { remote.password = match rpassword::read_password_from_tty(Some("Password: ")) {
Ok(p) => { Ok(p) => {
if p.is_empty() { if p.is_empty() {
None None
@@ -278,15 +264,8 @@ fn run(mut run_opts: RunOpts) -> i32 {
} }
}; };
// Set file transfer params if set // Set file transfer params if set
if let Some(address) = run_opts.address.take() { if let Some(remote) = run_opts.remote.take() {
manager.set_filetransfer_params( manager.set_filetransfer_params(remote);
address,
run_opts.port,
run_opts.protocol,
run_opts.username,
run_opts.password,
run_opts.remote_wrkdir,
);
} }
manager.run(activity); manager.run(activity);
0 0

View File

@@ -34,9 +34,8 @@ mod view;
// locals // locals
use super::{Activity, Context, ExitReason}; use super::{Activity, Context, ExitReason};
use crate::config::themes::Theme; use crate::config::themes::Theme;
use crate::filetransfer::FileTransferProtocol; use crate::filetransfer::{FileTransferParams, FileTransferProtocol};
use crate::system::bookmarks_client::BookmarksClient; use crate::system::bookmarks_client::BookmarksClient;
use crate::ui::context::FileTransferParams;
use crate::utils::git; use crate::utils::git;
// Includes // Includes

View File

@@ -28,7 +28,7 @@
// Locals // Locals
use super::input::InputHandler; use super::input::InputHandler;
use super::store::Store; use super::store::Store;
use crate::filetransfer::FileTransferProtocol; use crate::filetransfer::FileTransferParams;
use crate::system::config_client::ConfigClient; use crate::system::config_client::ConfigClient;
use crate::system::theme_provider::ThemeProvider; use crate::system::theme_provider::ThemeProvider;
@@ -37,7 +37,6 @@ use crossterm::event::DisableMouseCapture;
use crossterm::execute; use crossterm::execute;
use crossterm::terminal::{EnterAlternateScreen, LeaveAlternateScreen}; use crossterm::terminal::{EnterAlternateScreen, LeaveAlternateScreen};
use std::io::{stdout, Stdout}; use std::io::{stdout, Stdout};
use std::path::PathBuf;
use tuirealm::tui::backend::CrosstermBackend; use tuirealm::tui::backend::CrosstermBackend;
use tuirealm::tui::Terminal; use tuirealm::tui::Terminal;
@@ -56,19 +55,6 @@ pub struct Context {
error: Option<String>, error: Option<String>,
} }
/// ### FileTransferParams
///
/// Holds connection parameters for file transfers
#[derive(Clone)]
pub struct FileTransferParams {
pub address: String,
pub port: u16,
pub protocol: FileTransferProtocol,
pub username: Option<String>,
pub password: Option<String>,
pub entry_directory: Option<PathBuf>,
}
impl Context { impl Context {
/// ### new /// ### new
/// ///
@@ -198,34 +184,3 @@ impl Drop for Context {
self.leave_alternate_screen(); self.leave_alternate_screen();
} }
} }
impl Default for FileTransferParams {
fn default() -> Self {
Self {
address: String::new(),
port: 22,
protocol: FileTransferProtocol::Sftp,
username: None,
password: None,
entry_directory: None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn test_ui_context_ft_params() {
let params: FileTransferParams = FileTransferParams::default();
assert_eq!(params.address.as_str(), "");
assert_eq!(params.port, 22);
assert_eq!(params.protocol, FileTransferProtocol::Sftp);
assert!(params.username.is_none());
assert!(params.password.is_none());
}
}

View File

@@ -26,7 +26,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
// Locals // Locals
use crate::filetransfer::FileTransferProtocol; use crate::filetransfer::{FileTransferParams, FileTransferProtocol};
#[cfg(not(test))] // NOTE: don't use configuration during tests #[cfg(not(test))] // NOTE: don't use configuration during tests
use crate::system::config_client::ConfigClient; use crate::system::config_client::ConfigClient;
#[cfg(not(test))] // NOTE: don't use configuration during tests #[cfg(not(test))] // NOTE: don't use configuration during tests
@@ -75,14 +75,6 @@ lazy_static! {
static ref COLOR_RGB_REGEX: Regex = Regex::new(r"^(rgb)?\(?([01]?\d\d?|2[0-4]\d|25[0-5])(\W+)([01]?\d\d?|2[0-4]\d|25[0-5])\W+(([01]?\d\d?|2[0-4]\d|25[0-5])\)?)").unwrap(); static ref COLOR_RGB_REGEX: Regex = Regex::new(r"^(rgb)?\(?([01]?\d\d?|2[0-4]\d|25[0-5])(\W+)([01]?\d\d?|2[0-4]\d|25[0-5])\W+(([01]?\d\d?|2[0-4]\d|25[0-5])\)?)").unwrap();
} }
pub struct RemoteOptions {
pub hostname: String,
pub port: u16,
pub protocol: FileTransferProtocol,
pub username: Option<String>,
pub wrkdir: Option<PathBuf>,
}
/// ### parse_remote_opt /// ### parse_remote_opt
/// ///
/// Parse remote option string. Returns in case of success a RemoteOptions struct /// Parse remote option string. Returns in case of success a RemoteOptions struct
@@ -101,8 +93,7 @@ pub struct RemoteOptions {
/// - sftp://172.26.104.1:4022 /// - sftp://172.26.104.1:4022
/// - sftp://172.26.104.1 /// - sftp://172.26.104.1
/// - ... /// - ...
/// pub fn parse_remote_opt(remote: &str) -> Result<FileTransferParams, String> {
pub fn parse_remote_opt(remote: &str) -> Result<RemoteOptions, String> {
// Set protocol to default protocol // Set protocol to default protocol
#[cfg(not(test))] // NOTE: don't use configuration during tests #[cfg(not(test))] // NOTE: don't use configuration during tests
let mut protocol: FileTransferProtocol = match environment::init_config_dir() { let mut protocol: FileTransferProtocol = match environment::init_config_dir() {
@@ -152,7 +143,7 @@ pub fn parse_remote_opt(remote: &str) -> Result<RemoteOptions, String> {
}, },
}; };
// Get address // Get address
let hostname: String = match groups.get(3) { let address: String = match groups.get(3) {
Some(group) => group.as_str().to_string(), Some(group) => group.as_str().to_string(),
None => return Err(String::from("Missing address")), None => return Err(String::from("Missing address")),
}; };
@@ -164,14 +155,13 @@ pub fn parse_remote_opt(remote: &str) -> Result<RemoteOptions, String> {
}; };
} }
// Get workdir // Get workdir
let wrkdir: Option<PathBuf> = groups.get(5).map(|group| PathBuf::from(group.as_str())); let entry_directory: Option<PathBuf> =
Ok(RemoteOptions { groups.get(5).map(|group| PathBuf::from(group.as_str()));
hostname, Ok(FileTransferParams::new(address)
port, .port(port)
protocol, .protocol(protocol)
username, .username(username)
wrkdir, .entry_directory(entry_directory))
})
} }
None => Err(String::from("Bad remote host syntax!")), None => Err(String::from("Bad remote host syntax!")),
} }
@@ -476,107 +466,110 @@ mod tests {
#[test] #[test]
fn test_utils_parse_remote_opt() { fn test_utils_parse_remote_opt() {
// Base case // Base case
let result: RemoteOptions = parse_remote_opt(&String::from("172.26.104.1")) let result: FileTransferParams = parse_remote_opt(&String::from("172.26.104.1"))
.ok() .ok()
.unwrap(); .unwrap();
assert_eq!(result.hostname, String::from("172.26.104.1")); assert_eq!(result.address, String::from("172.26.104.1"));
assert_eq!(result.port, 22); assert_eq!(result.port, 22);
assert_eq!(result.protocol, FileTransferProtocol::Sftp); assert_eq!(result.protocol, FileTransferProtocol::Sftp);
assert!(result.username.is_some()); assert!(result.username.is_some());
// User case // User case
let result: RemoteOptions = parse_remote_opt(&String::from("root@172.26.104.1")) let result: FileTransferParams = parse_remote_opt(&String::from("root@172.26.104.1"))
.ok() .ok()
.unwrap(); .unwrap();
assert_eq!(result.hostname, String::from("172.26.104.1")); assert_eq!(result.address, String::from("172.26.104.1"));
assert_eq!(result.port, 22); assert_eq!(result.port, 22);
assert_eq!(result.protocol, FileTransferProtocol::Sftp); assert_eq!(result.protocol, FileTransferProtocol::Sftp);
assert_eq!(result.username.unwrap(), String::from("root")); assert_eq!(result.username.unwrap(), String::from("root"));
assert!(result.wrkdir.is_none()); assert!(result.entry_directory.is_none());
// User + port // User + port
let result: RemoteOptions = parse_remote_opt(&String::from("root@172.26.104.1:8022")) let result: FileTransferParams = parse_remote_opt(&String::from("root@172.26.104.1:8022"))
.ok() .ok()
.unwrap(); .unwrap();
assert_eq!(result.hostname, String::from("172.26.104.1")); assert_eq!(result.address, String::from("172.26.104.1"));
assert_eq!(result.port, 8022); assert_eq!(result.port, 8022);
assert_eq!(result.protocol, FileTransferProtocol::Sftp); assert_eq!(result.protocol, FileTransferProtocol::Sftp);
assert_eq!(result.username.unwrap(), String::from("root")); assert_eq!(result.username.unwrap(), String::from("root"));
assert!(result.wrkdir.is_none()); assert!(result.entry_directory.is_none());
// Port only // Port only
let result: RemoteOptions = parse_remote_opt(&String::from("172.26.104.1:4022")) let result: FileTransferParams = parse_remote_opt(&String::from("172.26.104.1:4022"))
.ok() .ok()
.unwrap(); .unwrap();
assert_eq!(result.hostname, String::from("172.26.104.1")); assert_eq!(result.address, String::from("172.26.104.1"));
assert_eq!(result.port, 4022); assert_eq!(result.port, 4022);
assert_eq!(result.protocol, FileTransferProtocol::Sftp); assert_eq!(result.protocol, FileTransferProtocol::Sftp);
assert!(result.username.is_some()); assert!(result.username.is_some());
assert!(result.wrkdir.is_none()); assert!(result.entry_directory.is_none());
// Protocol // Protocol
let result: RemoteOptions = parse_remote_opt(&String::from("ftp://172.26.104.1")) let result: FileTransferParams = parse_remote_opt(&String::from("ftp://172.26.104.1"))
.ok() .ok()
.unwrap(); .unwrap();
assert_eq!(result.hostname, String::from("172.26.104.1")); assert_eq!(result.address, String::from("172.26.104.1"));
assert_eq!(result.port, 21); // Fallback to ftp default assert_eq!(result.port, 21); // Fallback to ftp default
assert_eq!(result.protocol, FileTransferProtocol::Ftp(false)); assert_eq!(result.protocol, FileTransferProtocol::Ftp(false));
assert!(result.username.is_none()); // Doesn't fall back assert!(result.username.is_none()); // Doesn't fall back
assert!(result.wrkdir.is_none()); assert!(result.entry_directory.is_none());
// Protocol // Protocol
let result: RemoteOptions = parse_remote_opt(&String::from("sftp://172.26.104.1")) let result: FileTransferParams = parse_remote_opt(&String::from("sftp://172.26.104.1"))
.ok() .ok()
.unwrap(); .unwrap();
assert_eq!(result.hostname, String::from("172.26.104.1")); assert_eq!(result.address, String::from("172.26.104.1"));
assert_eq!(result.port, 22); // Fallback to sftp default assert_eq!(result.port, 22); // Fallback to sftp default
assert_eq!(result.protocol, FileTransferProtocol::Sftp); assert_eq!(result.protocol, FileTransferProtocol::Sftp);
assert!(result.username.is_some()); // Doesn't fall back assert!(result.username.is_some()); // Doesn't fall back
assert!(result.wrkdir.is_none()); assert!(result.entry_directory.is_none());
let result: RemoteOptions = parse_remote_opt(&String::from("scp://172.26.104.1")) let result: FileTransferParams = parse_remote_opt(&String::from("scp://172.26.104.1"))
.ok() .ok()
.unwrap(); .unwrap();
assert_eq!(result.hostname, String::from("172.26.104.1")); assert_eq!(result.address, String::from("172.26.104.1"));
assert_eq!(result.port, 22); // Fallback to scp default assert_eq!(result.port, 22); // Fallback to scp default
assert_eq!(result.protocol, FileTransferProtocol::Scp); assert_eq!(result.protocol, FileTransferProtocol::Scp);
assert!(result.username.is_some()); // Doesn't fall back assert!(result.username.is_some()); // Doesn't fall back
assert!(result.wrkdir.is_none()); assert!(result.entry_directory.is_none());
// Protocol + user // Protocol + user
let result: RemoteOptions = parse_remote_opt(&String::from("ftps://anon@172.26.104.1")) let result: FileTransferParams =
.ok() parse_remote_opt(&String::from("ftps://anon@172.26.104.1"))
.unwrap(); .ok()
assert_eq!(result.hostname, String::from("172.26.104.1")); .unwrap();
assert_eq!(result.address, String::from("172.26.104.1"));
assert_eq!(result.port, 21); // Fallback to ftp default assert_eq!(result.port, 21); // Fallback to ftp default
assert_eq!(result.protocol, FileTransferProtocol::Ftp(true)); assert_eq!(result.protocol, FileTransferProtocol::Ftp(true));
assert_eq!(result.username.unwrap(), String::from("anon")); assert_eq!(result.username.unwrap(), String::from("anon"));
assert!(result.wrkdir.is_none()); assert!(result.entry_directory.is_none());
// Path // Path
let result: RemoteOptions = parse_remote_opt(&String::from("root@172.26.104.1:8022:/var")) let result: FileTransferParams =
.ok() parse_remote_opt(&String::from("root@172.26.104.1:8022:/var"))
.unwrap(); .ok()
assert_eq!(result.hostname, String::from("172.26.104.1")); .unwrap();
assert_eq!(result.address, String::from("172.26.104.1"));
assert_eq!(result.port, 8022); assert_eq!(result.port, 8022);
assert_eq!(result.protocol, FileTransferProtocol::Sftp); assert_eq!(result.protocol, FileTransferProtocol::Sftp);
assert_eq!(result.username.unwrap(), String::from("root")); assert_eq!(result.username.unwrap(), String::from("root"));
assert_eq!(result.wrkdir.unwrap(), PathBuf::from("/var")); assert_eq!(result.entry_directory.unwrap(), PathBuf::from("/var"));
// Port only // Port only
let result: RemoteOptions = parse_remote_opt(&String::from("172.26.104.1:home")) let result: FileTransferParams = parse_remote_opt(&String::from("172.26.104.1:home"))
.ok() .ok()
.unwrap(); .unwrap();
assert_eq!(result.hostname, String::from("172.26.104.1")); assert_eq!(result.address, String::from("172.26.104.1"));
assert_eq!(result.port, 22); assert_eq!(result.port, 22);
assert_eq!(result.protocol, FileTransferProtocol::Sftp); assert_eq!(result.protocol, FileTransferProtocol::Sftp);
assert!(result.username.is_some()); assert!(result.username.is_some());
assert_eq!(result.wrkdir.unwrap(), PathBuf::from("home")); assert_eq!(result.entry_directory.unwrap(), PathBuf::from("home"));
// All together now // All together now
let result: RemoteOptions = let result: FileTransferParams =
parse_remote_opt(&String::from("ftp://anon@172.26.104.1:8021:/tmp")) parse_remote_opt(&String::from("ftp://anon@172.26.104.1:8021:/tmp"))
.ok() .ok()
.unwrap(); .unwrap();
assert_eq!(result.hostname, String::from("172.26.104.1")); assert_eq!(result.address, String::from("172.26.104.1"));
assert_eq!(result.port, 8021); // Fallback to ftp default assert_eq!(result.port, 8021); // Fallback to ftp default
assert_eq!(result.protocol, FileTransferProtocol::Ftp(false)); assert_eq!(result.protocol, FileTransferProtocol::Ftp(false));
assert_eq!(result.username.unwrap(), String::from("anon")); assert_eq!(result.username.unwrap(), String::from("anon"));
assert_eq!(result.wrkdir.unwrap(), PathBuf::from("/tmp")); assert_eq!(result.entry_directory.unwrap(), PathBuf::from("/tmp"));
// bad syntax // bad syntax
assert!(parse_remote_opt(&String::from("omar://172.26.104.1")).is_err()); // Bad protocol // Bad protocol
assert!(parse_remote_opt(&String::from("omar://172.26.104.1:650000")).is_err()); assert!(parse_remote_opt(&String::from("omar://172.26.104.1")).is_err());
// Bad port // Bad port
assert!(parse_remote_opt(&String::from("scp://172.26.104.1:650000")).is_err());
} }
#[test] #[test]