mirror of
https://github.com/veeso/termscp.git
synced 2025-12-07 09:36:00 -08:00
Aws s3 support
This commit is contained in:
@@ -26,14 +26,15 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
// Locals
|
||||
use super::{AuthActivity, FileTransferProtocol};
|
||||
use super::{AuthActivity, FileTransferParams};
|
||||
use crate::filetransfer::params::{AwsS3Params, GenericProtocolParams, ProtocolParams};
|
||||
use crate::system::bookmarks_client::BookmarksClient;
|
||||
use crate::system::environment;
|
||||
|
||||
// Ext
|
||||
use std::path::PathBuf;
|
||||
use tui_realm_stdlib::{input::InputPropsBuilder, radio::RadioPropsBuilder};
|
||||
use tuirealm::{Payload, PropsBuilder, Value};
|
||||
use tuirealm::PropsBuilder;
|
||||
|
||||
impl AuthActivity {
|
||||
/// ### del_bookmark
|
||||
@@ -62,9 +63,7 @@ impl AuthActivity {
|
||||
if let Some(key) = self.bookmarks_list.get(idx) {
|
||||
if let Some(bookmark) = bookmarks_cli.get_bookmark(key) {
|
||||
// Load parameters into components
|
||||
self.load_bookmark_into_gui(
|
||||
bookmark.0, bookmark.1, bookmark.2, bookmark.3, bookmark.4,
|
||||
);
|
||||
self.load_bookmark_into_gui(bookmark);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,20 +73,15 @@ impl AuthActivity {
|
||||
///
|
||||
/// Save current input fields as a bookmark
|
||||
pub(super) fn save_bookmark(&mut self, name: String, save_password: bool) {
|
||||
let (address, port, protocol, username, password) = self.get_input();
|
||||
let params = match self.collect_host_params() {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
self.mount_error(e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
if let Some(bookmarks_cli) = self.bookmarks_client.as_mut() {
|
||||
// Check if password must be saved
|
||||
let password: Option<String> = match save_password {
|
||||
true => match self
|
||||
.view
|
||||
.get_state(super::COMPONENT_RADIO_BOOKMARK_SAVE_PWD)
|
||||
{
|
||||
Some(Payload::One(Value::Usize(0))) => Some(password), // Yes
|
||||
_ => None, // No such component / No
|
||||
},
|
||||
false => None,
|
||||
};
|
||||
bookmarks_cli.add_bookmark(name.clone(), address, port, protocol, username, password);
|
||||
bookmarks_cli.add_bookmark(name.clone(), params, save_password);
|
||||
// Save bookmarks
|
||||
self.write_bookmarks();
|
||||
// Remove `name` from bookmarks if exists
|
||||
@@ -122,9 +116,7 @@ impl AuthActivity {
|
||||
if let Some(key) = self.recents_list.get(idx) {
|
||||
if let Some(bookmark) = client.get_recent(key) {
|
||||
// Load parameters
|
||||
self.load_bookmark_into_gui(
|
||||
bookmark.0, bookmark.1, bookmark.2, bookmark.3, None,
|
||||
);
|
||||
self.load_bookmark_into_gui(bookmark);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,9 +126,15 @@ impl AuthActivity {
|
||||
///
|
||||
/// Save current input fields as a "recent"
|
||||
pub(super) fn save_recent(&mut self) {
|
||||
let (address, port, protocol, username, _password) = self.get_input();
|
||||
let params = match self.collect_host_params() {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
self.mount_error(e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
if let Some(bookmarks_cli) = self.bookmarks_client.as_mut() {
|
||||
bookmarks_cli.add_recent(address, port, protocol, username);
|
||||
bookmarks_cli.add_recent(params);
|
||||
// Save bookmarks
|
||||
self.write_bookmarks();
|
||||
}
|
||||
@@ -234,40 +232,66 @@ impl AuthActivity {
|
||||
/// ### load_bookmark_into_gui
|
||||
///
|
||||
/// Load bookmark data into the gui components
|
||||
fn load_bookmark_into_gui(
|
||||
&mut self,
|
||||
addr: String,
|
||||
port: u16,
|
||||
protocol: FileTransferProtocol,
|
||||
username: String,
|
||||
password: Option<String>,
|
||||
) {
|
||||
fn load_bookmark_into_gui(&mut self, bookmark: FileTransferParams) {
|
||||
// Load parameters into components
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_RADIO_PROTOCOL) {
|
||||
let props = RadioPropsBuilder::from(props)
|
||||
.with_value(Self::protocol_enum_to_opt(bookmark.protocol))
|
||||
.build();
|
||||
self.view.update(super::COMPONENT_RADIO_PROTOCOL, props);
|
||||
}
|
||||
match bookmark.params {
|
||||
ProtocolParams::AwsS3(params) => self.load_bookmark_s3_into_gui(params),
|
||||
ProtocolParams::Generic(params) => self.load_bookmark_generic_into_gui(params),
|
||||
}
|
||||
}
|
||||
|
||||
fn load_bookmark_generic_into_gui(&mut self, params: GenericProtocolParams) {
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_INPUT_ADDR) {
|
||||
let props = InputPropsBuilder::from(props).with_value(addr).build();
|
||||
let props = InputPropsBuilder::from(props)
|
||||
.with_value(params.address.clone())
|
||||
.build();
|
||||
self.view.update(super::COMPONENT_INPUT_ADDR, props);
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_INPUT_PORT) {
|
||||
let props = InputPropsBuilder::from(props)
|
||||
.with_value(port.to_string())
|
||||
.with_value(params.port.to_string())
|
||||
.build();
|
||||
self.view.update(super::COMPONENT_INPUT_PORT, props);
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_RADIO_PROTOCOL) {
|
||||
let props = RadioPropsBuilder::from(props)
|
||||
.with_value(Self::protocol_enum_to_opt(protocol))
|
||||
.build();
|
||||
self.view.update(super::COMPONENT_RADIO_PROTOCOL, props);
|
||||
}
|
||||
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_INPUT_USERNAME) {
|
||||
let props = InputPropsBuilder::from(props).with_value(username).build();
|
||||
let props = InputPropsBuilder::from(props)
|
||||
.with_value(params.username.as_deref().unwrap_or_default().to_string())
|
||||
.build();
|
||||
self.view.update(super::COMPONENT_INPUT_USERNAME, props);
|
||||
}
|
||||
if let Some(password) = password {
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_INPUT_PASSWORD) {
|
||||
let props = InputPropsBuilder::from(props).with_value(password).build();
|
||||
self.view.update(super::COMPONENT_INPUT_PASSWORD, props);
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_INPUT_PASSWORD) {
|
||||
let props = InputPropsBuilder::from(props)
|
||||
.with_value(params.password.as_deref().unwrap_or_default().to_string())
|
||||
.build();
|
||||
self.view.update(super::COMPONENT_INPUT_PASSWORD, props);
|
||||
}
|
||||
}
|
||||
|
||||
fn load_bookmark_s3_into_gui(&mut self, params: AwsS3Params) {
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_INPUT_S3_BUCKET) {
|
||||
let props = InputPropsBuilder::from(props)
|
||||
.with_value(params.bucket_name.clone())
|
||||
.build();
|
||||
self.view.update(super::COMPONENT_INPUT_S3_BUCKET, props);
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_INPUT_S3_REGION) {
|
||||
let props = InputPropsBuilder::from(props)
|
||||
.with_value(params.region.clone())
|
||||
.build();
|
||||
self.view.update(super::COMPONENT_INPUT_S3_REGION, props);
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_INPUT_S3_PROFILE) {
|
||||
let props = InputPropsBuilder::from(props)
|
||||
.with_value(params.profile.as_deref().unwrap_or_default().to_string())
|
||||
.build();
|
||||
self.view.update(super::COMPONENT_INPUT_S3_PROFILE, props);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
use super::{AuthActivity, FileTransferParams, FileTransferProtocol};
|
||||
use crate::filetransfer::params::{AwsS3Params, GenericProtocolParams, ProtocolParams};
|
||||
|
||||
impl AuthActivity {
|
||||
/// ### protocol_opt_to_enum
|
||||
@@ -36,6 +37,7 @@ impl AuthActivity {
|
||||
1 => FileTransferProtocol::Scp,
|
||||
2 => FileTransferProtocol::Ftp(false),
|
||||
3 => FileTransferProtocol::Ftp(true),
|
||||
4 => FileTransferProtocol::AwsS3,
|
||||
_ => FileTransferProtocol::Sftp,
|
||||
}
|
||||
}
|
||||
@@ -49,6 +51,7 @@ impl AuthActivity {
|
||||
FileTransferProtocol::Scp => 1,
|
||||
FileTransferProtocol::Ftp(false) => 2,
|
||||
FileTransferProtocol::Ftp(true) => 3,
|
||||
FileTransferProtocol::AwsS3 => 4,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +62,7 @@ impl AuthActivity {
|
||||
match protocol {
|
||||
FileTransferProtocol::Sftp | FileTransferProtocol::Scp => 22,
|
||||
FileTransferProtocol::Ftp(_) => 21,
|
||||
FileTransferProtocol::AwsS3 => 22, // Doesn't matter, since not used
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,15 +87,24 @@ impl AuthActivity {
|
||||
|
||||
/// ### collect_host_params
|
||||
///
|
||||
/// Get input values from fields or return an error if fields are invalid
|
||||
/// Collect host params as `FileTransferParams`
|
||||
pub(super) fn collect_host_params(&self) -> Result<FileTransferParams, &'static str> {
|
||||
let (address, port, protocol, username, password): (
|
||||
String,
|
||||
u16,
|
||||
FileTransferProtocol,
|
||||
String,
|
||||
String,
|
||||
) = self.get_input();
|
||||
let protocol: FileTransferProtocol = self.get_protocol();
|
||||
match protocol {
|
||||
FileTransferProtocol::AwsS3 => self.collect_s3_host_params(protocol),
|
||||
protocol => self.collect_generic_host_params(protocol),
|
||||
}
|
||||
}
|
||||
|
||||
/// ### collect_generic_host_params
|
||||
///
|
||||
/// Get input values from fields or return an error if fields are invalid to work as generic
|
||||
pub(super) fn collect_generic_host_params(
|
||||
&self,
|
||||
protocol: FileTransferProtocol,
|
||||
) -> Result<FileTransferParams, &'static str> {
|
||||
let (address, port, username, password): (String, u16, String, String) =
|
||||
self.get_generic_params_input();
|
||||
if address.is_empty() {
|
||||
return Err("Invalid host");
|
||||
}
|
||||
@@ -99,17 +112,42 @@ impl AuthActivity {
|
||||
return Err("Invalid port");
|
||||
}
|
||||
Ok(FileTransferParams {
|
||||
address,
|
||||
port,
|
||||
protocol,
|
||||
username: match username.is_empty() {
|
||||
true => None,
|
||||
false => Some(username),
|
||||
},
|
||||
password: match password.is_empty() {
|
||||
true => None,
|
||||
false => Some(password),
|
||||
},
|
||||
params: ProtocolParams::Generic(
|
||||
GenericProtocolParams::default()
|
||||
.address(address)
|
||||
.port(port)
|
||||
.username(match username.is_empty() {
|
||||
true => None,
|
||||
false => Some(username),
|
||||
})
|
||||
.password(match password.is_empty() {
|
||||
true => None,
|
||||
false => Some(password),
|
||||
}),
|
||||
),
|
||||
entry_directory: None,
|
||||
})
|
||||
}
|
||||
|
||||
/// ### collect_s3_host_params
|
||||
///
|
||||
/// Get input values from fields or return an error if fields are invalid to work as aws s3
|
||||
pub(super) fn collect_s3_host_params(
|
||||
&self,
|
||||
protocol: FileTransferProtocol,
|
||||
) -> Result<FileTransferParams, &'static str> {
|
||||
let (bucket, region, profile): (String, String, Option<String>) =
|
||||
self.get_s3_params_input();
|
||||
if bucket.is_empty() {
|
||||
return Err("Invalid bucket");
|
||||
}
|
||||
if region.is_empty() {
|
||||
return Err("Invalid region");
|
||||
}
|
||||
Ok(FileTransferParams {
|
||||
protocol,
|
||||
params: ProtocolParams::AwsS3(AwsS3Params::new(bucket, region, profile)),
|
||||
entry_directory: None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -57,6 +57,9 @@ const COMPONENT_INPUT_PORT: &str = "INPUT_PORT";
|
||||
const COMPONENT_INPUT_USERNAME: &str = "INPUT_USERNAME";
|
||||
const COMPONENT_INPUT_PASSWORD: &str = "INPUT_PASSWORD";
|
||||
const COMPONENT_INPUT_BOOKMARK_NAME: &str = "INPUT_BOOKMARK_NAME";
|
||||
const COMPONENT_INPUT_S3_BUCKET: &str = "INPUT_S3_BUCKET";
|
||||
const COMPONENT_INPUT_S3_REGION: &str = "INPUT_S3_REGION";
|
||||
const COMPONENT_INPUT_S3_PROFILE: &str = "INPUT_S3_PROFILE";
|
||||
const COMPONENT_RADIO_PROTOCOL: &str = "RADIO_PROTOCOL";
|
||||
const COMPONENT_RADIO_QUIT: &str = "RADIO_QUIT";
|
||||
const COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK: &str = "RADIO_DELETE_BOOKMARK";
|
||||
@@ -163,6 +166,16 @@ impl AuthActivity {
|
||||
fn theme(&self) -> &Theme {
|
||||
self.context().theme_provider().theme()
|
||||
}
|
||||
|
||||
/// ### input_mask
|
||||
///
|
||||
/// Get current input mask to show
|
||||
fn input_mask(&self) -> InputMask {
|
||||
match self.get_protocol() {
|
||||
FileTransferProtocol::AwsS3 => InputMask::AwsS3,
|
||||
_ => InputMask::Generic,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Activity for AuthActivity {
|
||||
@@ -261,3 +274,12 @@ impl Activity for AuthActivity {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// ## InputMask
|
||||
///
|
||||
/// Auth form input mask
|
||||
#[derive(Eq, PartialEq)]
|
||||
enum InputMask {
|
||||
Generic,
|
||||
AwsS3,
|
||||
}
|
||||
|
||||
@@ -27,8 +27,9 @@
|
||||
*/
|
||||
// locals
|
||||
use super::{
|
||||
AuthActivity, FileTransferProtocol, COMPONENT_BOOKMARKS_LIST, COMPONENT_INPUT_ADDR,
|
||||
AuthActivity, FileTransferProtocol, InputMask, COMPONENT_BOOKMARKS_LIST, COMPONENT_INPUT_ADDR,
|
||||
COMPONENT_INPUT_BOOKMARK_NAME, COMPONENT_INPUT_PASSWORD, COMPONENT_INPUT_PORT,
|
||||
COMPONENT_INPUT_S3_BUCKET, COMPONENT_INPUT_S3_PROFILE, COMPONENT_INPUT_S3_REGION,
|
||||
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,
|
||||
@@ -53,54 +54,80 @@ impl Update for AuthActivity {
|
||||
Some(msg) => match msg {
|
||||
// Focus ( DOWN )
|
||||
(COMPONENT_RADIO_PROTOCOL, key) if key == &MSG_KEY_DOWN => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_ADDR);
|
||||
// Give focus based on current mask
|
||||
match self.input_mask() {
|
||||
InputMask::Generic => self.view.active(COMPONENT_INPUT_ADDR),
|
||||
InputMask::AwsS3 => self.view.active(COMPONENT_INPUT_S3_BUCKET),
|
||||
};
|
||||
None
|
||||
}
|
||||
// -- generic mask (DOWN)
|
||||
(COMPONENT_INPUT_ADDR, key) if key == &MSG_KEY_DOWN => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_PORT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_PORT, key) if key == &MSG_KEY_DOWN => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_USERNAME);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_USERNAME, key) if key == &MSG_KEY_DOWN => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_PASSWORD);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_PASSWORD, key) if key == &MSG_KEY_DOWN => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_RADIO_PROTOCOL);
|
||||
None
|
||||
}
|
||||
// -- s3 mask (DOWN)
|
||||
(COMPONENT_INPUT_S3_BUCKET, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_INPUT_S3_REGION);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_S3_REGION, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_INPUT_S3_PROFILE);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_S3_PROFILE, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_RADIO_PROTOCOL);
|
||||
None
|
||||
}
|
||||
// Focus ( UP )
|
||||
// -- generic (UP)
|
||||
(COMPONENT_INPUT_PASSWORD, key) if key == &MSG_KEY_UP => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_USERNAME);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_USERNAME, key) if key == &MSG_KEY_UP => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_PORT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_PORT, key) if key == &MSG_KEY_UP => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_ADDR);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_ADDR, key) if key == &MSG_KEY_UP => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_RADIO_PROTOCOL);
|
||||
None
|
||||
}
|
||||
// -- s3 (UP)
|
||||
(COMPONENT_INPUT_S3_BUCKET, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_RADIO_PROTOCOL);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_S3_REGION, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_INPUT_S3_BUCKET);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_S3_PROFILE, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_INPUT_S3_REGION);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_PROTOCOL, key) if key == &MSG_KEY_UP => {
|
||||
// Give focus to port
|
||||
self.view.active(COMPONENT_INPUT_PASSWORD);
|
||||
// Give focus based on current mask
|
||||
match self.input_mask() {
|
||||
InputMask::Generic => self.view.active(COMPONENT_INPUT_PASSWORD),
|
||||
InputMask::AwsS3 => self.view.active(COMPONENT_INPUT_S3_PROFILE),
|
||||
};
|
||||
None
|
||||
}
|
||||
// Protocol - On Change
|
||||
@@ -144,14 +171,20 @@ impl Update for AuthActivity {
|
||||
// Enter
|
||||
(COMPONENT_BOOKMARKS_LIST, Msg::OnSubmit(Payload::One(Value::Usize(idx)))) => {
|
||||
self.load_bookmark(*idx);
|
||||
// Give focus to input password
|
||||
self.view.active(COMPONENT_INPUT_PASSWORD);
|
||||
// Give focus to input password (or to protocol if not generic)
|
||||
self.view.active(match self.input_mask() {
|
||||
InputMask::Generic => COMPONENT_INPUT_PASSWORD,
|
||||
InputMask::AwsS3 => COMPONENT_INPUT_S3_BUCKET,
|
||||
});
|
||||
None
|
||||
}
|
||||
(COMPONENT_RECENTS_LIST, Msg::OnSubmit(Payload::One(Value::Usize(idx)))) => {
|
||||
self.load_recent(*idx);
|
||||
// Give focus to input password
|
||||
self.view.active(COMPONENT_INPUT_PASSWORD);
|
||||
self.view.active(match self.input_mask() {
|
||||
InputMask::Generic => COMPONENT_INPUT_PASSWORD,
|
||||
InputMask::AwsS3 => COMPONENT_INPUT_S3_BUCKET,
|
||||
});
|
||||
None
|
||||
}
|
||||
// Bookmark radio
|
||||
@@ -320,7 +353,7 @@ impl Update for AuthActivity {
|
||||
if key == &MSG_KEY_TAB =>
|
||||
{
|
||||
// Give focus to address
|
||||
self.view.active(COMPONENT_INPUT_ADDR);
|
||||
self.view.active(COMPONENT_RADIO_PROTOCOL);
|
||||
None
|
||||
}
|
||||
// Any <TAB>, go to bookmarks
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
// Locals
|
||||
use super::{AuthActivity, Context, FileTransferProtocol};
|
||||
use super::{AuthActivity, Context, FileTransferProtocol, InputMask};
|
||||
use crate::filetransfer::params::ProtocolParams;
|
||||
use crate::filetransfer::FileTransferParams;
|
||||
use crate::ui::components::bookmark_list::{BookmarkList, BookmarkListPropsBuilder};
|
||||
use crate::utils::ui::draw_area_in;
|
||||
// Ext
|
||||
@@ -109,7 +111,7 @@ impl AuthActivity {
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, protocol_color)
|
||||
.with_title("Protocol", Alignment::Left)
|
||||
.with_options(&["SFTP", "SCP", "FTP", "FTPS"])
|
||||
.with_options(&["SFTP", "SCP", "FTP", "FTPS", "AWS S3"])
|
||||
.with_value(Self::protocol_enum_to_opt(default_protocol))
|
||||
.rewind(true)
|
||||
.build(),
|
||||
@@ -163,6 +165,39 @@ impl AuthActivity {
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
// Bucket
|
||||
self.view.mount(
|
||||
super::COMPONENT_INPUT_S3_BUCKET,
|
||||
Box::new(Input::new(
|
||||
InputPropsBuilder::default()
|
||||
.with_foreground(addr_color)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, addr_color)
|
||||
.with_label("Bucket name", Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
// Region
|
||||
self.view.mount(
|
||||
super::COMPONENT_INPUT_S3_REGION,
|
||||
Box::new(Input::new(
|
||||
InputPropsBuilder::default()
|
||||
.with_foreground(port_color)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, port_color)
|
||||
.with_label("Region", Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
// Profile
|
||||
self.view.mount(
|
||||
super::COMPONENT_INPUT_S3_PROFILE,
|
||||
Box::new(Input::new(
|
||||
InputPropsBuilder::default()
|
||||
.with_foreground(username_color)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, username_color)
|
||||
.with_label("Profile", Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
// Version notice
|
||||
if let Some(version) = self
|
||||
.context()
|
||||
@@ -240,20 +275,43 @@ impl AuthActivity {
|
||||
let auth_chunks = Layout::default()
|
||||
.constraints(
|
||||
[
|
||||
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), // username
|
||||
Constraint::Length(3), // password
|
||||
Constraint::Length(3), // footer
|
||||
Constraint::Length(1), // h1
|
||||
Constraint::Length(1), // h2
|
||||
Constraint::Length(1), // Version
|
||||
Constraint::Length(3), // protocol
|
||||
Constraint::Length(self.input_mask_size()), // Input mask
|
||||
Constraint::Length(3), // footer
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.direction(Direction::Vertical)
|
||||
.split(chunks[0]);
|
||||
// Input mask chunks
|
||||
let input_mask = match self.input_mask() {
|
||||
InputMask::AwsS3 => Layout::default()
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Length(3), // bucket
|
||||
Constraint::Length(3), // region
|
||||
Constraint::Length(3), // profile
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.direction(Direction::Vertical)
|
||||
.split(auth_chunks[4]),
|
||||
InputMask::Generic => Layout::default()
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Length(3), // host
|
||||
Constraint::Length(3), // port
|
||||
Constraint::Length(3), // username
|
||||
Constraint::Length(3), // password
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.direction(Direction::Vertical)
|
||||
.split(auth_chunks[4]),
|
||||
};
|
||||
// Create bookmark chunks
|
||||
let bookmark_chunks = Layout::default()
|
||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
||||
@@ -269,16 +327,29 @@ impl AuthActivity {
|
||||
.render(super::COMPONENT_TEXT_NEW_VERSION, f, auth_chunks[2]);
|
||||
self.view
|
||||
.render(super::COMPONENT_RADIO_PROTOCOL, f, auth_chunks[3]);
|
||||
// Render input mask
|
||||
match self.input_mask() {
|
||||
InputMask::AwsS3 => {
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_S3_BUCKET, f, input_mask[0]);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_S3_REGION, f, input_mask[1]);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_S3_PROFILE, f, input_mask[2]);
|
||||
}
|
||||
InputMask::Generic => {
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_ADDR, f, input_mask[0]);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_PORT, f, input_mask[1]);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_USERNAME, f, input_mask[2]);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_PASSWORD, f, input_mask[3]);
|
||||
}
|
||||
}
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_ADDR, f, auth_chunks[4]);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_PORT, f, auth_chunks[5]);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_USERNAME, f, auth_chunks[6]);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_PASSWORD, f, auth_chunks[7]);
|
||||
self.view
|
||||
.render(super::COMPONENT_TEXT_FOOTER, f, auth_chunks[8]);
|
||||
.render(super::COMPONENT_TEXT_FOOTER, f, auth_chunks[5]);
|
||||
// Bookmark chunks
|
||||
self.view
|
||||
.render(super::COMPONENT_BOOKMARKS_LIST, f, bookmark_chunks[0]);
|
||||
@@ -388,19 +459,13 @@ impl AuthActivity {
|
||||
.bookmarks_list
|
||||
.iter()
|
||||
.map(|x| {
|
||||
let entry: (String, u16, FileTransferProtocol, String, _) = self
|
||||
.bookmarks_client
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get_bookmark(x)
|
||||
.unwrap();
|
||||
format!(
|
||||
"{} ({}://{}@{}:{})",
|
||||
Self::fmt_bookmark(
|
||||
x,
|
||||
entry.2.to_string().to_lowercase(),
|
||||
entry.3,
|
||||
entry.0,
|
||||
entry.1
|
||||
self.bookmarks_client
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get_bookmark(x)
|
||||
.unwrap(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
@@ -426,19 +491,12 @@ impl AuthActivity {
|
||||
.recents_list
|
||||
.iter()
|
||||
.map(|x| {
|
||||
let entry: (String, u16, FileTransferProtocol, String) = self
|
||||
.bookmarks_client
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get_recent(x)
|
||||
.unwrap();
|
||||
|
||||
format!(
|
||||
"{}://{}@{}:{}",
|
||||
entry.2.to_string().to_lowercase(),
|
||||
entry.3,
|
||||
entry.0,
|
||||
entry.1
|
||||
Self::fmt_recent(
|
||||
self.bookmarks_client
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get_recent(x)
|
||||
.unwrap(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
@@ -743,16 +801,32 @@ impl AuthActivity {
|
||||
self.view.umount(super::COMPONENT_TEXT_NEW_VERSION_NOTES);
|
||||
}
|
||||
|
||||
/// ### get_input
|
||||
/// ### get_protocol
|
||||
///
|
||||
/// Get protocol from view
|
||||
pub(super) fn get_protocol(&self) -> FileTransferProtocol {
|
||||
self.get_input_protocol()
|
||||
}
|
||||
|
||||
/// ### get_generic_params
|
||||
///
|
||||
/// Collect input values from view
|
||||
pub(super) fn get_input(&self) -> (String, u16, FileTransferProtocol, String, String) {
|
||||
pub(super) fn get_generic_params_input(&self) -> (String, u16, String, String) {
|
||||
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)
|
||||
(addr, port, username, password)
|
||||
}
|
||||
|
||||
/// ### get_s3_params_input
|
||||
///
|
||||
/// Collect s3 input values from view
|
||||
pub(super) fn get_s3_params_input(&self) -> (String, String, Option<String>) {
|
||||
let bucket: String = self.get_input_s3_bucket();
|
||||
let region: String = self.get_input_s3_region();
|
||||
let profile: Option<String> = self.get_input_s3_profile();
|
||||
(bucket, region, profile)
|
||||
}
|
||||
|
||||
pub(super) fn get_input_addr(&self) -> String {
|
||||
@@ -792,4 +866,75 @@ impl AuthActivity {
|
||||
_ => String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_input_s3_bucket(&self) -> String {
|
||||
match self.view.get_state(super::COMPONENT_INPUT_S3_BUCKET) {
|
||||
Some(Payload::One(Value::Str(x))) => x,
|
||||
_ => String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_input_s3_region(&self) -> String {
|
||||
match self.view.get_state(super::COMPONENT_INPUT_S3_REGION) {
|
||||
Some(Payload::One(Value::Str(x))) => x,
|
||||
_ => String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_input_s3_profile(&self) -> Option<String> {
|
||||
match self.view.get_state(super::COMPONENT_INPUT_S3_PROFILE) {
|
||||
Some(Payload::One(Value::Str(x))) => match x.is_empty() {
|
||||
true => None,
|
||||
false => Some(x),
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// ### input_mask_size
|
||||
///
|
||||
/// Returns the input mask size based on current input mask
|
||||
pub(super) fn input_mask_size(&self) -> u16 {
|
||||
match self.input_mask() {
|
||||
InputMask::AwsS3 => 9,
|
||||
InputMask::Generic => 12,
|
||||
}
|
||||
}
|
||||
|
||||
/// ### fmt_bookmark
|
||||
///
|
||||
/// Format bookmark to display on ui
|
||||
fn fmt_bookmark(name: &str, b: FileTransferParams) -> String {
|
||||
let addr: String = Self::fmt_recent(b);
|
||||
format!("{} ({})", name, addr)
|
||||
}
|
||||
|
||||
/// ### fmt_recent
|
||||
///
|
||||
/// Format recent connection to display on ui
|
||||
fn fmt_recent(b: FileTransferParams) -> String {
|
||||
let protocol: String = b.protocol.to_string().to_lowercase();
|
||||
match b.params {
|
||||
ProtocolParams::AwsS3(s3) => {
|
||||
let profile: String = match s3.profile {
|
||||
Some(p) => format!("[{}]", p),
|
||||
None => String::default(),
|
||||
};
|
||||
format!(
|
||||
"{}://{} ({}) {}",
|
||||
protocol, s3.bucket_name, s3.region, profile
|
||||
)
|
||||
}
|
||||
ProtocolParams::Generic(params) => {
|
||||
let username: String = match params.username {
|
||||
None => String::default(),
|
||||
Some(u) => format!("{}@", u),
|
||||
};
|
||||
format!(
|
||||
"{}://{}{}:{}",
|
||||
protocol, username, params.address, params.port
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user