285 feature request multi host (#293)

This commit is contained in:
Christian Visintin
2024-10-07 16:27:45 +02:00
committed by GitHub
parent a4c9acb49f
commit aab266a661
59 changed files with 5522 additions and 2651 deletions
+131 -53
View File
@@ -3,11 +3,12 @@
//! `auth_activity` is the module which implements the authentication activity
// Locals
use super::{AuthActivity, FileTransferParams};
use super::{AuthActivity, FileTransferParams, FormTab, HostBridgeProtocol};
use crate::filetransfer::params::{
AwsS3Params, GenericProtocolParams, KubeProtocolParams, ProtocolParams, SmbParams,
WebDAVProtocolParams,
};
use crate::filetransfer::HostBridgeParams;
impl AuthActivity {
/// Delete bookmark
@@ -26,27 +27,49 @@ impl AuthActivity {
}
/// Load selected bookmark (at index) to input fields
pub(super) fn load_bookmark(&mut self, idx: usize) {
pub(super) fn load_bookmark(&mut self, form_tab: FormTab, idx: usize) {
if let Some(bookmarks_cli) = self.bookmarks_client() {
// Iterate over bookmarks
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);
match form_tab {
FormTab::Remote => self.load_remote_bookmark_into_gui(bookmark),
FormTab::HostBridge => self.load_host_bridge_bookmark_into_gui(bookmark),
}
}
}
}
}
/// Save current input fields as a bookmark
pub(super) fn save_bookmark(&mut self, name: String, save_password: bool) {
let params = match self.collect_host_params() {
Ok(p) => p,
Err(e) => {
self.mount_error(e);
return;
}
pub(super) fn save_bookmark(&mut self, form_tab: FormTab, name: String, save_password: bool) {
let params = match form_tab {
FormTab::Remote => match self.collect_remote_host_params() {
Ok(p) => p,
Err(e) => {
self.mount_error(e);
return;
}
},
FormTab::HostBridge => match self.collect_host_bridge_params() {
Ok(HostBridgeParams::Remote(protocol, params)) => FileTransferParams {
protocol,
params,
remote_path: None,
local_path: None,
},
Ok(HostBridgeParams::Localhost(_)) => {
self.mount_error("You cannot save a localhost bookmark");
return;
}
Err(e) => {
self.mount_error(e);
return;
}
},
};
if let Some(bookmarks_cli) = self.bookmarks_client_mut() {
bookmarks_cli.add_bookmark(name.clone(), params, save_password);
// Save bookmarks
@@ -73,13 +96,16 @@ impl AuthActivity {
}
/// Load selected recent (at index) to input fields
pub(super) fn load_recent(&mut self, idx: usize) {
pub(super) fn load_recent(&mut self, form_tab: FormTab, idx: usize) {
if let Some(client) = self.bookmarks_client() {
// Iterate over bookmarks
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);
match form_tab {
FormTab::Remote => self.load_remote_bookmark_into_gui(bookmark),
FormTab::HostBridge => self.load_host_bridge_bookmark_into_gui(bookmark),
}
}
}
}
@@ -87,7 +113,7 @@ impl AuthActivity {
/// Save current input fields as a "recent"
pub(super) fn save_recent(&mut self) {
let params = match self.collect_host_params() {
let params = match self.collect_remote_host_params() {
Ok(p) => p,
Err(e) => {
self.mount_error(e);
@@ -147,73 +173,125 @@ impl AuthActivity {
}
/// Load bookmark data into the gui components
fn load_bookmark_into_gui(&mut self, bookmark: FileTransferParams) {
fn load_host_bridge_bookmark_into_gui(&mut self, bookmark: FileTransferParams) {
// Load parameters into components
self.protocol = bookmark.protocol;
self.mount_protocol(bookmark.protocol);
self.host_bridge_protocol = HostBridgeProtocol::Remote(bookmark.protocol);
self.mount_host_bridge_protocol(self.host_bridge_protocol);
self.mount_remote_directory(
FormTab::HostBridge,
bookmark
.remote_path
.map(|x| x.to_string_lossy().to_string())
.unwrap_or_default(),
);
self.mount_local_directory(
FormTab::HostBridge,
bookmark
.local_path
.map(|x| x.to_string_lossy().to_string())
.unwrap_or_default(),
);
match bookmark.params {
ProtocolParams::AwsS3(params) => self.load_bookmark_s3_into_gui(params),
ProtocolParams::Kube(params) => self.load_bookmark_kube_into_gui(params),
ProtocolParams::AwsS3(params) => {
self.load_bookmark_s3_into_gui(FormTab::HostBridge, params)
}
ProtocolParams::Kube(params) => {
self.load_bookmark_kube_into_gui(FormTab::HostBridge, params)
}
ProtocolParams::Generic(params) => self.load_bookmark_generic_into_gui(params),
ProtocolParams::Smb(params) => self.load_bookmark_smb_into_gui(params),
ProtocolParams::WebDAV(params) => self.load_bookmark_webdav_into_gui(params),
ProtocolParams::Generic(params) => {
self.load_bookmark_generic_into_gui(FormTab::HostBridge, params)
}
ProtocolParams::Smb(params) => {
self.load_bookmark_smb_into_gui(FormTab::HostBridge, params)
}
ProtocolParams::WebDAV(params) => {
self.load_bookmark_webdav_into_gui(FormTab::HostBridge, params)
}
}
}
fn load_bookmark_generic_into_gui(&mut self, params: GenericProtocolParams) {
self.mount_address(params.address.as_str());
self.mount_port(params.port);
self.mount_username(params.username.as_deref().unwrap_or(""));
self.mount_password(params.password.as_deref().unwrap_or(""));
/// Load bookmark data into the gui components
fn load_remote_bookmark_into_gui(&mut self, bookmark: FileTransferParams) {
// Load parameters into components
self.remote_protocol = bookmark.protocol;
self.mount_remote_protocol(bookmark.protocol);
self.mount_remote_directory(
FormTab::Remote,
bookmark
.remote_path
.map(|x| x.to_string_lossy().to_string())
.unwrap_or_default(),
);
self.mount_local_directory(
FormTab::Remote,
bookmark
.local_path
.map(|x| x.to_string_lossy().to_string())
.unwrap_or_default(),
);
match bookmark.params {
ProtocolParams::AwsS3(params) => {
self.load_bookmark_s3_into_gui(FormTab::Remote, params)
}
ProtocolParams::Kube(params) => {
self.load_bookmark_kube_into_gui(FormTab::Remote, params)
}
ProtocolParams::Generic(params) => {
self.load_bookmark_generic_into_gui(FormTab::Remote, params)
}
ProtocolParams::Smb(params) => self.load_bookmark_smb_into_gui(FormTab::Remote, params),
ProtocolParams::WebDAV(params) => {
self.load_bookmark_webdav_into_gui(FormTab::Remote, params)
}
}
}
fn load_bookmark_s3_into_gui(&mut self, params: AwsS3Params) {
self.mount_s3_bucket(params.bucket_name.as_str());
self.mount_s3_region(params.region.as_deref().unwrap_or(""));
self.mount_s3_endpoint(params.endpoint.as_deref().unwrap_or(""));
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(""));
self.mount_s3_new_path_style(params.new_path_style);
fn load_bookmark_generic_into_gui(&mut self, form_tab: FormTab, params: GenericProtocolParams) {
self.mount_address(form_tab, params.address.as_str());
self.mount_port(form_tab, params.port);
self.mount_username(form_tab, params.username.as_deref().unwrap_or(""));
self.mount_password(form_tab, params.password.as_deref().unwrap_or(""));
}
fn load_bookmark_kube_into_gui(&mut self, params: KubeProtocolParams) {
self.mount_kube_cluster_url(params.cluster_url.as_deref().unwrap_or(""));
self.mount_kube_namespace(params.namespace.as_deref().unwrap_or(""));
self.mount_kube_client_cert(params.client_cert.as_deref().unwrap_or(""));
self.mount_kube_client_key(params.client_key.as_deref().unwrap_or(""));
self.mount_kube_username(params.username.as_deref().unwrap_or(""));
fn load_bookmark_s3_into_gui(&mut self, form_tab: FormTab, params: AwsS3Params) {
self.mount_s3_bucket(form_tab, params.bucket_name.as_str());
self.mount_s3_region(form_tab, params.region.as_deref().unwrap_or(""));
self.mount_s3_endpoint(form_tab, params.endpoint.as_deref().unwrap_or(""));
self.mount_s3_profile(form_tab, params.profile.as_deref().unwrap_or(""));
self.mount_s3_access_key(form_tab, params.access_key.as_deref().unwrap_or(""));
self.mount_s3_secret_access_key(
form_tab,
params.secret_access_key.as_deref().unwrap_or(""),
);
self.mount_s3_security_token(form_tab, params.security_token.as_deref().unwrap_or(""));
self.mount_s3_session_token(form_tab, params.session_token.as_deref().unwrap_or(""));
self.mount_s3_new_path_style(form_tab, params.new_path_style);
}
fn load_bookmark_smb_into_gui(&mut self, params: SmbParams) {
self.mount_address(params.address.as_str());
fn load_bookmark_kube_into_gui(&mut self, form_tab: FormTab, params: KubeProtocolParams) {
self.mount_kube_cluster_url(form_tab, params.cluster_url.as_deref().unwrap_or(""));
self.mount_kube_namespace(form_tab, params.namespace.as_deref().unwrap_or(""));
self.mount_kube_client_cert(form_tab, params.client_cert.as_deref().unwrap_or(""));
self.mount_kube_client_key(form_tab, params.client_key.as_deref().unwrap_or(""));
self.mount_kube_username(form_tab, params.username.as_deref().unwrap_or(""));
}
fn load_bookmark_smb_into_gui(&mut self, form_tab: FormTab, params: SmbParams) {
self.mount_address(form_tab, params.address.as_str());
#[cfg(unix)]
self.mount_port(params.port);
self.mount_username(params.username.as_deref().unwrap_or(""));
self.mount_password(params.password.as_deref().unwrap_or(""));
self.mount_smb_share(&params.share);
self.mount_port(form_tab, params.port);
self.mount_username(form_tab, params.username.as_deref().unwrap_or(""));
self.mount_password(form_tab, params.password.as_deref().unwrap_or(""));
self.mount_smb_share(form_tab, &params.share);
#[cfg(unix)]
self.mount_smb_workgroup(params.workgroup.as_deref().unwrap_or(""));
self.mount_smb_workgroup(form_tab, params.workgroup.as_deref().unwrap_or(""));
}
fn load_bookmark_webdav_into_gui(&mut self, params: WebDAVProtocolParams) {
self.mount_webdav_uri(&params.uri);
self.mount_username(&params.username);
self.mount_password(&params.password);
fn load_bookmark_webdav_into_gui(&mut self, form_tab: FormTab, params: WebDAVProtocolParams) {
self.mount_webdav_uri(form_tab, &params.uri);
self.mount_username(form_tab, &params.username);
self.mount_password(form_tab, &params.password);
}
}
@@ -9,6 +9,7 @@ use tuirealm::props::{Alignment, BorderSides, BorderType, Borders, Color, InputT
use tuirealm::{Component, Event, MockComponent, NoUserEvent, State, StateValue};
use super::{FormMsg, Msg, UiMsg};
use crate::ui::activities::auth::FormTab;
// -- bookmark list
@@ -323,10 +324,11 @@ impl Component<Msg, NoUserEvent> for DeleteRecentPopup {
#[derive(MockComponent)]
pub struct BookmarkSavePassword {
component: Radio,
form_tab: FormTab,
}
impl BookmarkSavePassword {
pub fn new(color: Color) -> Self {
pub fn new(form_tab: FormTab, color: Color) -> Self {
Self {
component: Radio::default()
.borders(
@@ -340,6 +342,7 @@ impl BookmarkSavePassword {
.rewind(true)
.foreground(color)
.title("Save secrets?", Alignment::Center),
form_tab,
}
}
}
@@ -364,7 +367,7 @@ impl Component<Msg, NoUserEvent> for BookmarkSavePassword {
}
Event::Keyboard(KeyEvent {
code: Key::Enter, ..
}) => Some(Msg::Form(FormMsg::SaveBookmark)),
}) => Some(Msg::Form(FormMsg::SaveBookmark(self.form_tab))),
Event::Keyboard(KeyEvent { code: Key::Up, .. }) => {
Some(Msg::Ui(UiMsg::SaveBookmarkPasswordBlur))
}
@@ -378,10 +381,11 @@ impl Component<Msg, NoUserEvent> for BookmarkSavePassword {
#[derive(MockComponent)]
pub struct BookmarkName {
component: Input,
form_tab: FormTab,
}
impl BookmarkName {
pub fn new(color: Color) -> Self {
pub fn new(form_tab: FormTab, color: Color) -> Self {
Self {
component: Input::default()
.borders(
@@ -393,6 +397,7 @@ impl BookmarkName {
.foreground(color)
.title("Bookmark name", Alignment::Left)
.input_type(InputType::Text),
form_tab,
}
}
}
@@ -447,7 +452,7 @@ impl Component<Msg, NoUserEvent> for BookmarkName {
}
Event::Keyboard(KeyEvent {
code: Key::Enter, ..
}) => Some(Msg::Form(FormMsg::SaveBookmark)),
}) => Some(Msg::Form(FormMsg::SaveBookmark(self.form_tab))),
Event::Keyboard(KeyEvent {
code: Key::Down, ..
}) => Some(Msg::Ui(UiMsg::BookmarkNameBlur)),
File diff suppressed because it is too large Load Diff
+6 -5
View File
@@ -16,11 +16,12 @@ pub use bookmarks::{
#[cfg(unix)]
pub use form::InputSmbWorkgroup;
pub use form::{
InputAddress, InputKubeClientCert, InputKubeClientKey, InputKubeClusterUrl, InputKubeNamespace,
InputKubeUsername, InputLocalDirectory, InputPassword, InputPort, InputRemoteDirectory,
InputS3AccessKey, InputS3Bucket, InputS3Endpoint, InputS3Profile, InputS3Region,
InputS3SecretAccessKey, InputS3SecurityToken, InputS3SessionToken, InputSmbShare,
InputUsername, InputWebDAVUri, ProtocolRadio, RadioS3NewPathStyle,
HostBridgeProtocolRadio, InputAddress, InputKubeClientCert, InputKubeClientKey,
InputKubeClusterUrl, InputKubeNamespace, InputKubeUsername, InputLocalDirectory, InputPassword,
InputPort, InputRemoteDirectory, InputS3AccessKey, InputS3Bucket, InputS3Endpoint,
InputS3Profile, InputS3Region, InputS3SecretAccessKey, InputS3SecurityToken,
InputS3SessionToken, InputSmbShare, InputUsername, InputWebDAVUri, RadioS3NewPathStyle,
RemoteProtocolRadio,
};
pub use popup::{
ErrorPopup, InfoPopup, InstallUpdatePopup, Keybindings, QuitPopup, ReleaseNotes, WaitPopup,
@@ -100,6 +100,8 @@ impl HelpFooter {
TextSpan::from(" Change field "),
TextSpan::from("<TAB>").bold().fg(key_color),
TextSpan::from(" Switch tab "),
TextSpan::from("<BACKTAB>").bold().fg(key_color),
TextSpan::from(" Switch form "),
TextSpan::from("<ENTER>").bold().fg(key_color),
TextSpan::from(" Submit form "),
TextSpan::from("<F10|ESC>").bold().fg(key_color),
+82 -27
View File
@@ -2,8 +2,11 @@
//!
//! `auth_activity` is the module which implements the authentication activity
use super::{AuthActivity, FileTransferParams, FileTransferProtocol};
use std::env;
use super::{AuthActivity, FileTransferParams, FileTransferProtocol, FormTab, HostBridgeProtocol};
use crate::filetransfer::params::ProtocolParams;
use crate::filetransfer::HostBridgeParams;
use crate::system::auto_update::{Release, Update, UpdateStatus};
use crate::system::notifications::Notification;
@@ -36,24 +39,64 @@ impl AuthActivity {
}
/// Collect host params as `FileTransferParams`
pub(super) fn collect_host_params(&self) -> Result<FileTransferParams, &'static str> {
match self.protocol {
FileTransferProtocol::AwsS3 => self.collect_s3_host_params(),
FileTransferProtocol::Kube => self.collect_kube_host_params(),
FileTransferProtocol::Smb => self.collect_smb_host_params(),
pub(super) fn collect_host_bridge_params(&self) -> Result<HostBridgeParams, &'static str> {
match self.host_bridge_protocol {
HostBridgeProtocol::Localhost => self.collect_localhost_host_params(),
HostBridgeProtocol::Remote(remote) => {
let transfer_params = match remote {
FileTransferProtocol::AwsS3 => self.collect_s3_host_params(FormTab::HostBridge),
FileTransferProtocol::Kube => {
self.collect_kube_host_params(FormTab::HostBridge)
}
FileTransferProtocol::Smb => self.collect_smb_host_params(FormTab::HostBridge),
FileTransferProtocol::Ftp(_)
| FileTransferProtocol::Scp
| FileTransferProtocol::Sftp => {
self.collect_generic_host_params(remote, FormTab::HostBridge)
}
FileTransferProtocol::WebDAV => {
self.collect_webdav_host_params(FormTab::HostBridge)
}
}?;
Ok(HostBridgeParams::Remote(
transfer_params.protocol,
transfer_params.params,
))
}
}
}
/// Collect host params as `FileTransferParams`
pub(super) fn collect_remote_host_params(&self) -> Result<FileTransferParams, &'static str> {
match self.remote_protocol {
FileTransferProtocol::AwsS3 => self.collect_s3_host_params(FormTab::Remote),
FileTransferProtocol::Kube => self.collect_kube_host_params(FormTab::Remote),
FileTransferProtocol::Smb => self.collect_smb_host_params(FormTab::Remote),
FileTransferProtocol::Ftp(_)
| FileTransferProtocol::Scp
| FileTransferProtocol::Sftp => self.collect_generic_host_params(self.protocol),
FileTransferProtocol::WebDAV => self.collect_webdav_host_params(),
| FileTransferProtocol::Sftp => {
self.collect_generic_host_params(self.remote_protocol, FormTab::Remote)
}
FileTransferProtocol::WebDAV => self.collect_webdav_host_params(FormTab::Remote),
}
}
fn collect_localhost_host_params(&self) -> Result<HostBridgeParams, &'static str> {
let path = self
.get_input_local_directory(FormTab::HostBridge)
.unwrap_or_else(|| env::current_dir().unwrap_or_default());
Ok(HostBridgeParams::Localhost(path))
}
/// 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,
form_tab: FormTab,
) -> Result<FileTransferParams, &'static str> {
let params = self.get_generic_params_input();
let params = self.get_generic_params_input(form_tab);
if params.address.is_empty() {
return Err("Invalid host");
}
@@ -63,39 +106,48 @@ impl AuthActivity {
Ok(FileTransferParams {
protocol,
params: ProtocolParams::Generic(params),
local_path: self.get_input_local_directory(),
remote_path: self.get_input_remote_directory(),
local_path: self.get_input_local_directory(form_tab),
remote_path: self.get_input_remote_directory(form_tab),
})
}
/// 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 params = self.get_s3_params_input();
pub(super) fn collect_s3_host_params(
&self,
form_tab: FormTab,
) -> Result<FileTransferParams, &'static str> {
let params = self.get_s3_params_input(form_tab);
if params.bucket_name.is_empty() {
return Err("Invalid bucket");
}
Ok(FileTransferParams {
protocol: FileTransferProtocol::AwsS3,
params: ProtocolParams::AwsS3(params),
local_path: self.get_input_local_directory(),
remote_path: self.get_input_remote_directory(),
local_path: self.get_input_local_directory(form_tab),
remote_path: self.get_input_remote_directory(form_tab),
})
}
/// Get input values from fields or return an error if fields are invalid to work as aws s3
pub(super) fn collect_kube_host_params(&self) -> Result<FileTransferParams, &'static str> {
let params = self.get_kube_params_input();
pub(super) fn collect_kube_host_params(
&self,
form_tab: FormTab,
) -> Result<FileTransferParams, &'static str> {
let params = self.get_kube_params_input(form_tab);
Ok(FileTransferParams {
protocol: FileTransferProtocol::Kube,
params: ProtocolParams::Kube(params),
local_path: self.get_input_local_directory(),
remote_path: self.get_input_remote_directory(),
local_path: self.get_input_local_directory(form_tab),
remote_path: self.get_input_remote_directory(form_tab),
})
}
pub(super) fn collect_smb_host_params(&self) -> Result<FileTransferParams, &'static str> {
let params = self.get_smb_params_input();
pub(super) fn collect_smb_host_params(
&self,
form_tab: FormTab,
) -> Result<FileTransferParams, &'static str> {
let params = self.get_smb_params_input(form_tab);
if params.address.is_empty() {
return Err("Invalid address");
}
@@ -109,21 +161,24 @@ impl AuthActivity {
Ok(FileTransferParams {
protocol: FileTransferProtocol::Smb,
params: ProtocolParams::Smb(params),
local_path: self.get_input_local_directory(),
remote_path: self.get_input_remote_directory(),
local_path: self.get_input_local_directory(form_tab),
remote_path: self.get_input_remote_directory(form_tab),
})
}
pub(super) fn collect_webdav_host_params(&self) -> Result<FileTransferParams, &'static str> {
let params = self.get_webdav_params_input();
pub(super) fn collect_webdav_host_params(
&self,
form_tab: FormTab,
) -> Result<FileTransferParams, &'static str> {
let params = self.get_webdav_params_input(form_tab);
if params.uri.is_empty() {
return Err("Invalid URI");
}
Ok(FileTransferParams {
protocol: FileTransferProtocol::WebDAV,
params: ProtocolParams::WebDAV(params),
local_path: self.get_input_local_directory(),
remote_path: self.get_input_remote_directory(),
local_path: self.get_input_local_directory(form_tab),
remote_path: self.get_input_remote_directory(form_tab),
})
}
+98 -40
View File
@@ -23,20 +23,30 @@ use crate::filetransfer::{FileTransferParams, FileTransferProtocol};
use crate::system::bookmarks_client::BookmarksClient;
use crate::system::config_client::ConfigClient;
// radio
const RADIO_PROTOCOL_SFTP: usize = 0;
const RADIO_PROTOCOL_SCP: usize = 1;
const RADIO_PROTOCOL_FTP: usize = 2;
const RADIO_PROTOCOL_FTPS: usize = 3;
const RADIO_PROTOCOL_S3: usize = 4;
const RADIO_PROTOCOL_KUBE: usize = 5;
const RADIO_PROTOCOL_WEBDAV: usize = 6;
const RADIO_PROTOCOL_SMB: usize = 7;
// host bridge protocol radio
const HOST_BRIDGE_RADIO_PROTOCOL_LOCALHOST: usize = 0;
const HOST_BRIDGE_RADIO_PROTOCOL_SFTP: usize = 1;
const HOST_BRIDGE_RADIO_PROTOCOL_SCP: usize = 2;
const HOST_BRIDGE_RADIO_PROTOCOL_FTP: usize = 3;
const HOST_BRIDGE_RADIO_PROTOCOL_FTPS: usize = 4;
const HOST_BRIDGE_RADIO_PROTOCOL_S3: usize = 5;
const HOST_BRIDGE_RADIO_PROTOCOL_KUBE: usize = 6;
const HOST_BRIDGE_RADIO_PROTOCOL_WEBDAV: usize = 7;
const HOST_BRIDGE_RADIO_PROTOCOL_SMB: usize = 8; // Keep as last
// remote protocol radio
const REMOTE_RADIO_PROTOCOL_SFTP: usize = 0;
const REMOTE_RADIO_PROTOCOL_SCP: usize = 1;
const REMOTE_RADIO_PROTOCOL_FTP: usize = 2;
const REMOTE_RADIO_PROTOCOL_FTPS: usize = 3;
const REMOTE_RADIO_PROTOCOL_S3: usize = 4;
const REMOTE_RADIO_PROTOCOL_KUBE: usize = 5;
const REMOTE_RADIO_PROTOCOL_WEBDAV: usize = 6;
const REMOTE_RADIO_PROTOCOL_SMB: usize = 7; // Keep as last
// -- components
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub enum Id {
Address,
BookmarkName,
BookmarkSavePassword,
BookmarksList,
@@ -45,22 +55,33 @@ pub enum Id {
ErrorPopup,
GlobalListener,
HelpFooter,
HostBridge(AuthFormId),
InfoPopup,
InstallUpdatePopup,
Keybindings,
NewVersionChangelog,
NewVersionDisclaimer,
QuitPopup,
RecentsList,
Remote(AuthFormId),
Subtitle,
Title,
WaitPopup,
WindowSizeError,
}
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub enum AuthFormId {
Address,
KubeNamespace,
KubeClusterUrl,
KubeUsername,
KubeClientCert,
KubeClientKey,
LocalDirectory,
NewVersionChangelog,
NewVersionDisclaimer,
Password,
Port,
Protocol,
QuitPopup,
RecentsList,
RemoteDirectory,
S3AccessKey,
S3Bucket,
@@ -74,23 +95,19 @@ pub enum Id {
SmbShare,
#[cfg(unix)]
SmbWorkgroup,
Subtitle,
Title,
Username,
WaitPopup,
WebDAVUri,
WindowSizeError,
}
#[derive(Debug, Eq, PartialEq)]
pub enum Msg {
enum Msg {
Form(FormMsg),
Ui(UiMsg),
None,
}
#[derive(Debug, PartialEq, Eq)]
pub enum FormMsg {
enum FormMsg {
Connect,
DeleteBookmark,
DeleteRecent,
@@ -98,15 +115,14 @@ pub enum FormMsg {
InstallUpdate,
LoadBookmark(usize),
LoadRecent(usize),
ProtocolChanged(FileTransferProtocol),
HostBridgeProtocolChanged(HostBridgeProtocol),
RemoteProtocolChanged(FileTransferProtocol),
Quit,
SaveBookmark,
SaveBookmark(FormTab),
}
#[derive(Debug, PartialEq, Eq)]
pub enum UiMsg {
AddressBlurDown,
AddressBlurUp,
BookmarksListBlur,
BookmarksTabBlur,
CloseDeleteBookmark,
@@ -117,6 +133,25 @@ pub enum UiMsg {
CloseKeybindingsPopup,
CloseQuitPopup,
CloseSaveBookmark,
HostBridge(UiAuthFormMsg),
RececentsListBlur,
Remote(UiAuthFormMsg),
BookmarkNameBlur,
SaveBookmarkPasswordBlur,
ShowDeleteBookmarkPopup,
ShowDeleteRecentPopup,
ShowKeybindingsPopup,
ShowQuitPopup,
ShowReleaseNotes,
ShowSaveBookmarkPopup,
WindowResized,
}
#[derive(Debug, PartialEq, Eq)]
pub enum UiAuthFormMsg {
AddressBlurDown,
AddressBlurUp,
ChangeFormTab,
KubeNamespaceBlurDown,
KubeNamespaceBlurUp,
KubeClusterUrlBlurDown,
@@ -136,7 +171,6 @@ pub enum UiMsg {
PortBlurUp,
ProtocolBlurDown,
ProtocolBlurUp,
RececentsListBlur,
RemoteDirectoryBlurDown,
RemoteDirectoryBlurUp,
S3AccessKeyBlurDown,
@@ -163,19 +197,10 @@ pub enum UiMsg {
SmbWorkgroupDown,
#[cfg(unix)]
SmbWorkgroupUp,
BookmarkNameBlur,
SaveBookmarkPasswordBlur,
ShowDeleteBookmarkPopup,
ShowDeleteRecentPopup,
ShowKeybindingsPopup,
ShowQuitPopup,
ShowReleaseNotes,
ShowSaveBookmarkPopup,
UsernameBlurDown,
UsernameBlurUp,
WebDAVUriBlurDown,
WebDAVUriBlurUp,
WindowResized,
}
/// Auth form input mask
@@ -184,10 +209,23 @@ enum InputMask {
Generic,
AwsS3,
Kube,
Localhost,
Smb,
WebDAV,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum HostBridgeProtocol {
Localhost,
Remote(FileTransferProtocol),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum FormTab {
HostBridge,
Remote,
}
// Store keys
const STORE_KEY_LATEST_VERSION: &str = "AUTH_LATEST_VERSION";
const STORE_KEY_RELEASE_NOTES: &str = "AUTH_RELEASE_NOTES";
@@ -203,8 +241,11 @@ pub struct AuthActivity {
exit_reason: Option<ExitReason>,
/// Should redraw ui
redraw: bool,
/// Protocol
protocol: FileTransferProtocol,
/// Host bridge protocol
host_bridge_protocol: HostBridgeProtocol,
last_form_tab: FormTab,
/// Remote file transfer protocol
remote_protocol: FileTransferProtocol,
context: Option<Context>,
}
@@ -220,9 +261,11 @@ impl AuthActivity {
context: None,
bookmarks_list: Vec::new(),
exit_reason: None,
last_form_tab: FormTab::Remote,
recents_list: Vec::new(),
redraw: true,
protocol: FileTransferProtocol::Sftp,
host_bridge_protocol: HostBridgeProtocol::Localhost,
remote_protocol: FileTransferProtocol::Sftp,
}
}
@@ -255,8 +298,23 @@ impl AuthActivity {
}
/// Get current input mask to show
fn input_mask(&self) -> InputMask {
match self.protocol {
fn remote_input_mask(&self) -> InputMask {
Self::file_transfer_protocol_input_mask(self.remote_protocol)
}
/// Get current input mask to show
fn host_bridge_input_mask(&self) -> InputMask {
match self.host_bridge_protocol {
HostBridgeProtocol::Localhost => InputMask::Localhost,
HostBridgeProtocol::Remote(protocol) => {
Self::file_transfer_protocol_input_mask(protocol)
}
}
}
/// Get input mask for protocol
fn file_transfer_protocol_input_mask(protocol: FileTransferProtocol) -> InputMask {
match protocol {
FileTransferProtocol::AwsS3 => InputMask::AwsS3,
FileTransferProtocol::Ftp(_)
| FileTransferProtocol::Scp
@@ -275,7 +333,7 @@ impl Activity for AuthActivity {
fn on_create(&mut self, mut context: Context) {
debug!("Initializing activity");
// Initialize file transfer params
context.set_ftparams(FileTransferParams::default());
context.set_remote_params(FileTransferParams::default());
// Set context
self.context = Some(context);
// Clear terminal
+650 -175
View File
@@ -4,7 +4,10 @@
use tuirealm::{State, StateValue};
use super::{AuthActivity, ExitReason, FormMsg, Id, InputMask, Msg, UiMsg, Update};
use super::{
AuthActivity, AuthFormId, ExitReason, FormMsg, FormTab, HostBridgeProtocol, Id, InputMask, Msg,
UiAuthFormMsg, UiMsg, Update,
};
impl Update<Msg> for AuthActivity {
fn update(&mut self, msg: Option<Msg>) -> Option<Msg> {
@@ -21,19 +24,26 @@ impl AuthActivity {
fn update_form(&mut self, msg: FormMsg) -> Option<Msg> {
match msg {
FormMsg::Connect => {
match self.collect_host_params() {
Err(err) => {
// mount error
self.mount_error(err);
}
Ok(params) => {
self.save_recent();
// Set file transfer params to context
self.context_mut().set_ftparams(params);
// Set exit reason
self.exit_reason = Some(super::ExitReason::Connect);
}
}
let Ok(remote_params) = self.collect_remote_host_params() else {
// mount error
self.mount_error("Invalid remote params parameters");
return None;
};
let Ok(host_bridge_params) = self.collect_host_bridge_params() else {
// mount error
self.mount_error("Invalid host bridge params parameters");
return None;
};
self.save_recent();
// Set file transfer params to context
self.context_mut().set_remote_params(remote_params);
// set host bridge params
self.context_mut()
.set_host_bridge_params(host_bridge_params);
// Set exit reason
self.exit_reason = Some(super::ExitReason::Connect);
}
FormMsg::DeleteBookmark => {
if let Ok(State::One(StateValue::Usize(idx))) = self.app.state(&Id::BookmarksList) {
@@ -62,50 +72,86 @@ impl AuthActivity {
self.install_update();
}
FormMsg::LoadBookmark(i) => {
self.load_bookmark(i);
self.load_bookmark(self.last_form_tab, i);
// Give focus to input password (or to protocol if not generic)
assert!(self
.app
.active(match self.input_mask() {
InputMask::Generic => &Id::Password,
InputMask::Smb => &Id::Password,
InputMask::AwsS3 => &Id::S3Bucket,
InputMask::Kube => &Id::KubeNamespace,
InputMask::WebDAV => &Id::Password,
})
.is_ok());
let focus = match self.last_form_tab {
FormTab::Remote => match self.remote_input_mask() {
InputMask::Localhost => &Id::Remote(AuthFormId::LocalDirectory),
InputMask::Generic => &Id::Remote(AuthFormId::Password),
InputMask::Smb => &Id::Remote(AuthFormId::Password),
InputMask::AwsS3 => &Id::Remote(AuthFormId::S3Bucket),
InputMask::Kube => &Id::Remote(AuthFormId::KubeNamespace),
InputMask::WebDAV => &Id::Remote(AuthFormId::Password),
},
FormTab::HostBridge => match self.host_bridge_input_mask() {
InputMask::Localhost => &Id::HostBridge(AuthFormId::LocalDirectory),
InputMask::Generic => &Id::HostBridge(AuthFormId::Password),
InputMask::Smb => &Id::HostBridge(AuthFormId::Password),
InputMask::AwsS3 => &Id::HostBridge(AuthFormId::S3Bucket),
InputMask::Kube => &Id::HostBridge(AuthFormId::KubeNamespace),
InputMask::WebDAV => &Id::HostBridge(AuthFormId::Password),
},
};
assert!(self.app.active(focus).is_ok());
}
FormMsg::LoadRecent(i) => {
self.load_recent(i);
self.load_recent(self.last_form_tab, i);
// Give focus to input password (or to protocol if not generic)
assert!(self
.app
.active(match self.input_mask() {
InputMask::Generic => &Id::Password,
InputMask::Smb => &Id::Password,
InputMask::AwsS3 => &Id::S3Bucket,
InputMask::Kube => &Id::KubeNamespace,
InputMask::WebDAV => &Id::Password,
})
.is_ok());
let focus = match self.last_form_tab {
FormTab::Remote => match self.remote_input_mask() {
InputMask::Localhost => &Id::Remote(AuthFormId::LocalDirectory),
InputMask::Generic => &Id::Remote(AuthFormId::Password),
InputMask::Smb => &Id::Remote(AuthFormId::Password),
InputMask::AwsS3 => &Id::Remote(AuthFormId::S3Bucket),
InputMask::Kube => &Id::Remote(AuthFormId::KubeNamespace),
InputMask::WebDAV => &Id::Remote(AuthFormId::Password),
},
FormTab::HostBridge => match self.host_bridge_input_mask() {
InputMask::Localhost => &Id::HostBridge(AuthFormId::LocalDirectory),
InputMask::Generic => &Id::HostBridge(AuthFormId::Password),
InputMask::Smb => &Id::HostBridge(AuthFormId::Password),
InputMask::AwsS3 => &Id::HostBridge(AuthFormId::S3Bucket),
InputMask::Kube => &Id::HostBridge(AuthFormId::KubeNamespace),
InputMask::WebDAV => &Id::HostBridge(AuthFormId::Password),
},
};
assert!(self.app.active(focus).is_ok());
}
FormMsg::ProtocolChanged(protocol) => {
self.protocol = protocol;
FormMsg::HostBridgeProtocolChanged(protocol) => {
self.host_bridge_protocol = protocol;
// Update port
let port: u16 = self.get_input_port();
let port: u16 = self.get_input_port(FormTab::HostBridge);
if let HostBridgeProtocol::Remote(remote_protocol) = protocol {
if Self::is_port_standard(port) {
self.mount_port(
FormTab::HostBridge,
Self::get_default_port_for_protocol(remote_protocol),
);
}
}
}
FormMsg::RemoteProtocolChanged(protocol) => {
self.remote_protocol = protocol;
// Update port
let port: u16 = self.get_input_port(FormTab::Remote);
if Self::is_port_standard(port) {
self.mount_port(Self::get_default_port_for_protocol(protocol));
self.mount_port(
FormTab::Remote,
Self::get_default_port_for_protocol(protocol),
);
}
}
FormMsg::Quit => {
self.exit_reason = Some(ExitReason::Quit);
}
FormMsg::SaveBookmark => {
FormMsg::SaveBookmark(form_tab) => {
// get bookmark name
let (name, save_password) = self.get_new_bookmark();
// Save bookmark
if !name.is_empty() {
self.save_bookmark(name, save_password);
self.save_bookmark(form_tab, name, save_password);
}
// Umount popup
self.umount_bookmark_save_dialog();
@@ -118,16 +164,30 @@ impl AuthActivity {
fn update_ui(&mut self, msg: UiMsg) -> Option<Msg> {
match msg {
UiMsg::AddressBlurDown => {
let id = if cfg!(windows) && self.input_mask() == InputMask::Smb {
&Id::SmbShare
UiMsg::HostBridge(UiAuthFormMsg::AddressBlurDown) => {
let id = if cfg!(windows) && self.host_bridge_input_mask() == InputMask::Smb {
&Id::HostBridge(AuthFormId::SmbShare)
} else {
&Id::Port
&Id::HostBridge(AuthFormId::Port)
};
assert!(self.app.active(id).is_ok());
}
UiMsg::AddressBlurUp => {
assert!(self.app.active(&Id::Protocol).is_ok());
UiMsg::Remote(UiAuthFormMsg::AddressBlurDown) => {
let id = if cfg!(windows) && self.remote_input_mask() == InputMask::Smb {
&Id::Remote(AuthFormId::SmbShare)
} else {
&Id::Remote(AuthFormId::Port)
};
assert!(self.app.active(id).is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::AddressBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::Protocol))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::AddressBlurUp) => {
assert!(self.app.active(&Id::Remote(AuthFormId::Protocol)).is_ok());
}
UiMsg::BookmarksListBlur => {
assert!(self.app.active(&Id::RecentsList).is_ok());
@@ -136,7 +196,21 @@ impl AuthActivity {
assert!(self.app.active(&Id::BookmarkSavePassword).is_ok());
}
UiMsg::BookmarksTabBlur => {
assert!(self.app.active(&Id::Protocol).is_ok());
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::Protocol))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::ChangeFormTab) => {
self.last_form_tab = FormTab::Remote;
assert!(self.app.active(&Id::Remote(AuthFormId::Protocol)).is_ok());
}
UiMsg::Remote(UiAuthFormMsg::ChangeFormTab) => {
self.last_form_tab = FormTab::HostBridge;
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::Protocol))
.is_ok());
}
UiMsg::CloseDeleteBookmark => {
assert!(self.app.umount(&Id::DeleteBookmarkPopup).is_ok());
@@ -162,185 +236,554 @@ impl AuthActivity {
assert!(self.app.umount(&Id::BookmarkName).is_ok());
assert!(self.app.umount(&Id::BookmarkSavePassword).is_ok());
}
UiMsg::LocalDirectoryBlurDown => {
assert!(self.app.active(&Id::Protocol).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::LocalDirectoryBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::Protocol))
.is_ok());
}
UiMsg::LocalDirectoryBlurUp => {
assert!(self.app.active(&Id::RemoteDirectory).is_ok());
UiMsg::Remote(UiAuthFormMsg::LocalDirectoryBlurDown) => {
assert!(self.app.active(&Id::Remote(AuthFormId::Protocol)).is_ok());
}
UiMsg::ParamsFormBlur => {
UiMsg::HostBridge(UiAuthFormMsg::LocalDirectoryBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::RemoteDirectory))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::LocalDirectoryBlurUp) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::RemoteDirectory))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::ParamsFormBlur) => {
assert!(self.app.active(&Id::BookmarksList).is_ok());
}
UiMsg::PasswordBlurDown => {
UiMsg::Remote(UiAuthFormMsg::ParamsFormBlur) => {
assert!(self.app.active(&Id::BookmarksList).is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::PasswordBlurDown) => {
assert!(self
.app
.active(match self.input_mask() {
InputMask::Generic => &Id::RemoteDirectory,
.active(match self.host_bridge_input_mask() {
InputMask::Localhost => unreachable!(),
InputMask::Generic => &Id::HostBridge(AuthFormId::RemoteDirectory),
#[cfg(unix)]
InputMask::Smb => &Id::SmbWorkgroup,
InputMask::Smb => &Id::HostBridge(AuthFormId::SmbWorkgroup),
#[cfg(windows)]
InputMask::Smb => &Id::RemoteDirectory,
InputMask::AwsS3 => panic!("this shouldn't happen (password on s3)"),
InputMask::Kube => panic!("this shouldn't happen (password on kube)"),
InputMask::WebDAV => &Id::RemoteDirectory,
InputMask::Smb => &Id::HostBridge(AuthFormId::RemoteDirectory),
InputMask::AwsS3 => unreachable!("this shouldn't happen (password on s3)"),
InputMask::Kube => unreachable!("this shouldn't happen (password on kube)"),
InputMask::WebDAV => &Id::HostBridge(AuthFormId::RemoteDirectory),
})
.is_ok());
}
UiMsg::PasswordBlurUp => {
assert!(self.app.active(&Id::Username).is_ok());
}
UiMsg::PortBlurDown => {
UiMsg::Remote(UiAuthFormMsg::PasswordBlurDown) => {
assert!(self
.app
.active(match self.input_mask() {
InputMask::Generic => &Id::Username,
InputMask::Smb => &Id::SmbShare,
InputMask::AwsS3 | InputMask::Kube | InputMask::WebDAV =>
panic!("this shouldn't happen (port on s3/kube/webdav)"),
.active(match self.remote_input_mask() {
InputMask::Localhost => unreachable!(),
InputMask::Generic => &Id::Remote(AuthFormId::RemoteDirectory),
#[cfg(unix)]
InputMask::Smb => &Id::Remote(AuthFormId::SmbWorkgroup),
#[cfg(windows)]
InputMask::Smb => &Id::Remote(AuthFormId::RemoteDirectory),
InputMask::AwsS3 => unreachable!("this shouldn't happen (password on s3)"),
InputMask::Kube => unreachable!("this shouldn't happen (password on kube)"),
InputMask::WebDAV => &Id::Remote(AuthFormId::RemoteDirectory),
})
.is_ok());
}
UiMsg::PortBlurUp => {
assert!(self.app.active(&Id::Address).is_ok());
}
UiMsg::ProtocolBlurDown => {
UiMsg::HostBridge(UiAuthFormMsg::PasswordBlurUp) => {
assert!(self
.app
.active(match self.input_mask() {
InputMask::Generic => &Id::Address,
InputMask::Smb => &Id::Address,
InputMask::AwsS3 => &Id::S3Bucket,
InputMask::Kube => &Id::KubeNamespace,
InputMask::WebDAV => &Id::WebDAVUri,
.active(&Id::HostBridge(AuthFormId::Username))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::PasswordBlurUp) => {
assert!(self.app.active(&Id::Remote(AuthFormId::Username)).is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::PortBlurDown) => {
assert!(self
.app
.active(match self.host_bridge_input_mask() {
InputMask::Generic => &Id::HostBridge(AuthFormId::Username),
InputMask::Smb => &Id::HostBridge(AuthFormId::SmbShare),
InputMask::Localhost
| InputMask::AwsS3
| InputMask::Kube
| InputMask::WebDAV =>
unreachable!("this shouldn't happen (port on s3/kube/webdav)"),
})
.is_ok());
}
UiMsg::ProtocolBlurUp => {
assert!(self.app.active(&Id::LocalDirectory).is_ok());
UiMsg::Remote(UiAuthFormMsg::PortBlurDown) => {
assert!(self
.app
.active(match self.remote_input_mask() {
InputMask::Generic => &Id::Remote(AuthFormId::Username),
InputMask::Smb => &Id::Remote(AuthFormId::SmbShare),
InputMask::Localhost
| InputMask::AwsS3
| InputMask::Kube
| InputMask::WebDAV =>
unreachable!("this shouldn't happen (port on s3/kube/webdav)"),
})
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::PortBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::Address))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::PortBlurUp) => {
assert!(self.app.active(&Id::Remote(AuthFormId::Address)).is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::ProtocolBlurDown) => {
assert!(self
.app
.active(match self.host_bridge_input_mask() {
InputMask::Localhost => &Id::HostBridge(AuthFormId::LocalDirectory),
InputMask::Generic => &Id::HostBridge(AuthFormId::Address),
InputMask::Smb => &Id::HostBridge(AuthFormId::Address),
InputMask::AwsS3 => &Id::HostBridge(AuthFormId::S3Bucket),
InputMask::Kube => &Id::HostBridge(AuthFormId::KubeNamespace),
InputMask::WebDAV => &Id::HostBridge(AuthFormId::WebDAVUri),
})
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::ProtocolBlurDown) => {
assert!(self
.app
.active(match self.remote_input_mask() {
InputMask::Localhost => &Id::Remote(AuthFormId::LocalDirectory),
InputMask::Generic => &Id::Remote(AuthFormId::Address),
InputMask::Smb => &Id::Remote(AuthFormId::Address),
InputMask::AwsS3 => &Id::Remote(AuthFormId::S3Bucket),
InputMask::Kube => &Id::Remote(AuthFormId::KubeNamespace),
InputMask::WebDAV => &Id::Remote(AuthFormId::WebDAVUri),
})
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::ProtocolBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::LocalDirectory))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::ProtocolBlurUp) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::LocalDirectory))
.is_ok());
}
UiMsg::RececentsListBlur => {
assert!(self.app.active(&Id::BookmarksList).is_ok());
}
UiMsg::RemoteDirectoryBlurDown => {
assert!(self.app.active(&Id::LocalDirectory).is_ok());
}
UiMsg::RemoteDirectoryBlurUp => {
UiMsg::HostBridge(UiAuthFormMsg::RemoteDirectoryBlurDown) => {
assert!(self
.app
.active(match self.input_mask() {
InputMask::Generic => &Id::Password,
.active(&Id::HostBridge(AuthFormId::LocalDirectory))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::RemoteDirectoryBlurDown) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::LocalDirectory))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::RemoteDirectoryBlurUp) => {
assert!(self
.app
.active(match self.host_bridge_input_mask() {
InputMask::Localhost => unreachable!(),
InputMask::Generic => &Id::HostBridge(AuthFormId::Password),
#[cfg(unix)]
InputMask::Smb => &Id::SmbWorkgroup,
InputMask::Smb => &Id::HostBridge(AuthFormId::SmbWorkgroup),
#[cfg(windows)]
InputMask::Smb => &Id::Password,
InputMask::Kube => &Id::KubeClientKey,
InputMask::AwsS3 => &Id::S3NewPathStyle,
InputMask::WebDAV => &Id::Password,
InputMask::Smb => &Id::HostBridge(AuthFormId::Password),
InputMask::Kube => &Id::HostBridge(AuthFormId::KubeClientKey),
InputMask::AwsS3 => &Id::HostBridge(AuthFormId::S3NewPathStyle),
InputMask::WebDAV => &Id::HostBridge(AuthFormId::Password),
})
.is_ok());
}
UiMsg::S3BucketBlurDown => {
assert!(self.app.active(&Id::S3Region).is_ok());
UiMsg::Remote(UiAuthFormMsg::RemoteDirectoryBlurUp) => {
assert!(self
.app
.active(match self.remote_input_mask() {
InputMask::Localhost => unreachable!(),
InputMask::Generic => &Id::Remote(AuthFormId::Password),
#[cfg(unix)]
InputMask::Smb => &Id::Remote(AuthFormId::SmbWorkgroup),
#[cfg(windows)]
InputMask::Smb => &Id::Remote(AuthFormId::Password),
InputMask::Kube => &Id::Remote(AuthFormId::KubeClientKey),
InputMask::AwsS3 => &Id::Remote(AuthFormId::S3NewPathStyle),
InputMask::WebDAV => &Id::Remote(AuthFormId::Password),
})
.is_ok());
}
UiMsg::S3BucketBlurUp => {
assert!(self.app.active(&Id::Protocol).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3BucketBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3Region))
.is_ok());
}
UiMsg::S3RegionBlurDown => {
assert!(self.app.active(&Id::S3Endpoint).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3BucketBlurDown) => {
assert!(self.app.active(&Id::Remote(AuthFormId::S3Region)).is_ok());
}
UiMsg::S3RegionBlurUp => {
assert!(self.app.active(&Id::S3Bucket).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3BucketBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::Protocol))
.is_ok());
}
UiMsg::S3EndpointBlurDown => {
assert!(self.app.active(&Id::S3Profile).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3BucketBlurUp) => {
assert!(self.app.active(&Id::Remote(AuthFormId::Protocol)).is_ok());
}
UiMsg::S3EndpointBlurUp => {
assert!(self.app.active(&Id::S3Region).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3RegionBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3Endpoint))
.is_ok());
}
UiMsg::S3ProfileBlurDown => {
assert!(self.app.active(&Id::S3AccessKey).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3RegionBlurDown) => {
assert!(self.app.active(&Id::Remote(AuthFormId::S3Endpoint)).is_ok());
}
UiMsg::S3ProfileBlurUp => {
assert!(self.app.active(&Id::S3Endpoint).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3RegionBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3Bucket))
.is_ok());
}
UiMsg::S3AccessKeyBlurDown => {
assert!(self.app.active(&Id::S3SecretAccessKey).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3RegionBlurUp) => {
assert!(self.app.active(&Id::Remote(AuthFormId::S3Bucket)).is_ok());
}
UiMsg::S3AccessKeyBlurUp => {
assert!(self.app.active(&Id::S3Profile).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3EndpointBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3Profile))
.is_ok());
}
UiMsg::S3SecretAccessKeyBlurDown => {
assert!(self.app.active(&Id::S3SecurityToken).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3EndpointBlurDown) => {
assert!(self.app.active(&Id::Remote(AuthFormId::S3Profile)).is_ok());
}
UiMsg::S3SecretAccessKeyBlurUp => {
assert!(self.app.active(&Id::S3AccessKey).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3EndpointBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3Region))
.is_ok());
}
UiMsg::S3SecurityTokenBlurDown => {
assert!(self.app.active(&Id::S3SessionToken).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3EndpointBlurUp) => {
assert!(self.app.active(&Id::Remote(AuthFormId::S3Region)).is_ok());
}
UiMsg::S3SecurityTokenBlurUp => {
assert!(self.app.active(&Id::S3SecretAccessKey).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3ProfileBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3AccessKey))
.is_ok());
}
UiMsg::S3SessionTokenBlurDown => {
assert!(self.app.active(&Id::S3NewPathStyle).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3ProfileBlurDown) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::S3AccessKey))
.is_ok());
}
UiMsg::S3SessionTokenBlurUp => {
assert!(self.app.active(&Id::S3SecurityToken).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3ProfileBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3Endpoint))
.is_ok());
}
UiMsg::S3NewPathStyleBlurDown => {
assert!(self.app.active(&Id::RemoteDirectory).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3ProfileBlurUp) => {
assert!(self.app.active(&Id::Remote(AuthFormId::S3Endpoint)).is_ok());
}
UiMsg::S3NewPathStyleBlurUp => {
assert!(self.app.active(&Id::S3SessionToken).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3AccessKeyBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3SecretAccessKey))
.is_ok());
}
UiMsg::KubeClientCertBlurDown => {
assert!(self.app.active(&Id::KubeClientKey).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3AccessKeyBlurDown) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::S3SecretAccessKey))
.is_ok());
}
UiMsg::KubeClientCertBlurUp => {
assert!(self.app.active(&Id::KubeUsername).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3AccessKeyBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3Profile))
.is_ok());
}
UiMsg::KubeClientKeyBlurDown => {
assert!(self.app.active(&Id::RemoteDirectory).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3AccessKeyBlurUp) => {
assert!(self.app.active(&Id::Remote(AuthFormId::S3Profile)).is_ok());
}
UiMsg::KubeClientKeyBlurUp => {
assert!(self.app.active(&Id::KubeClientCert).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3SecretAccessKeyBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3SecurityToken))
.is_ok());
}
UiMsg::KubeNamespaceBlurDown => {
assert!(self.app.active(&Id::KubeClusterUrl).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3SecretAccessKeyBlurDown) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::S3SecurityToken))
.is_ok());
}
UiMsg::KubeNamespaceBlurUp => {
assert!(self.app.active(&Id::Protocol).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3SecretAccessKeyBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3AccessKey))
.is_ok());
}
UiMsg::KubeClusterUrlBlurDown => {
assert!(self.app.active(&Id::KubeUsername).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3SecretAccessKeyBlurUp) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::S3AccessKey))
.is_ok());
}
UiMsg::KubeClusterUrlBlurUp => {
assert!(self.app.active(&Id::KubeNamespace).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3SecurityTokenBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3SessionToken))
.is_ok());
}
UiMsg::KubeUsernameBlurDown => {
assert!(self.app.active(&Id::KubeClientCert).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3SecurityTokenBlurDown) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::S3SessionToken))
.is_ok());
}
UiMsg::KubeUsernameBlurUp => {
assert!(self.app.active(&Id::KubeClusterUrl).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::S3SecurityTokenBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3SecretAccessKey))
.is_ok());
}
UiMsg::SmbShareBlurDown => {
assert!(self.app.active(&Id::Username).is_ok());
UiMsg::Remote(UiAuthFormMsg::S3SecurityTokenBlurUp) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::S3SecretAccessKey))
.is_ok());
}
UiMsg::SmbShareBlurUp => {
let id = if cfg!(windows) && self.input_mask() == InputMask::Smb {
&Id::Address
UiMsg::HostBridge(UiAuthFormMsg::S3SessionTokenBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3NewPathStyle))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::S3SessionTokenBlurDown) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::S3NewPathStyle))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::S3SessionTokenBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3SecurityToken))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::S3SessionTokenBlurUp) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::S3SecurityToken))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::S3NewPathStyleBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::RemoteDirectory))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::S3NewPathStyleBlurDown) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::RemoteDirectory))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::S3NewPathStyleBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::S3SessionToken))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::S3NewPathStyleBlurUp) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::S3SessionToken))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::KubeClientCertBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::KubeClientKey))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::KubeClientCertBlurDown) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::KubeClientKey))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::KubeClientCertBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::KubeUsername))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::KubeClientCertBlurUp) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::KubeUsername))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::KubeClientKeyBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::RemoteDirectory))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::KubeClientKeyBlurDown) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::RemoteDirectory))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::KubeClientKeyBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::KubeClientCert))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::KubeClientKeyBlurUp) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::KubeClientCert))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::KubeNamespaceBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::KubeClusterUrl))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::KubeNamespaceBlurDown) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::KubeClusterUrl))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::KubeNamespaceBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::Protocol))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::KubeNamespaceBlurUp) => {
assert!(self.app.active(&Id::Remote(AuthFormId::Protocol)).is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::KubeClusterUrlBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::KubeUsername))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::KubeClusterUrlBlurDown) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::KubeUsername))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::KubeClusterUrlBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::KubeNamespace))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::KubeClusterUrlBlurUp) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::KubeNamespace))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::KubeUsernameBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::KubeClientCert))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::KubeUsernameBlurDown) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::KubeClientCert))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::KubeUsernameBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::KubeClusterUrl))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::KubeUsernameBlurUp) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::KubeClusterUrl))
.is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::SmbShareBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::Username))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::SmbShareBlurDown) => {
assert!(self.app.active(&Id::Remote(AuthFormId::Username)).is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::SmbShareBlurUp) => {
let id = if cfg!(windows) && self.host_bridge_input_mask() == InputMask::Smb {
&Id::HostBridge(AuthFormId::Address)
} else {
&Id::Port
&Id::HostBridge(AuthFormId::Port)
};
assert!(self.app.active(id).is_ok());
}
UiMsg::Remote(UiAuthFormMsg::SmbShareBlurUp) => {
let id = if cfg!(windows) && self.remote_input_mask() == InputMask::Smb {
&Id::Remote(AuthFormId::Address)
} else {
&Id::Remote(AuthFormId::Port)
};
assert!(self.app.active(id).is_ok());
}
#[cfg(unix)]
UiMsg::SmbWorkgroupDown => {
assert!(self.app.active(&Id::RemoteDirectory).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::SmbWorkgroupDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::RemoteDirectory))
.is_ok());
}
#[cfg(unix)]
UiMsg::SmbWorkgroupUp => {
assert!(self.app.active(&Id::Password).is_ok());
UiMsg::Remote(UiAuthFormMsg::SmbWorkgroupDown) => {
assert!(self
.app
.active(&Id::Remote(AuthFormId::RemoteDirectory))
.is_ok());
}
#[cfg(unix)]
UiMsg::HostBridge(UiAuthFormMsg::SmbWorkgroupUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::Password))
.is_ok());
}
#[cfg(unix)]
UiMsg::Remote(UiAuthFormMsg::SmbWorkgroupUp) => {
assert!(self.app.active(&Id::Remote(AuthFormId::Password)).is_ok());
}
UiMsg::SaveBookmarkPasswordBlur => {
assert!(self.app.active(&Id::BookmarkName).is_ok());
@@ -361,28 +804,60 @@ impl AuthActivity {
self.mount_release_notes();
}
UiMsg::ShowSaveBookmarkPopup => {
self.mount_bookmark_save_dialog();
self.mount_bookmark_save_dialog(self.get_current_form_tab());
}
UiMsg::UsernameBlurDown => {
assert!(self.app.active(&Id::Password).is_ok());
}
UiMsg::UsernameBlurUp => {
UiMsg::HostBridge(UiAuthFormMsg::UsernameBlurDown) => {
assert!(self
.app
.active(match self.input_mask() {
InputMask::Generic => &Id::Port,
InputMask::Smb => &Id::SmbShare,
InputMask::Kube => panic!("this shouldn't happen (username on kube)"),
InputMask::AwsS3 => panic!("this shouldn't happen (username on s3)"),
InputMask::WebDAV => &Id::WebDAVUri,
.active(&Id::HostBridge(AuthFormId::Password))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::UsernameBlurDown) => {
assert!(self.app.active(&Id::Remote(AuthFormId::Password)).is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::UsernameBlurUp) => {
assert!(self
.app
.active(match self.host_bridge_input_mask() {
InputMask::Localhost => unreachable!(),
InputMask::Generic => &Id::HostBridge(AuthFormId::Port),
InputMask::Smb => &Id::HostBridge(AuthFormId::SmbShare),
InputMask::Kube => unreachable!("this shouldn't happen (username on kube)"),
InputMask::AwsS3 => unreachable!("this shouldn't happen (username on s3)"),
InputMask::WebDAV => &Id::HostBridge(AuthFormId::WebDAVUri),
})
.is_ok());
}
UiMsg::WebDAVUriBlurDown => {
assert!(self.app.active(&Id::Username).is_ok());
UiMsg::Remote(UiAuthFormMsg::UsernameBlurUp) => {
assert!(self
.app
.active(match self.remote_input_mask() {
InputMask::Localhost => unreachable!(),
InputMask::Generic => &Id::Remote(AuthFormId::Port),
InputMask::Smb => &Id::Remote(AuthFormId::SmbShare),
InputMask::Kube => unreachable!("this shouldn't happen (username on kube)"),
InputMask::AwsS3 => unreachable!("this shouldn't happen (username on s3)"),
InputMask::WebDAV => &Id::Remote(AuthFormId::WebDAVUri),
})
.is_ok());
}
UiMsg::WebDAVUriBlurUp => {
assert!(self.app.active(&Id::Protocol).is_ok());
UiMsg::HostBridge(UiAuthFormMsg::WebDAVUriBlurDown) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::Username))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::WebDAVUriBlurDown) => {
assert!(self.app.active(&Id::Remote(AuthFormId::Username)).is_ok());
}
UiMsg::HostBridge(UiAuthFormMsg::WebDAVUriBlurUp) => {
assert!(self
.app
.active(&Id::HostBridge(AuthFormId::Protocol))
.is_ok());
}
UiMsg::Remote(UiAuthFormMsg::WebDAVUriBlurUp) => {
assert!(self.app.active(&Id::Remote(AuthFormId::Protocol)).is_ok());
}
UiMsg::WindowResized => {
self.redraw = true;
File diff suppressed because it is too large Load Diff