termscp/src/ui/activities/auth/mod.rs

257 lines
8.5 KiB
Rust
Raw Normal View History

2020-12-15 09:21:52 +01:00
//! ## AuthActivity
//!
//! `auth_activity` is the module which implements the authentication activity
2021-03-26 22:25:10 +01:00
/**
* MIT License
*
* termscp - Copyright (c) 2021 Christian Visintin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
2020-12-15 09:21:52 +01:00
// Sub modules
2020-12-15 12:22:47 +01:00
mod bookmarks;
mod misc;
2021-03-09 21:52:11 +01:00
mod update;
2021-03-10 12:29:41 +01:00
mod view;
2020-12-15 09:21:52 +01:00
// locals
2021-03-21 17:16:52 +01:00
use super::{Activity, Context, ExitReason};
use crate::config::themes::Theme;
use crate::filetransfer::{FileTransferParams, FileTransferProtocol};
use crate::system::bookmarks_client::BookmarksClient;
2021-09-26 18:14:13 +02:00
use crate::system::config_client::ConfigClient;
2020-12-15 09:21:52 +01:00
// Includes
use crossterm::event::Event;
2020-12-15 09:21:52 +01:00
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
2021-06-06 14:19:20 +02:00
use tuirealm::{Update, View};
2020-12-15 12:28:06 +01:00
2021-03-09 21:52:11 +01:00
// -- components
const COMPONENT_TEXT_H1: &str = "TEXT_H1";
const COMPONENT_TEXT_H2: &str = "TEXT_H2";
2021-03-13 17:30:57 +01:00
const COMPONENT_TEXT_NEW_VERSION: &str = "TEXT_NEW_VERSION";
2021-06-26 18:00:03 +02:00
const COMPONENT_TEXT_NEW_VERSION_NOTES: &str = "TEXTAREA_NEW_VERSION";
2021-03-09 21:52:11 +01:00
const COMPONENT_TEXT_FOOTER: &str = "TEXT_FOOTER";
const COMPONENT_TEXT_HELP: &str = "TEXT_HELP";
const COMPONENT_TEXT_ERROR: &str = "TEXT_ERROR";
2021-09-10 22:22:15 +02:00
const COMPONENT_TEXT_INFO: &str = "TEXT_INFO";
const COMPONENT_TEXT_WAIT: &str = "TEXT_WAIT";
const COMPONENT_TEXT_SIZE_ERR: &str = "TEXT_SIZE_ERR";
2021-03-09 21:52:11 +01:00
const COMPONENT_INPUT_ADDR: &str = "INPUT_ADDRESS";
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";
2021-08-26 11:24:13 +02:00
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";
2021-03-09 21:52:11 +01:00
const COMPONENT_RADIO_PROTOCOL: &str = "RADIO_PROTOCOL";
2021-03-14 15:44:21 +01:00
const COMPONENT_RADIO_QUIT: &str = "RADIO_QUIT";
2021-03-10 12:10:36 +01:00
const COMPONENT_RADIO_BOOKMARK_DEL_BOOKMARK: &str = "RADIO_DELETE_BOOKMARK";
const COMPONENT_RADIO_BOOKMARK_DEL_RECENT: &str = "RADIO_DELETE_RECENT";
2021-03-09 21:52:11 +01:00
const COMPONENT_RADIO_BOOKMARK_SAVE_PWD: &str = "RADIO_SAVE_PASSWORD";
2021-09-10 22:22:15 +02:00
const COMPONENT_RADIO_INSTALL_UPDATE: &str = "RADIO_INSTALL_UPDATE";
2021-03-09 21:52:11 +01:00
const COMPONENT_BOOKMARKS_LIST: &str = "BOOKMARKS_LIST";
const COMPONENT_RECENTS_LIST: &str = "RECENTS_LIST";
2021-03-08 14:20:13 +01:00
// Store keys
const STORE_KEY_LATEST_VERSION: &str = "AUTH_LATEST_VERSION";
2021-06-26 18:00:03 +02:00
const STORE_KEY_RELEASE_NOTES: &str = "AUTH_RELEASE_NOTES";
2021-03-08 14:20:13 +01:00
2020-12-15 09:21:52 +01:00
/// ### AuthActivity
///
/// AuthActivity is the data holder for the authentication activity
pub struct AuthActivity {
2021-03-21 17:16:52 +01:00
exit_reason: Option<ExitReason>,
2020-12-15 09:21:52 +01:00
context: Option<Context>,
2021-03-09 21:52:11 +01:00
view: View,
bookmarks_client: Option<BookmarksClient>,
redraw: bool, // Should ui actually be redrawned?
bookmarks_list: Vec<String>, // List of bookmarks
recents_list: Vec<String>, // list of recents
2020-12-15 09:21:52 +01:00
}
impl Default for AuthActivity {
fn default() -> Self {
Self::new()
}
}
impl AuthActivity {
/// ### new
///
/// Instantiates a new AuthActivity
pub fn new() -> AuthActivity {
AuthActivity {
2021-03-21 17:16:52 +01:00
exit_reason: None,
2020-12-15 09:21:52 +01:00
context: None,
2021-03-09 21:52:11 +01:00
view: View::init(),
bookmarks_client: None,
2020-12-15 09:21:52 +01:00
redraw: true, // True at startup
bookmarks_list: Vec::new(),
recents_list: Vec::new(),
2020-12-24 18:47:00 +01:00
}
}
2021-07-08 15:43:23 +02:00
/// ### context
///
/// Returns a reference to context
fn context(&self) -> &Context {
self.context.as_ref().unwrap()
}
/// ### context_mut
///
/// Returns a mutable reference to context
fn context_mut(&mut self) -> &mut Context {
self.context.as_mut().unwrap()
}
2021-09-26 18:14:13 +02:00
/// ### config
///
/// Returns config client reference
fn config(&self) -> &ConfigClient {
self.context().config()
}
/// ### theme
///
/// Returns a reference to theme
fn theme(&self) -> &Theme {
2021-07-08 15:43:23 +02:00
self.context().theme_provider().theme()
}
2021-08-26 11:24:13 +02:00
/// ### input_mask
///
/// Get current input mask to show
fn input_mask(&self) -> InputMask {
match self.get_protocol() {
FileTransferProtocol::AwsS3 => InputMask::AwsS3,
_ => InputMask::Generic,
}
}
2020-12-15 09:21:52 +01:00
}
impl Activity for AuthActivity {
/// ### on_create
///
/// `on_create` is the function which must be called to initialize the activity.
/// `on_create` must initialize all the data structures used by the activity
/// Context is taken from activity manager and will be released only when activity is destroyed
fn on_create(&mut self, mut context: Context) {
2021-05-17 22:15:20 +02:00
debug!("Initializing activity");
// Initialize file transfer params
2021-07-08 15:43:23 +02:00
context.set_ftparams(FileTransferParams::default());
2020-12-15 09:21:52 +01:00
// Set context
self.context = Some(context);
// Clear terminal
2021-07-08 15:43:23 +02:00
self.context_mut().clear_screen();
2020-12-15 09:21:52 +01:00
// Put raw mode on enabled
2021-05-17 22:15:20 +02:00
if let Err(err) = enable_raw_mode() {
error!("Failed to enter raw mode: {}", err);
}
// If check for updates is enabled, check for updates
self.check_for_updates();
2021-05-21 12:31:30 +02:00
// Initialize view
self.init();
// Init bookmarks client
if self.bookmarks_client.is_none() {
self.init_bookmarks_client();
// View bookarmsk
self.view_bookmarks();
self.view_recent_connections();
2020-12-15 12:22:47 +01:00
}
2021-03-08 12:01:40 +01:00
// Verify error state from context
2021-07-08 15:43:23 +02:00
if let Some(err) = self.context_mut().error() {
self.mount_error(err.as_str());
2020-12-24 18:47:00 +01:00
}
2021-05-17 22:15:20 +02:00
info!("Activity initialized");
2020-12-15 09:21:52 +01:00
}
/// ### on_draw
///
/// `on_draw` is the function which draws the graphical interface.
/// This function must be called at each tick to refresh the interface
fn on_draw(&mut self) {
// Context must be something
if self.context.is_none() {
return;
}
2020-12-15 13:44:51 +01:00
// Read one event
2021-07-08 15:43:23 +02:00
if let Ok(Some(event)) = self.context().input_hnd().read_event() {
2021-02-27 20:49:20 +01:00
// Set redraw to true
self.redraw = true;
// Handle on resize
if let Event::Resize(_, h) = event {
self.check_minimum_window_size(h);
}
2021-03-10 12:29:41 +01:00
// Handle event on view and update
let msg = self.view.on(event);
self.update(msg);
2020-12-15 09:21:52 +01:00
}
// Redraw if necessary
if self.redraw {
2021-03-10 12:29:41 +01:00
// View
self.view();
2020-12-15 09:21:52 +01:00
// Set redraw to false
self.redraw = false;
}
}
2021-03-21 17:16:52 +01:00
/// ### will_umount
2021-03-26 20:38:47 +01:00
///
2021-03-21 17:16:52 +01:00
/// `will_umount` is the method which must be able to report to the activity manager, whether
/// the activity should be terminated or not.
/// If not, the call will return `None`, otherwise return`Some(ExitReason)`
fn will_umount(&self) -> Option<&ExitReason> {
self.exit_reason.as_ref()
}
2020-12-15 09:21:52 +01:00
/// ### on_destroy
///
/// `on_destroy` is the function which cleans up runtime variables and data before terminating the activity.
/// This function must be called once before terminating the activity.
/// This function finally releases the context
fn on_destroy(&mut self) -> Option<Context> {
// Disable raw mode
2021-05-17 22:15:20 +02:00
if let Err(err) = disable_raw_mode() {
error!("Failed to disable raw mode: {}", err);
}
2020-12-15 09:21:52 +01:00
self.context.as_ref()?;
// Clear terminal and return
match self.context.take() {
Some(mut ctx) => {
2020-12-19 21:47:03 +01:00
ctx.clear_screen();
2020-12-15 09:21:52 +01:00
Some(ctx)
}
None => None,
}
}
}
2021-08-26 11:24:13 +02:00
/// ## InputMask
///
/// Auth form input mask
#[derive(Eq, PartialEq)]
enum InputMask {
Generic,
AwsS3,
}