mirror of
https://github.com/veeso/termscp.git
synced 2026-07-25 00:57:18 +02:00
Aws s3 connection parameters extension (#89)
* Aws s3 connection parameters extension * Changed 'save password?' popup to 'change secrets?' * missing docs
This commit is contained in:
@@ -229,5 +229,9 @@ impl AuthActivity {
|
||||
self.mount_s3_bucket(params.bucket_name.as_str());
|
||||
self.mount_s3_region(params.region.as_str());
|
||||
self.mount_s3_profile(params.profile.as_deref().unwrap_or(""));
|
||||
self.mount_s3_access_key(params.access_key.as_deref().unwrap_or(""));
|
||||
self.mount_s3_secret_access_key(params.secret_access_key.as_deref().unwrap_or(""));
|
||||
self.mount_s3_security_token(params.security_token.as_deref().unwrap_or(""));
|
||||
self.mount_s3_session_token(params.session_token.as_deref().unwrap_or(""));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ impl BookmarkSavePassword {
|
||||
.value(0)
|
||||
.rewind(true)
|
||||
.foreground(color)
|
||||
.title("Save password?", Alignment::Center),
|
||||
.title("Save secrets?", Alignment::Center),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ impl Component<Msg, NoUserEvent> for InputAddress {
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
self.perform(Cmd::Type(ch));
|
||||
Some(Msg::None)
|
||||
@@ -263,7 +263,7 @@ impl Component<Msg, NoUserEvent> for InputPort {
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
self.perform(Cmd::Type(ch));
|
||||
Some(Msg::None)
|
||||
@@ -348,7 +348,7 @@ impl Component<Msg, NoUserEvent> for InputUsername {
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
self.perform(Cmd::Type(ch));
|
||||
Some(Msg::None)
|
||||
@@ -432,7 +432,7 @@ impl Component<Msg, NoUserEvent> for InputPassword {
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
self.perform(Cmd::Type(ch));
|
||||
Some(Msg::None)
|
||||
@@ -517,7 +517,7 @@ impl Component<Msg, NoUserEvent> for InputS3Bucket {
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
self.perform(Cmd::Type(ch));
|
||||
Some(Msg::None)
|
||||
@@ -537,7 +537,7 @@ impl Component<Msg, NoUserEvent> for InputS3Bucket {
|
||||
}
|
||||
}
|
||||
|
||||
// -- s3 bucket
|
||||
// -- s3 region
|
||||
|
||||
#[derive(MockComponent)]
|
||||
pub struct InputS3Region {
|
||||
@@ -602,7 +602,7 @@ impl Component<Msg, NoUserEvent> for InputS3Region {
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
self.perform(Cmd::Type(ch));
|
||||
Some(Msg::None)
|
||||
@@ -622,7 +622,7 @@ impl Component<Msg, NoUserEvent> for InputS3Region {
|
||||
}
|
||||
}
|
||||
|
||||
// -- s3 bucket
|
||||
// -- s3 profile
|
||||
|
||||
#[derive(MockComponent)]
|
||||
pub struct InputS3Profile {
|
||||
@@ -687,7 +687,7 @@ impl Component<Msg, NoUserEvent> for InputS3Profile {
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
self.perform(Cmd::Type(ch));
|
||||
Some(Msg::None)
|
||||
@@ -708,3 +708,342 @@ impl Component<Msg, NoUserEvent> for InputS3Profile {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- s3 access key
|
||||
|
||||
#[derive(MockComponent)]
|
||||
pub struct InputS3AccessKey {
|
||||
component: Input,
|
||||
}
|
||||
|
||||
impl InputS3AccessKey {
|
||||
pub fn new(access_key: &str, color: Color) -> Self {
|
||||
Self {
|
||||
component: Input::default()
|
||||
.borders(
|
||||
Borders::default()
|
||||
.color(color)
|
||||
.modifiers(BorderType::Rounded),
|
||||
)
|
||||
.foreground(color)
|
||||
.placeholder("AKIA...", Style::default().fg(Color::Rgb(128, 128, 128)))
|
||||
.title("Access key", Alignment::Left)
|
||||
.input_type(InputType::Text)
|
||||
.value(access_key),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component<Msg, NoUserEvent> for InputS3AccessKey {
|
||||
fn on(&mut self, ev: Event<NoUserEvent>) -> Option<Msg> {
|
||||
match ev {
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Left, ..
|
||||
}) => {
|
||||
self.perform(Cmd::Move(Direction::Left));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Right, ..
|
||||
}) => {
|
||||
self.perform(Cmd::Move(Direction::Right));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Home, ..
|
||||
}) => {
|
||||
self.perform(Cmd::GoTo(Position::Begin));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent { code: Key::End, .. }) => {
|
||||
self.perform(Cmd::GoTo(Position::End));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Delete, ..
|
||||
}) => {
|
||||
self.perform(Cmd::Cancel);
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Backspace,
|
||||
..
|
||||
}) => {
|
||||
self.perform(Cmd::Delete);
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
self.perform(Cmd::Type(ch));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Enter, ..
|
||||
}) => Some(Msg::Form(FormMsg::Connect)),
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Down, ..
|
||||
}) => Some(Msg::Ui(UiMsg::S3AccessKeyBlurDown)),
|
||||
Event::Keyboard(KeyEvent { code: Key::Up, .. }) => {
|
||||
Some(Msg::Ui(UiMsg::S3AccessKeyBlurUp))
|
||||
}
|
||||
Event::Keyboard(KeyEvent { code: Key::Tab, .. }) => {
|
||||
Some(Msg::Ui(UiMsg::ParamsFormBlur))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(MockComponent)]
|
||||
pub struct InputS3SecretAccessKey {
|
||||
component: Input,
|
||||
}
|
||||
|
||||
impl InputS3SecretAccessKey {
|
||||
pub fn new(secret_access_key: &str, color: Color) -> Self {
|
||||
Self {
|
||||
component: Input::default()
|
||||
.borders(
|
||||
Borders::default()
|
||||
.color(color)
|
||||
.modifiers(BorderType::Rounded),
|
||||
)
|
||||
.foreground(color)
|
||||
.title("Secret access key", Alignment::Left)
|
||||
.input_type(InputType::Password('*'))
|
||||
.value(secret_access_key),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component<Msg, NoUserEvent> for InputS3SecretAccessKey {
|
||||
fn on(&mut self, ev: Event<NoUserEvent>) -> Option<Msg> {
|
||||
match ev {
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Left, ..
|
||||
}) => {
|
||||
self.perform(Cmd::Move(Direction::Left));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Right, ..
|
||||
}) => {
|
||||
self.perform(Cmd::Move(Direction::Right));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Home, ..
|
||||
}) => {
|
||||
self.perform(Cmd::GoTo(Position::Begin));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent { code: Key::End, .. }) => {
|
||||
self.perform(Cmd::GoTo(Position::End));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Delete, ..
|
||||
}) => {
|
||||
self.perform(Cmd::Cancel);
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Backspace,
|
||||
..
|
||||
}) => {
|
||||
self.perform(Cmd::Delete);
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
self.perform(Cmd::Type(ch));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Enter, ..
|
||||
}) => Some(Msg::Form(FormMsg::Connect)),
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Down, ..
|
||||
}) => Some(Msg::Ui(UiMsg::S3SecretAccessKeyBlurDown)),
|
||||
Event::Keyboard(KeyEvent { code: Key::Up, .. }) => {
|
||||
Some(Msg::Ui(UiMsg::S3SecretAccessKeyBlurUp))
|
||||
}
|
||||
Event::Keyboard(KeyEvent { code: Key::Tab, .. }) => {
|
||||
Some(Msg::Ui(UiMsg::ParamsFormBlur))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(MockComponent)]
|
||||
pub struct InputS3SecurityToken {
|
||||
component: Input,
|
||||
}
|
||||
|
||||
impl InputS3SecurityToken {
|
||||
pub fn new(security_token: &str, color: Color) -> Self {
|
||||
Self {
|
||||
component: Input::default()
|
||||
.borders(
|
||||
Borders::default()
|
||||
.color(color)
|
||||
.modifiers(BorderType::Rounded),
|
||||
)
|
||||
.foreground(color)
|
||||
.title("Security token", Alignment::Left)
|
||||
.input_type(InputType::Password('*'))
|
||||
.value(security_token),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component<Msg, NoUserEvent> for InputS3SecurityToken {
|
||||
fn on(&mut self, ev: Event<NoUserEvent>) -> Option<Msg> {
|
||||
match ev {
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Left, ..
|
||||
}) => {
|
||||
self.perform(Cmd::Move(Direction::Left));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Right, ..
|
||||
}) => {
|
||||
self.perform(Cmd::Move(Direction::Right));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Home, ..
|
||||
}) => {
|
||||
self.perform(Cmd::GoTo(Position::Begin));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent { code: Key::End, .. }) => {
|
||||
self.perform(Cmd::GoTo(Position::End));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Delete, ..
|
||||
}) => {
|
||||
self.perform(Cmd::Cancel);
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Backspace,
|
||||
..
|
||||
}) => {
|
||||
self.perform(Cmd::Delete);
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
self.perform(Cmd::Type(ch));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Enter, ..
|
||||
}) => Some(Msg::Form(FormMsg::Connect)),
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Down, ..
|
||||
}) => Some(Msg::Ui(UiMsg::S3SecurityTokenBlurDown)),
|
||||
Event::Keyboard(KeyEvent { code: Key::Up, .. }) => {
|
||||
Some(Msg::Ui(UiMsg::S3SecurityTokenBlurUp))
|
||||
}
|
||||
Event::Keyboard(KeyEvent { code: Key::Tab, .. }) => {
|
||||
Some(Msg::Ui(UiMsg::ParamsFormBlur))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(MockComponent)]
|
||||
pub struct InputS3SessionToken {
|
||||
component: Input,
|
||||
}
|
||||
|
||||
impl InputS3SessionToken {
|
||||
pub fn new(session_token: &str, color: Color) -> Self {
|
||||
Self {
|
||||
component: Input::default()
|
||||
.borders(
|
||||
Borders::default()
|
||||
.color(color)
|
||||
.modifiers(BorderType::Rounded),
|
||||
)
|
||||
.foreground(color)
|
||||
.title("Session token", Alignment::Left)
|
||||
.input_type(InputType::Password('*'))
|
||||
.value(session_token),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component<Msg, NoUserEvent> for InputS3SessionToken {
|
||||
fn on(&mut self, ev: Event<NoUserEvent>) -> Option<Msg> {
|
||||
match ev {
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Left, ..
|
||||
}) => {
|
||||
self.perform(Cmd::Move(Direction::Left));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Right, ..
|
||||
}) => {
|
||||
self.perform(Cmd::Move(Direction::Right));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Home, ..
|
||||
}) => {
|
||||
self.perform(Cmd::GoTo(Position::Begin));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent { code: Key::End, .. }) => {
|
||||
self.perform(Cmd::GoTo(Position::End));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Delete, ..
|
||||
}) => {
|
||||
self.perform(Cmd::Cancel);
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Backspace,
|
||||
..
|
||||
}) => {
|
||||
self.perform(Cmd::Delete);
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
self.perform(Cmd::Type(ch));
|
||||
Some(Msg::None)
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Enter, ..
|
||||
}) => Some(Msg::Form(FormMsg::Connect)),
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Down, ..
|
||||
}) => Some(Msg::Ui(UiMsg::S3SessionTokenBlurDown)),
|
||||
Event::Keyboard(KeyEvent { code: Key::Up, .. }) => {
|
||||
Some(Msg::Ui(UiMsg::S3SessionTokenBlurUp))
|
||||
}
|
||||
Event::Keyboard(KeyEvent { code: Key::Tab, .. }) => {
|
||||
Some(Msg::Ui(UiMsg::ParamsFormBlur))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ pub use bookmarks::{
|
||||
RecentsList,
|
||||
};
|
||||
pub use form::{
|
||||
InputAddress, InputPassword, InputPort, InputS3Bucket, InputS3Profile, InputS3Region,
|
||||
InputAddress, InputPassword, InputPort, InputS3AccessKey, InputS3Bucket, InputS3Profile,
|
||||
InputS3Region, InputS3SecretAccessKey, InputS3SecurityToken, InputS3SessionToken,
|
||||
InputUsername, ProtocolRadio,
|
||||
};
|
||||
pub use popup::{
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
use super::{AuthActivity, FileTransferParams, FileTransferProtocol};
|
||||
use crate::filetransfer::params::{AwsS3Params, GenericProtocolParams, ProtocolParams};
|
||||
use crate::filetransfer::params::ProtocolParams;
|
||||
use crate::system::auto_update::{Release, Update, UpdateStatus};
|
||||
use crate::system::notifications::Notification;
|
||||
|
||||
@@ -68,46 +68,32 @@ impl AuthActivity {
|
||||
&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() {
|
||||
let params = self.get_generic_params_input();
|
||||
if params.address.is_empty() {
|
||||
return Err("Invalid host");
|
||||
}
|
||||
if port == 0 {
|
||||
if params.port == 0 {
|
||||
return Err("Invalid port");
|
||||
}
|
||||
Ok(FileTransferParams {
|
||||
protocol,
|
||||
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),
|
||||
}),
|
||||
),
|
||||
params: ProtocolParams::Generic(params),
|
||||
entry_directory: None,
|
||||
})
|
||||
}
|
||||
|
||||
/// 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) -> Result<FileTransferParams, &'static str> {
|
||||
let (bucket, region, profile): (String, String, Option<String>) =
|
||||
self.get_s3_params_input();
|
||||
if bucket.is_empty() {
|
||||
let params = self.get_s3_params_input();
|
||||
if params.bucket_name.is_empty() {
|
||||
return Err("Invalid bucket");
|
||||
}
|
||||
if region.is_empty() {
|
||||
if params.region.is_empty() {
|
||||
return Err("Invalid region");
|
||||
}
|
||||
Ok(FileTransferParams {
|
||||
protocol: FileTransferProtocol::AwsS3,
|
||||
params: ProtocolParams::AwsS3(AwsS3Params::new(bucket, region, profile)),
|
||||
params: ProtocolParams::AwsS3(params),
|
||||
entry_directory: None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -66,9 +66,13 @@ pub enum Id {
|
||||
Protocol,
|
||||
QuitPopup,
|
||||
RecentsList,
|
||||
S3AccessKey,
|
||||
S3Bucket,
|
||||
S3Profile,
|
||||
S3Region,
|
||||
S3SecretAccessKey,
|
||||
S3SecurityToken,
|
||||
S3SessionToken,
|
||||
Subtitle,
|
||||
Title,
|
||||
Username,
|
||||
@@ -119,12 +123,20 @@ pub enum UiMsg {
|
||||
ProtocolBlurDown,
|
||||
ProtocolBlurUp,
|
||||
RececentsListBlur,
|
||||
S3AccessKeyBlurDown,
|
||||
S3AccessKeyBlurUp,
|
||||
S3BucketBlurDown,
|
||||
S3BucketBlurUp,
|
||||
S3ProfileBlurDown,
|
||||
S3ProfileBlurUp,
|
||||
S3RegionBlurDown,
|
||||
S3RegionBlurUp,
|
||||
S3SecretAccessKeyBlurDown,
|
||||
S3SecretAccessKeyBlurUp,
|
||||
S3SecurityTokenBlurDown,
|
||||
S3SecurityTokenBlurUp,
|
||||
S3SessionTokenBlurDown,
|
||||
S3SessionTokenBlurUp,
|
||||
BookmarkNameBlur,
|
||||
SaveBookmarkPasswordBlur,
|
||||
ShowDeleteBookmarkPopup,
|
||||
|
||||
@@ -203,7 +203,7 @@ impl AuthActivity {
|
||||
.app
|
||||
.active(match self.input_mask() {
|
||||
InputMask::Generic => &Id::Password,
|
||||
InputMask::AwsS3 => &Id::S3Profile,
|
||||
InputMask::AwsS3 => &Id::S3SessionToken,
|
||||
})
|
||||
.is_ok());
|
||||
}
|
||||
@@ -223,11 +223,35 @@ impl AuthActivity {
|
||||
assert!(self.app.active(&Id::S3Bucket).is_ok());
|
||||
}
|
||||
UiMsg::S3ProfileBlurDown => {
|
||||
assert!(self.app.active(&Id::Protocol).is_ok());
|
||||
assert!(self.app.active(&Id::S3AccessKey).is_ok());
|
||||
}
|
||||
UiMsg::S3ProfileBlurUp => {
|
||||
assert!(self.app.active(&Id::S3Region).is_ok());
|
||||
}
|
||||
UiMsg::S3AccessKeyBlurDown => {
|
||||
assert!(self.app.active(&Id::S3SecretAccessKey).is_ok());
|
||||
}
|
||||
UiMsg::S3AccessKeyBlurUp => {
|
||||
assert!(self.app.active(&Id::S3Profile).is_ok());
|
||||
}
|
||||
UiMsg::S3SecretAccessKeyBlurDown => {
|
||||
assert!(self.app.active(&Id::S3SecurityToken).is_ok());
|
||||
}
|
||||
UiMsg::S3SecretAccessKeyBlurUp => {
|
||||
assert!(self.app.active(&Id::S3AccessKey).is_ok());
|
||||
}
|
||||
UiMsg::S3SecurityTokenBlurDown => {
|
||||
assert!(self.app.active(&Id::S3SessionToken).is_ok());
|
||||
}
|
||||
UiMsg::S3SecurityTokenBlurUp => {
|
||||
assert!(self.app.active(&Id::S3SecretAccessKey).is_ok());
|
||||
}
|
||||
UiMsg::S3SessionTokenBlurDown => {
|
||||
assert!(self.app.active(&Id::Protocol).is_ok());
|
||||
}
|
||||
UiMsg::S3SessionTokenBlurUp => {
|
||||
assert!(self.app.active(&Id::S3SecurityToken).is_ok());
|
||||
}
|
||||
UiMsg::SaveBookmarkPasswordBlur => {
|
||||
assert!(self.app.active(&Id::BookmarkName).is_ok());
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
*/
|
||||
// Locals
|
||||
use super::{components, AuthActivity, Context, FileTransferProtocol, Id, InputMask};
|
||||
use crate::filetransfer::params::ProtocolParams;
|
||||
use crate::filetransfer::params::{AwsS3Params, GenericProtocolParams, ProtocolParams};
|
||||
use crate::filetransfer::FileTransferParams;
|
||||
use crate::utils::ui::draw_area_in;
|
||||
|
||||
@@ -74,6 +74,10 @@ impl AuthActivity {
|
||||
self.mount_s3_bucket("");
|
||||
self.mount_s3_profile("");
|
||||
self.mount_s3_region("");
|
||||
self.mount_s3_access_key("");
|
||||
self.mount_s3_secret_access_key("");
|
||||
self.mount_s3_security_token("");
|
||||
self.mount_s3_session_token("");
|
||||
// Version notice
|
||||
if let Some(version) = self
|
||||
.context()
|
||||
@@ -158,6 +162,7 @@ impl AuthActivity {
|
||||
Constraint::Length(3), // bucket
|
||||
Constraint::Length(3), // region
|
||||
Constraint::Length(3), // profile
|
||||
Constraint::Length(3), // access_key
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
@@ -190,9 +195,11 @@ impl AuthActivity {
|
||||
// Render input mask
|
||||
match self.input_mask() {
|
||||
InputMask::AwsS3 => {
|
||||
self.app.view(&Id::S3Bucket, f, input_mask[0]);
|
||||
self.app.view(&Id::S3Region, f, input_mask[1]);
|
||||
self.app.view(&Id::S3Profile, f, input_mask[2]);
|
||||
let s3_view_ids = self.get_s3_view();
|
||||
self.app.view(&s3_view_ids[0], f, input_mask[0]);
|
||||
self.app.view(&s3_view_ids[1], f, input_mask[1]);
|
||||
self.app.view(&s3_view_ids[2], f, input_mask[2]);
|
||||
self.app.view(&s3_view_ids[3], f, input_mask[3]);
|
||||
}
|
||||
InputMask::Generic => {
|
||||
self.app.view(&Id::Address, f, input_mask[0]);
|
||||
@@ -653,23 +660,83 @@ impl AuthActivity {
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
pub(crate) fn mount_s3_access_key(&mut self, key: &str) {
|
||||
let password_color = self.theme().auth_password;
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::S3AccessKey,
|
||||
Box::new(components::InputS3AccessKey::new(key, password_color)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
pub(crate) fn mount_s3_secret_access_key(&mut self, key: &str) {
|
||||
let addr_color = self.theme().auth_address;
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::S3SecretAccessKey,
|
||||
Box::new(components::InputS3SecretAccessKey::new(key, addr_color)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
pub(crate) fn mount_s3_security_token(&mut self, token: &str) {
|
||||
let port_color = self.theme().auth_port;
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::S3SecurityToken,
|
||||
Box::new(components::InputS3SecurityToken::new(token, port_color)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
pub(crate) fn mount_s3_session_token(&mut self, token: &str) {
|
||||
let username_color = self.theme().auth_username;
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::S3SessionToken,
|
||||
Box::new(components::InputS3SessionToken::new(token, username_color)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
// -- query
|
||||
|
||||
/// Collect input values from view
|
||||
pub(super) fn get_generic_params_input(&self) -> (String, u16, String, String) {
|
||||
pub(super) fn get_generic_params_input(&self) -> GenericProtocolParams {
|
||||
let addr: String = self.get_input_addr();
|
||||
let port: u16 = self.get_input_port();
|
||||
let username: String = self.get_input_username();
|
||||
let password: String = self.get_input_password();
|
||||
(addr, port, username, password)
|
||||
let username = self.get_input_username();
|
||||
let password = self.get_input_password();
|
||||
GenericProtocolParams::default()
|
||||
.address(addr)
|
||||
.port(port)
|
||||
.username(username)
|
||||
.password(password)
|
||||
}
|
||||
|
||||
/// Collect s3 input values from view
|
||||
pub(super) fn get_s3_params_input(&self) -> (String, String, Option<String>) {
|
||||
pub(super) fn get_s3_params_input(&self) -> AwsS3Params {
|
||||
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)
|
||||
let access_key = self.get_input_s3_access_key();
|
||||
let secret_access_key = self.get_input_s3_secret_access_key();
|
||||
let security_token = self.get_input_s3_security_token();
|
||||
let session_token = self.get_input_s3_session_token();
|
||||
AwsS3Params::new(bucket, region, profile)
|
||||
.access_key(access_key)
|
||||
.secret_access_key(secret_access_key)
|
||||
.security_token(security_token)
|
||||
.session_token(session_token)
|
||||
}
|
||||
|
||||
pub(super) fn get_input_addr(&self) -> String {
|
||||
@@ -689,17 +756,17 @@ impl AuthActivity {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_input_username(&self) -> String {
|
||||
pub(super) fn get_input_username(&self) -> Option<String> {
|
||||
match self.app.state(&Id::Username) {
|
||||
Ok(State::One(StateValue::String(x))) => x,
|
||||
_ => String::new(),
|
||||
Ok(State::One(StateValue::String(x))) if !x.is_empty() => Some(x),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_input_password(&self) -> String {
|
||||
pub(super) fn get_input_password(&self) -> Option<String> {
|
||||
match self.app.state(&Id::Password) {
|
||||
Ok(State::One(StateValue::String(x))) => x,
|
||||
_ => String::new(),
|
||||
Ok(State::One(StateValue::String(x))) if !x.is_empty() => Some(x),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -724,6 +791,34 @@ impl AuthActivity {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_input_s3_access_key(&self) -> Option<String> {
|
||||
match self.app.state(&Id::S3AccessKey) {
|
||||
Ok(State::One(StateValue::String(x))) if !x.is_empty() => Some(x),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_input_s3_secret_access_key(&self) -> Option<String> {
|
||||
match self.app.state(&Id::S3SecretAccessKey) {
|
||||
Ok(State::One(StateValue::String(x))) if !x.is_empty() => Some(x),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_input_s3_security_token(&self) -> Option<String> {
|
||||
match self.app.state(&Id::S3SecurityToken) {
|
||||
Ok(State::One(StateValue::String(x))) if !x.is_empty() => Some(x),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_input_s3_session_token(&self) -> Option<String> {
|
||||
match self.app.state(&Id::S3SessionToken) {
|
||||
Ok(State::One(StateValue::String(x))) if !x.is_empty() => Some(x),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get new bookmark params
|
||||
pub(super) fn get_new_bookmark(&self) -> (String, bool) {
|
||||
let name = match self.app.state(&Id::BookmarkName) {
|
||||
@@ -745,7 +840,7 @@ impl AuthActivity {
|
||||
/// 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::AwsS3 => 12,
|
||||
InputMask::Generic => 12,
|
||||
}
|
||||
}
|
||||
@@ -785,6 +880,19 @@ impl AuthActivity {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the visible element in the aws-s3 form, based on current focus
|
||||
fn get_s3_view(&self) -> [Id; 4] {
|
||||
match self.app.focus() {
|
||||
Some(&Id::S3SecretAccessKey | &Id::S3SecurityToken | &Id::S3SessionToken) => [
|
||||
Id::S3AccessKey,
|
||||
Id::S3SecretAccessKey,
|
||||
Id::S3SecurityToken,
|
||||
Id::S3SessionToken,
|
||||
],
|
||||
_ => [Id::S3Bucket, Id::S3Region, Id::S3Profile, Id::S3AccessKey],
|
||||
}
|
||||
}
|
||||
|
||||
fn init_global_listener(&mut self) {
|
||||
use tuirealm::event::{Key, KeyEvent, KeyModifiers};
|
||||
assert!(self
|
||||
|
||||
@@ -240,7 +240,7 @@ impl Component<Msg, NoUserEvent> for SshHost {
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
self.perform(Cmd::Type(ch));
|
||||
Some(Msg::None)
|
||||
@@ -319,7 +319,7 @@ impl Component<Msg, NoUserEvent> for SshUsername {
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
self.perform(Cmd::Type(ch));
|
||||
Some(Msg::None)
|
||||
|
||||
@@ -895,7 +895,7 @@ impl Component<Msg, NoUserEvent> for InputColor {
|
||||
}
|
||||
Event::Keyboard(KeyEvent {
|
||||
code: Key::Char(ch),
|
||||
modifiers: KeyModifiers::NONE,
|
||||
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
|
||||
}) => {
|
||||
let result = self.perform(Cmd::Type(ch));
|
||||
self.update_color(result)
|
||||
|
||||
Reference in New Issue
Block a user