Moved file transfer protocol input on top; port will now be set to default for current protocol on change

This commit is contained in:
veeso
2021-05-05 22:05:46 +02:00
parent dcec804681
commit 4f1e505a7a
5 changed files with 184 additions and 90 deletions

View File

@@ -0,0 +1,71 @@
//! ## AuthActivity
//!
//! `auth_activity` is the module which implements the authentication activity
/**
* MIT License
*
* termscp - Copyright (c) 2021 Christian Visintin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
use super::{AuthActivity, FileTransferProtocol};
impl AuthActivity {
/// ### protocol_opt_to_enum
///
/// Convert radio index for protocol into a `FileTransferProtocol`
pub(super) fn protocol_opt_to_enum(protocol: usize) -> FileTransferProtocol {
match protocol {
1 => FileTransferProtocol::Scp,
2 => FileTransferProtocol::Ftp(false),
3 => FileTransferProtocol::Ftp(true),
_ => FileTransferProtocol::Sftp,
}
}
/// ### protocol_enum_to_opt
///
/// Convert `FileTransferProtocol` enum into radio group index
pub(super) fn protocol_enum_to_opt(protocol: FileTransferProtocol) -> usize {
match protocol {
FileTransferProtocol::Sftp => 0,
FileTransferProtocol::Scp => 1,
FileTransferProtocol::Ftp(false) => 2,
FileTransferProtocol::Ftp(true) => 3,
}
}
/// ### get_default_port_for_protocol
///
/// Get the default port for protocol
pub(super) fn get_default_port_for_protocol(protocol: FileTransferProtocol) -> u16 {
match protocol {
FileTransferProtocol::Sftp | FileTransferProtocol::Scp => 22,
FileTransferProtocol::Ftp(_) => 21,
}
}
/// ### is_port_standard
///
/// Returns whether the port is standard or not
pub(super) fn is_port_standard(port: u16) -> bool {
port < 1024
}
}

View File

@@ -27,6 +27,7 @@
*/
// Sub modules
mod bookmarks;
mod misc;
mod update;
mod view;

View File

