diff --git a/src/activity_manager.rs b/src/activity_manager.rs index 63747a3..64ca29a 100644 --- a/src/activity_manager.rs +++ b/src/activity_manager.rs @@ -26,9 +26,10 @@ use std::path::PathBuf; // Deps +use crate::filetransfer::FileTransferProtocol; use crate::host::Localhost; use crate::ui::activities::{ - auth_activity::AuthActivity, auth_activity::ScpProtocol, + auth_activity::AuthActivity, filetransfer_activity::FileTransferActivity, filetransfer_activity::FileTransferParams, Activity, }; @@ -83,7 +84,7 @@ impl ActivityManager { &mut self, address: String, port: u16, - protocol: ScpProtocol, + protocol: FileTransferProtocol, username: Option, password: Option, ) { diff --git a/src/filetransfer/mod.rs b/src/filetransfer/mod.rs index beccf70..d4f12e5 100644 --- a/src/filetransfer/mod.rs +++ b/src/filetransfer/mod.rs @@ -38,10 +38,10 @@ type ProgressCallback = fn(bytes_written: usize, size: usize); /// /// This enum defines the different transfer protocol available in TermSCP -#[derive(PartialEq, Clone)] +#[derive(std::cmp::PartialEq, std::fmt::Debug, std::clone::Clone)] pub enum FileTransferProtocol { Sftp, - Ftps, + Ftp, } /// ## FileTransferError @@ -62,6 +62,29 @@ pub enum FileTransferError { UnknownError, } +impl FileTransferError { + + /// ### msg + /// + /// Get error message + pub fn msg(&self) -> String { + match self { + FileTransferError::AuthenticationFailed => String::from("Authentication failed: bad credentials"), + FileTransferError::BadAddress => String::from("Bad address syntax"), + FileTransferError::ConnectionError => String::from("Connection error"), + FileTransferError::DirStatFailed => String::from("Could not stat directory"), + FileTransferError::FileCreateDenied => String::from("Failed to create file"), + FileTransferError::FileReadonly => String::from("File is readonly"), + FileTransferError::IoErr(err) => format!("IO Error: {}", err), + FileTransferError::NoSuchFileOrDirectory => String::from("No such file or directory"), + FileTransferError::ProtocolError => String::from("Protocol error"), + FileTransferError::UninitializedSession => String::from("Uninitialized session"), + FileTransferError::UnknownError => String::from("Unknown error"), + } + } + +} + /// ## FileTransfer /// /// File transfer trait must be implemented by all the file transfers and defines the method used by a generic file transfer diff --git a/src/main.rs b/src/main.rs index da563e1..9c361d0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,7 +42,7 @@ mod utils; // namespaces use activity_manager::{ActivityManager, NextActivity}; -use ui::activities::auth_activity::ScpProtocol; +use filetransfer::FileTransferProtocol; /// ### print_usage /// @@ -60,7 +60,7 @@ fn main() { let mut port: u16 = 22; // Default port let mut username: Option = None; // Default username let password: Option; // Default password - let mut protocol: ScpProtocol = ScpProtocol::Sftp; // Default protocol + let mut protocol: FileTransferProtocol = FileTransferProtocol::Sftp; // Default protocol let mut ticks: Duration = Duration::from_micros(50); //Process options // FIXME: there is no way to provide password from CLI atm diff --git a/src/ui/activities/auth_activity.rs b/src/ui/activities/auth_activity.rs index fd8f10d..8d38c79 100644 --- a/src/ui/activities/auth_activity.rs +++ b/src/ui/activities/auth_activity.rs @@ -30,6 +30,7 @@ extern crate unicode_width; // locals use super::{Activity, Context}; +use crate::filetransfer::FileTransferProtocol; // Includes use crossterm::event::Event as InputEvent; @@ -65,22 +66,13 @@ enum InputMode { Popup, } -/// ### ScpProtocol -/// -/// ScpProtocol describes the communication protocol selected by the user to communicate with the remote -#[derive(std::cmp::PartialEq, std::fmt::Debug, std::clone::Clone)] -pub enum ScpProtocol { - Sftp, - Ftp, -} - /// ### AuthActivity /// /// AuthActivity is the data holder for the authentication activity pub struct AuthActivity { pub address: String, pub port: String, - pub protocol: ScpProtocol, + pub protocol: FileTransferProtocol, pub username: String, pub password: String, pub submit: bool, // becomes true after user has submitted fields @@ -99,7 +91,7 @@ impl AuthActivity { AuthActivity { address: String::new(), port: String::from("22"), - protocol: ScpProtocol::Sftp, + protocol: FileTransferProtocol::Sftp, username: String::new(), password: String::new(), submit: false, @@ -233,8 +225,8 @@ impl AuthActivity { // If current field is Protocol handle event... (move element left) if self.selected_field == InputField::Protocol { self.protocol = match self.protocol { - ScpProtocol::Sftp => ScpProtocol::Sftp, - ScpProtocol::Ftp => ScpProtocol::Sftp, // End of list + FileTransferProtocol::Sftp => FileTransferProtocol::Sftp, + FileTransferProtocol::Ftp => FileTransferProtocol::Sftp, // End of list } } } @@ -242,8 +234,8 @@ impl AuthActivity { // If current field is Protocol handle event... ( move element right ) if self.selected_field == InputField::Protocol { self.protocol = match self.protocol { - ScpProtocol::Sftp => ScpProtocol::Ftp, - ScpProtocol::Ftp => ScpProtocol::Ftp, // End of list + FileTransferProtocol::Sftp => FileTransferProtocol::Ftp, + FileTransferProtocol::Ftp => FileTransferProtocol::Ftp, // End of list } } } @@ -306,8 +298,8 @@ impl AuthActivity { fn draw_protocol_select(&self) -> Tabs { let protocols: Vec = vec![Spans::from("SFTP"), Spans::from("FTP")]; let index: usize = match self.protocol { - ScpProtocol::Sftp => 0, - ScpProtocol::Ftp => 1, + FileTransferProtocol::Sftp => 0, + FileTransferProtocol::Ftp => 1, }; Tabs::new(protocols) .block(Block::default().borders(Borders::ALL).title("Protocol")) diff --git a/src/utils.rs b/src/utils.rs index 8bd972e..24a8eda 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -26,7 +26,7 @@ // Dependencies extern crate whoami; -use crate::ui::activities::auth_activity::ScpProtocol; +use crate::filetransfer::FileTransferProtocol; /// ### parse_remote_opt /// @@ -49,11 +49,11 @@ use crate::ui::activities::auth_activity::ScpProtocol; /// pub fn parse_remote_opt( remote: &String, -) -> Result<(String, u16, ScpProtocol, Option), String> { +) -> Result<(String, u16, FileTransferProtocol, Option), String> { let mut wrkstr: String = remote.clone(); let address: String; let mut port: u16 = 22; - let mut protocol: ScpProtocol = ScpProtocol::Sftp; + let mut protocol: FileTransferProtocol = FileTransferProtocol::Sftp; let mut username: Option = None; // Split string by '://' let tokens: Vec<&str> = wrkstr.split("://").collect(); @@ -65,13 +65,13 @@ pub fn parse_remote_opt( match tokens[0] { "sftp" => { // Set protocol to sftp - protocol = ScpProtocol::Sftp; + protocol = FileTransferProtocol::Sftp; // Set port to default (22) port = 22; } "ftp" | "ftps" => { // Set protocol to fpt - protocol = ScpProtocol::Ftp; + protocol = FileTransferProtocol::Ftp; // Set port to default (21) port = 21; } @@ -82,7 +82,7 @@ pub fn parse_remote_opt( _ => return Err(String::from("Bad syntax")), // Too many tokens... } // Set username to default if sftp - if protocol == ScpProtocol::Sftp { + if protocol == FileTransferProtocol::Sftp { // Set username to current username username = Some(whoami::username()); } @@ -127,46 +127,46 @@ mod tests { #[test] fn test_utils_parse_remote_opt() { // Base case - let result: (String, u16, ScpProtocol, Option) = parse_remote_opt(&String::from("172.26.104.1")).ok().unwrap(); + let result: (String, u16, FileTransferProtocol, Option) = parse_remote_opt(&String::from("172.26.104.1")).ok().unwrap(); assert_eq!(result.0, String::from("172.26.104.1")); assert_eq!(result.1, 22); - assert_eq!(result.2, ScpProtocol::Sftp); + assert_eq!(result.2, FileTransferProtocol::Sftp); assert!(result.3.is_some()); // User case - let result: (String, u16, ScpProtocol, Option) = parse_remote_opt(&String::from("root@172.26.104.1")).ok().unwrap(); + let result: (String, u16, FileTransferProtocol, Option) = parse_remote_opt(&String::from("root@172.26.104.1")).ok().unwrap(); assert_eq!(result.0, String::from("172.26.104.1")); assert_eq!(result.1, 22); - assert_eq!(result.2, ScpProtocol::Sftp); + assert_eq!(result.2, FileTransferProtocol::Sftp); assert_eq!(result.3.unwrap(), String::from("root")); // User + port - let result: (String, u16, ScpProtocol, Option) = parse_remote_opt(&String::from("root@172.26.104.1:8022")).ok().unwrap(); + let result: (String, u16, FileTransferProtocol, Option) = parse_remote_opt(&String::from("root@172.26.104.1:8022")).ok().unwrap(); assert_eq!(result.0, String::from("172.26.104.1")); assert_eq!(result.1, 8022); - assert_eq!(result.2, ScpProtocol::Sftp); + assert_eq!(result.2, FileTransferProtocol::Sftp); assert_eq!(result.3.unwrap(), String::from("root")); // Port only - let result: (String, u16, ScpProtocol, Option) = parse_remote_opt(&String::from("172.26.104.1:4022")).ok().unwrap(); + let result: (String, u16, FileTransferProtocol, Option) = parse_remote_opt(&String::from("172.26.104.1:4022")).ok().unwrap(); assert_eq!(result.0, String::from("172.26.104.1")); assert_eq!(result.1, 4022); - assert_eq!(result.2, ScpProtocol::Sftp); + assert_eq!(result.2, FileTransferProtocol::Sftp); assert!(result.3.is_some()); // Protocol - let result: (String, u16, ScpProtocol, Option) = parse_remote_opt(&String::from("ftp://172.26.104.1")).ok().unwrap(); + let result: (String, u16, FileTransferProtocol, Option) = parse_remote_opt(&String::from("ftp://172.26.104.1")).ok().unwrap(); assert_eq!(result.0, String::from("172.26.104.1")); assert_eq!(result.1, 21); // Fallback to ftp default - assert_eq!(result.2, ScpProtocol::Ftp); + assert_eq!(result.2, FileTransferProtocol::Ftp); assert!(result.3.is_none()); // Doesn't fall back // Protocol + user - let result: (String, u16, ScpProtocol, Option) = parse_remote_opt(&String::from("ftp://anon@172.26.104.1")).ok().unwrap(); + let result: (String, u16, FileTransferProtocol, Option) = parse_remote_opt(&String::from("ftp://anon@172.26.104.1")).ok().unwrap(); assert_eq!(result.0, String::from("172.26.104.1")); assert_eq!(result.1, 21); // Fallback to ftp default - assert_eq!(result.2, ScpProtocol::Ftp); + assert_eq!(result.2, FileTransferProtocol::Ftp); assert_eq!(result.3.unwrap(), String::from("anon")); // All together now - let result: (String, u16, ScpProtocol, Option) = parse_remote_opt(&String::from("ftp://anon@172.26.104.1:8021")).ok().unwrap(); + let result: (String, u16, FileTransferProtocol, Option) = parse_remote_opt(&String::from("ftp://anon@172.26.104.1:8021")).ok().unwrap(); assert_eq!(result.0, String::from("172.26.104.1")); assert_eq!(result.1, 8021); // Fallback to ftp default - assert_eq!(result.2, ScpProtocol::Ftp); + assert_eq!(result.2, FileTransferProtocol::Ftp); assert_eq!(result.3.unwrap(), String::from("anon")); // bad syntax