mirror of
https://github.com/veeso/termscp.git
synced 2025-12-06 17:15:35 -08:00
Removed redundant remoteOpts struct; use FileTransferParams only
This commit is contained in:
@@ -26,7 +26,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
// Deps
|
||||
use crate::filetransfer::FileTransferProtocol;
|
||||
use crate::filetransfer::{FileTransferParams, FileTransferProtocol};
|
||||
use crate::host::{HostError, Localhost};
|
||||
use crate::system::config_client::ConfigClient;
|
||||
use crate::system::environment;
|
||||
@@ -35,7 +35,7 @@ use crate::ui::activities::{
|
||||
auth::AuthActivity, filetransfer::FileTransferActivity, setup::SetupActivity, Activity,
|
||||
ExitReason,
|
||||
};
|
||||
use crate::ui::context::{Context, FileTransferParams};
|
||||
use crate::ui::context::Context;
|
||||
|
||||
// Namespaces
|
||||
use std::path::{Path, PathBuf};
|
||||
@@ -87,27 +87,9 @@ impl ActivityManager {
|
||||
/// ### set_filetransfer_params
|
||||
///
|
||||
/// Set file transfer params
|
||||
pub fn set_filetransfer_params(
|
||||
&mut self,
|
||||
address: String,
|
||||
port: u16,
|
||||
protocol: FileTransferProtocol,
|
||||
username: Option<String>,
|
||||
password: Option<String>,
|
||||
entry_directory: Option<PathBuf>,
|
||||
) {
|
||||
pub fn set_filetransfer_params(&mut self, params: FileTransferParams) {
|
||||
// Put params into the context
|
||||
self.context
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.set_ftparams(FileTransferParams {
|
||||
address,
|
||||
port,
|
||||
protocol,
|
||||
username,
|
||||
password,
|
||||
entry_directory,
|
||||
});
|
||||
self.context.as_mut().unwrap().set_ftparams(params);
|
||||
}
|
||||
|
||||
/// ### run
|
||||
|
||||
@@ -34,9 +34,12 @@ use thiserror::Error;
|
||||
use wildmatch::WildMatch;
|
||||
// exports
|
||||
pub mod ftp_transfer;
|
||||
pub mod params;
|
||||
pub mod scp_transfer;
|
||||
pub mod sftp_transfer;
|
||||
|
||||
pub use params::FileTransferParams;
|
||||
|
||||
/// ## FileTransferProtocol
|
||||
///
|
||||
/// This enum defines the different transfer protocol available in termscp
|
||||
|
||||
51
src/main.rs
51
src/main.rs
@@ -56,7 +56,7 @@ mod utils;
|
||||
|
||||
// namespaces
|
||||
use activity_manager::{ActivityManager, NextActivity};
|
||||
use filetransfer::FileTransferProtocol;
|
||||
use filetransfer::FileTransferParams;
|
||||
use system::logging;
|
||||
|
||||
enum Task {
|
||||
@@ -97,12 +97,7 @@ struct Args {
|
||||
}
|
||||
|
||||
struct RunOpts {
|
||||
address: Option<String>,
|
||||
port: u16,
|
||||
username: Option<String>,
|
||||
password: Option<String>,
|
||||
remote_wrkdir: Option<PathBuf>,
|
||||
protocol: FileTransferProtocol,
|
||||
remote: Option<FileTransferParams>,
|
||||
ticks: Duration,
|
||||
log_enabled: bool,
|
||||
task: Task,
|
||||
@@ -111,12 +106,7 @@ struct RunOpts {
|
||||
impl Default for RunOpts {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
address: None,
|
||||
port: 22,
|
||||
username: None,
|
||||
password: None,
|
||||
remote_wrkdir: None,
|
||||
protocol: FileTransferProtocol::Sftp,
|
||||
remote: None,
|
||||
ticks: Duration::from_millis(10),
|
||||
log_enabled: true,
|
||||
task: Task::Activity(NextActivity::Authentication),
|
||||
@@ -176,10 +166,6 @@ fn parse_args(args: Args) -> Result<RunOpts, String> {
|
||||
if args.quiet {
|
||||
run_opts.log_enabled = false;
|
||||
}
|
||||
// Match password
|
||||
if let Some(passwd) = args.password {
|
||||
run_opts.password = Some(passwd);
|
||||
}
|
||||
// Match ticks
|
||||
run_opts.ticks = Duration::from_millis(args.ticks);
|
||||
// @! extra modes
|
||||
@@ -191,13 +177,13 @@ fn parse_args(args: Args) -> Result<RunOpts, String> {
|
||||
if let Some(remote) = args.positional.get(0) {
|
||||
// Parse address
|
||||
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
|
||||
run_opts.address = Some(host_opts.hostname);
|
||||
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;
|
||||
run_opts.remote = Some(remote);
|
||||
// In this case the first activity will be 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
|
||||
fn read_password(run_opts: &mut RunOpts) -> Result<(), String> {
|
||||
// Initialize client if necessary
|
||||
if run_opts.address.is_some() {
|
||||
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("")));
|
||||
if run_opts.password.is_none() {
|
||||
if let Some(remote) = run_opts.remote.as_mut() {
|
||||
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 remote.password.is_none() {
|
||||
// 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) => {
|
||||
if p.is_empty() {
|
||||
None
|
||||
@@ -278,15 +264,8 @@ fn run(mut run_opts: RunOpts) -> i32 {
|
||||
}
|
||||
};
|
||||
// Set file transfer params if set
|
||||
if let Some(address) = run_opts.address.take() {
|
||||
manager.set_filetransfer_params(
|
||||
address,
|
||||
run_opts.port,
|
||||
run_opts.protocol,
|
||||
run_opts.username,
|
||||
run_opts.password,
|
||||
run_opts.remote_wrkdir,
|
||||
);
|
||||
if let Some(remote) = run_opts.remote.take() {
|
||||
manager.set_filetransfer_params(remote);
|
||||
}
|
||||
manager.run(activity);
|
||||
0
|
||||
|
||||
@@ -34,9 +34,8 @@ mod view;
|
||||
// locals
|
||||
use super::{Activity, Context, ExitReason};
|
||||
use crate::config::themes::Theme;
|
||||
use crate::filetransfer::FileTransferProtocol;
|
||||
use crate::filetransfer::{FileTransferParams, FileTransferProtocol};
|
||||
use crate::system::bookmarks_client::BookmarksClient;
|
||||
use crate::ui::context::FileTransferParams;
|
||||
use crate::utils::git;
|
||||
|
||||
// Includes
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
// Locals
|
||||
use super::input::InputHandler;
|
||||
use super::store::Store;
|
||||
use crate::filetransfer::FileTransferProtocol;
|
||||
use crate::filetransfer::FileTransferParams;
|
||||
use crate::system::config_client::ConfigClient;
|
||||
use crate::system::theme_provider::ThemeProvider;
|
||||
|
||||
@@ -37,7 +37,6 @@ use crossterm::event::DisableMouseCapture;
|
||||
use crossterm::execute;
|
||||
use crossterm::terminal::{EnterAlternateScreen, LeaveAlternateScreen};
|
||||
use std::io::{stdout, Stdout};
|
||||
use std::path::PathBuf;
|
||||
use tuirealm::tui::backend::CrosstermBackend;
|
||||
use tuirealm::tui::Terminal;
|
||||
|
||||
@@ -56,19 +55,6 @@ pub struct Context {
|
||||
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 {
|
||||
/// ### new
|
||||
///
|
||||
@@ -198,34 +184,3 @@ impl Drop for Context {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
// Locals
|
||||
use crate::filetransfer::FileTransferProtocol;
|
||||
use crate::filetransfer::{FileTransferParams, FileTransferProtocol};
|
||||
#[cfg(not(test))] // NOTE: don't use configuration during tests
|
||||
use crate::system::config_client::ConfigClient;
|
||||
#[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();
|
||||
}
|
||||
|
||||
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 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
|
||||
/// - ...
|
||||
///
|
||||
pub fn parse_remote_opt(remote: &str) -> Result<RemoteOptions, String> {
|
||||
pub fn parse_remote_opt(remote: &str) -> Result<FileTransferParams, String> {
|
||||
// Set protocol to default protocol
|
||||
#[cfg(not(test))] // NOTE: don't use configuration during tests
|
||||
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
|
||||
let hostname: String = match groups.get(3) {
|
||||
let address: String = match groups.get(3) {
|
||||
Some(group) => group.as_str().to_string(),
|
||||
None => return Err(String::from("Missing address")),
|
||||
};
|
||||
@@ -164,14 +155,13 @@ pub fn parse_remote_opt(remote: &str) -> Result<RemoteOptions, String> {
|
||||
};
|
||||
}
|
||||
// Get workdir
|
||||
let wrkdir: Option<PathBuf> = groups.get(5).map(|group| PathBuf::from(group.as_str()));
|
||||
Ok(RemoteOptions {
|
||||
hostname,
|
||||
port,
|
||||
protocol,
|
||||
username,
|
||||
wrkdir,
|
||||
})
|
||||
let entry_directory: Option<PathBuf> =
|
||||
groups.get(5).map(|group| PathBuf::from(group.as_str()));
|
||||
Ok(FileTransferParams::new(address)
|
||||
.port(port)
|
||||
.protocol(protocol)
|
||||
.username(username)
|
||||
.entry_directory(entry_directory))
|
||||
}
|
||||
None => Err(String::from("Bad remote host syntax!")),
|
||||
}
|
||||
@@ -476,107 +466,110 @@ mod tests {
|
||||
#[test]
|
||||
fn test_utils_parse_remote_opt() {
|
||||
// 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()
|
||||
.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.protocol, FileTransferProtocol::Sftp);
|
||||
assert!(result.username.is_some());
|
||||
// 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()
|
||||
.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.protocol, FileTransferProtocol::Sftp);
|
||||
assert_eq!(result.username.unwrap(), String::from("root"));
|
||||
assert!(result.wrkdir.is_none());
|
||||
assert!(result.entry_directory.is_none());
|
||||
// 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()
|
||||
.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.protocol, FileTransferProtocol::Sftp);
|
||||
assert_eq!(result.username.unwrap(), String::from("root"));
|
||||
assert!(result.wrkdir.is_none());
|
||||
assert!(result.entry_directory.is_none());
|
||||
// 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()
|
||||
.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.protocol, FileTransferProtocol::Sftp);
|
||||
assert!(result.username.is_some());
|
||||
assert!(result.wrkdir.is_none());
|
||||
assert!(result.entry_directory.is_none());
|
||||
// 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()
|
||||
.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.protocol, FileTransferProtocol::Ftp(false));
|
||||
assert!(result.username.is_none()); // Doesn't fall back
|
||||
assert!(result.wrkdir.is_none());
|
||||
assert!(result.entry_directory.is_none());
|
||||
// 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()
|
||||
.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.protocol, FileTransferProtocol::Sftp);
|
||||
assert!(result.username.is_some()); // Doesn't fall back
|
||||
assert!(result.wrkdir.is_none());
|
||||
let result: RemoteOptions = parse_remote_opt(&String::from("scp://172.26.104.1"))
|
||||
assert!(result.entry_directory.is_none());
|
||||
let result: FileTransferParams = parse_remote_opt(&String::from("scp://172.26.104.1"))
|
||||
.ok()
|
||||
.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.protocol, FileTransferProtocol::Scp);
|
||||
assert!(result.username.is_some()); // Doesn't fall back
|
||||
assert!(result.wrkdir.is_none());
|
||||
assert!(result.entry_directory.is_none());
|
||||
// Protocol + user
|
||||
let result: RemoteOptions = parse_remote_opt(&String::from("ftps://anon@172.26.104.1"))
|
||||
.ok()
|
||||
.unwrap();
|
||||
assert_eq!(result.hostname, String::from("172.26.104.1"));
|
||||
let result: FileTransferParams =
|
||||
parse_remote_opt(&String::from("ftps://anon@172.26.104.1"))
|
||||
.ok()
|
||||
.unwrap();
|
||||
assert_eq!(result.address, String::from("172.26.104.1"));
|
||||
assert_eq!(result.port, 21); // Fallback to ftp default
|
||||
assert_eq!(result.protocol, FileTransferProtocol::Ftp(true));
|
||||
assert_eq!(result.username.unwrap(), String::from("anon"));
|
||||
assert!(result.wrkdir.is_none());
|
||||
assert!(result.entry_directory.is_none());
|
||||
// Path
|
||||
let result: RemoteOptions = parse_remote_opt(&String::from("root@172.26.104.1:8022:/var"))
|
||||
.ok()
|
||||
.unwrap();
|
||||
assert_eq!(result.hostname, String::from("172.26.104.1"));
|
||||
let result: FileTransferParams =
|
||||
parse_remote_opt(&String::from("root@172.26.104.1:8022:/var"))
|
||||
.ok()
|
||||
.unwrap();
|
||||
assert_eq!(result.address, String::from("172.26.104.1"));
|
||||
assert_eq!(result.port, 8022);
|
||||
assert_eq!(result.protocol, FileTransferProtocol::Sftp);
|
||||
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
|
||||
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()
|
||||
.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.protocol, FileTransferProtocol::Sftp);
|
||||
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
|
||||
let result: RemoteOptions =
|
||||
let result: FileTransferParams =
|
||||
parse_remote_opt(&String::from("ftp://anon@172.26.104.1:8021:/tmp"))
|
||||
.ok()
|
||||
.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.protocol, FileTransferProtocol::Ftp(false));
|
||||
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
|
||||
assert!(parse_remote_opt(&String::from("omar://172.26.104.1")).is_err()); // Bad protocol
|
||||
assert!(parse_remote_opt(&String::from("omar://172.26.104.1:650000")).is_err());
|
||||
// Bad protocol
|
||||
assert!(parse_remote_opt(&String::from("omar://172.26.104.1")).is_err());
|
||||
// Bad port
|
||||
assert!(parse_remote_opt(&String::from("scp://172.26.104.1:650000")).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user