@@ -27,15 +27,16 @@
*/
// locals
use super::{
AuthActivity, FileTransferParams, COMPONENT_BOOKMARKS_LIST, COMPONENT_INPUT_ADDR,
COMPONENT_INPUT_BOOKMARK_NAME, COMPONENT_INPUT_PASSWORD, COMPONENT_INPUT_PORT,
COMPONENT_INPUT_USERNAME, COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK,
AuthActivity, FileTransferParams, FileTransferProtocol, COMPONENT_BOOKMARKS_LIST,
COMPONENT_INPUT_ADDR, COMPONENT_INPUT_BOOKMARK_NAME, COMPONENT_INPUT_PASSWORD,
COMPONENT_INPUT_PORT, COMPONENT_INPUT_USERNAME, COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK,
COMPONENT_RADIO_BOOKMARK_DEL_RECENT, COMPONENT_RADIO_BOOKMARK_SAVE_PWD,
COMPONENT_RADIO_PROTOCOL, COMPONENT_RADIO_QUIT, COMPONENT_RECENTS_LIST, COMPONENT_TEXT_ERROR,
COMPONENT_TEXT_HELP,
};
use crate::ui::activities::keymap::*;
use tuirealm::{Msg, Payload, Value};
use tuirealm::components::InputPropsBuilder;
use tuirealm::{Msg, Payload, PropsBuilder, Value};
// -- update
@@ -51,17 +52,17 @@ impl AuthActivity {
None => None, // Exit after None
Some(msg) => match msg {
// Focus ( DOWN )
(COMPONENT_RADIO_PROTOCOL, &MSG_KEY_DOWN) => {
// Give focus to port
self.view.active(COMPONENT_INPUT_ADDR);
None
}
(COMPONENT_INPUT_ADDR, &MSG_KEY_DOWN) => {
// Give focus to port
self.view.active(COMPONENT_INPUT_PORT);
None
}
(COMPONENT_INPUT_PORT, &MSG_KEY_DOWN) => {
// Give focus to port
self.view.active(COMPONENT_RADIO_PROTOCOL);
None
}
(COMPONENT_RADIO_PROTOCOL, &MSG_KEY_DOWN) => {
// Give focus to port
self.view.active(COMPONENT_INPUT_USERNAME);
None
@@ -73,7 +74,7 @@ impl AuthActivity {
}
(COMPONENT_INPUT_PASSWORD, &MSG_KEY_DOWN) => {
// Give focus to port
self.view.active(COMPONENT_INPUT_ADDR);
self.view.active(COMPONENT_RADIO_PROTOCOL);
None
}
// Focus ( UP )
@@ -83,11 +84,6 @@ impl AuthActivity {
None
}
(COMPONENT_INPUT_USERNAME, &MSG_KEY_UP) => {
// Give focus to port
self.view.active(COMPONENT_RADIO_PROTOCOL);
None
}
(COMPONENT_RADIO_PROTOCOL, &MSG_KEY_UP) => {
// Give focus to port
self.view.active(COMPONENT_INPUT_PORT);
None
@@ -98,10 +94,28 @@ impl AuthActivity {
None
}
(COMPONENT_INPUT_ADDR, &MSG_KEY_UP) => {
// Give focus to port
self.view.active(COMPONENT_RADIO_PROTOCOL);
None
}
(COMPONENT_RADIO_PROTOCOL, &MSG_KEY_UP) => {
// Give focus to port
self.view.active(COMPONENT_INPUT_PASSWORD);
None
}
// Protocol - On Change
(COMPONENT_RADIO_PROTOCOL, Msg::OnChange(Payload::One(Value::Usize(protocol)))) => {
// If port is standard, update the current port with default for selected protocol
let protocol: FileTransferProtocol = Self::protocol_opt_to_enum(*protocol);
// Get port
let port: u16 = self.get_input_port();
match Self::is_port_standard(port) {
false => None, // Return None
true => {
self.update_input_port(Self::get_default_port_for_protocol(protocol))
}
}
}
// <TAB> bookmarks
(COMPONENT_BOOKMARKS_LIST, &MSG_KEY_TAB)
| (COMPONENT_RECENTS_LIST, &MSG_KEY_TAB) => {
@@ -322,4 +336,16 @@ impl AuthActivity {
},
}
}
fn update_input_port(&mut self, port: u16) -> Option<(String, Msg)> {
match self.view.get_props(COMPONENT_INPUT_PORT) {
None => None,
Some(props) => {
let props = InputPropsBuilder::from(props)
.with_value(port.to_string())
.build();
self.view.update(COMPONENT_INPUT_PORT, props)
}
}
}
}

View File

@@ -99,42 +99,12 @@ impl AuthActivity {
.build(),
)),
);
// Address
self.view.mount(
super::COMPONENT_INPUT_ADDR,
Box::new(Input::new(
InputPropsBuilder::default()
.with_foreground(Color::Yellow)
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightYellow)
.with_label(String::from("Remote address"))
.build(),
)),
);
// Get default protocol
let default_protocol: FileTransferProtocol =
match self.context.as_ref().unwrap().config_client.as_ref() {
Some(cli) => cli.get_default_protocol(),
None => FileTransferProtocol::Sftp,
};
// Calc default port
let default_port: String = String::from(match default_protocol {
FileTransferProtocol::Ftp(_) => "21",
FileTransferProtocol::Sftp | FileTransferProtocol::Scp => "22",
});
// Port
self.view.mount(
super::COMPONENT_INPUT_PORT,
Box::new(Input::new(
InputPropsBuilder::default()
.with_foreground(Color::LightCyan)
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightCyan)
.with_label(String::from("Port number"))
.with_input(InputType::Number)
.with_input_len(5)
.with_value(default_port)
.build(),
)),
);
// Protocol
self.view.mount(
super::COMPONENT_RADIO_PROTOCOL,
@@ -156,6 +126,36 @@ impl AuthActivity {
.build(),
)),
);
// Address
self.view.mount(
super::COMPONENT_INPUT_ADDR,
Box::new(Input::new(
InputPropsBuilder::default()
.with_foreground(Color::Yellow)
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightYellow)
.with_label(String::from("Remote address"))
.build(),
)),
);
// Calc default port
let default_port: String = String::from(match default_protocol {
FileTransferProtocol::Ftp(_) => "21",
FileTransferProtocol::Sftp | FileTransferProtocol::Scp => "22",
});
// Port
self.view.mount(
super::COMPONENT_INPUT_PORT,
Box::new(Input::new(
InputPropsBuilder::default()
.with_foreground(Color::LightCyan)
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightCyan)
.with_label(String::from("Port number"))
.with_input(InputType::Number)
.with_input_len(5)
.with_value(default_port)
.build(),
)),
);
// Username
self.view.mount(
super::COMPONENT_INPUT_USERNAME,
@@ -229,8 +229,8 @@ impl AuthActivity {
)),
);
let _ = self.view_recent_connections();
// Active address
self.view.active(super::COMPONENT_INPUT_ADDR);
// Active protocol
self.view.active(super::COMPONENT_RADIO_PROTOCOL);
}
/// ### view
@@ -258,9 +258,9 @@ impl AuthActivity {
Constraint::Length(1), // h1
Constraint::Length(1), // h2
Constraint::Length(1), // Version
Constraint::Length(3), // protocol
Constraint::Length(3), // host
Constraint::Length(3), // port
Constraint::Length(3), // protocol
Constraint::Length(3), // username
Constraint::Length(3), // password
Constraint::Length(3), // footer
@@ -283,11 +283,11 @@ impl AuthActivity {
self.view
.render(super::COMPONENT_TEXT_NEW_VERSION, f, auth_chunks[2]);
self.view
.render(super::COMPONENT_INPUT_ADDR, f, auth_chunks[3]);
.render(super::COMPONENT_RADIO_PROTOCOL, f, auth_chunks[3]);
self.view
.render(super::COMPONENT_INPUT_PORT, f, auth_chunks[4]);
.render(super::COMPONENT_INPUT_ADDR, f, auth_chunks[4]);
self.view
.render(super::COMPONENT_RADIO_PROTOCOL, f, auth_chunks[5]);
.render(super::COMPONENT_INPUT_PORT, f, auth_chunks[5]);
self.view
.render(super::COMPONENT_INPUT_USERNAME, f, auth_chunks[6]);
self.view
@@ -716,53 +716,46 @@ impl AuthActivity {
///
/// Collect input values from view
pub(super) fn get_input(&self) -> (String, u16, FileTransferProtocol, String, String) {
let addr: String = match self.view.get_state(super::COMPONENT_INPUT_ADDR) {
Some(Payload::One(Value::Str(a))) => a,
_ => String::new(),
};
let port: u16 = match self.view.get_state(super::COMPONENT_INPUT_PORT) {
Some(Payload::One(Value::Usize(p))) => p as u16,
_ => 0,
};
let protocol: FileTransferProtocol =
match self.view.get_state(super::COMPONENT_RADIO_PROTOCOL) {
Some(Payload::One(Value::Usize(p))) => Self::protocol_opt_to_enum(p),
_ => FileTransferProtocol::Sftp,
};
let username: String = match self.view.get_state(super::COMPONENT_INPUT_USERNAME) {
Some(Payload::One(Value::Str(a))) => a,
_ => String::new(),
};
let password: String = match self.view.get_state(super::COMPONENT_INPUT_PASSWORD) {
Some(Payload::One(Value::Str(a))) => a,
_ => String::new(),
};
let addr: String = self.get_input_addr();
let port: u16 = self.get_input_port();
let protocol: FileTransferProtocol = self.get_input_protocol();
let username: String = self.get_input_username();
let password: String = self.get_input_password();
(addr, port, protocol, username, password)
}
// -- utils
pub(super) fn get_input_addr(&self) -> String {
match self.view.get_state(super::COMPONENT_INPUT_ADDR) {
Some(Payload::One(Value::Str(x))) => x,
_ => String::new(),
}
}
/// ### protocol_opt_to_enum
///
/// Convert radio index for protocol into a `FileTransferProtocol`
pub(crate) fn protocol_opt_to_enum(protocol: usize) -> FileTransferProtocol {
match protocol {
1 => FileTransferProtocol::Scp,
2 => FileTransferProtocol::Ftp(false),
3 => FileTransferProtocol::Ftp(true),
pub(super) fn get_input_port(&self) -> u16 {
match self.view.get_state(super::COMPONENT_INPUT_PORT) {
Some(Payload::One(Value::Usize(x))) => x as u16,
_ => Self::get_default_port_for_protocol(FileTransferProtocol::Sftp),
}
}
pub(super) fn get_input_protocol(&self) -> FileTransferProtocol {
match self.view.get_state(super::COMPONENT_RADIO_PROTOCOL) {
Some(Payload::One(Value::Usize(x))) => Self::protocol_opt_to_enum(x),
_ => FileTransferProtocol::Sftp,
}
}
/// ### protocol_enum_to_opt
///
/// Convert `FileTransferProtocol` enum into radio group index
pub(crate) fn protocol_enum_to_opt(protocol: FileTransferProtocol) -> usize {
match protocol {
FileTransferProtocol::Sftp => 0,
FileTransferProtocol::Scp => 1,
FileTransferProtocol::Ftp(false) => 2,
FileTransferProtocol::Ftp(true) => 3,
pub(super) fn get_input_username(&self) -> String {
match self.view.get_state(super::COMPONENT_INPUT_USERNAME) {
Some(Payload::One(Value::Str(x))) => x,
_ => String::new(),
}
}
pub(super) fn get_input_password(&self) -> String {
match self.view.get_state(super::COMPONENT_INPUT_PASSWORD) {
Some(Payload::One(Value::Str(x))) => x,
_ => String::new(),
}
}
}