Working on AuthActivity

This commit is contained in:
ChristianVisintin
2020-11-21 21:26:27 +01:00
parent 818408455e
commit 5eb1ace958
4 changed files with 213 additions and 2 deletions

1
docs/drawio/UI.drawio Normal file
View File

@@ -0,0 +1 @@
<mxfile host="Electron" modified="2020-11-21T19:08:13.709Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.3.1 Chrome/83.0.4103.119 Electron/9.0.5 Safari/537.36" etag="CH09h_mpCNwCuwQp3CzT" version="13.3.1" type="device" pages="2"><diagram id="SlpWaeKyUTlHltKKkHdB" name="ScpActivity">7ZlRk5owEMc/DY/HABGEx2rv2pnWmXaczj3nJEKmgdAQD+yn7wJBoOhUrbbcTHwx2SSb5L+/4EoMtEzKDwJn8YqHhBmOFZYGem84ju26FnxVln1j8QO3MUSChqpTZ1jTn0QZ1bhoR0OSDzpKzpmk2dC44WlKNnJgw0LwYthty9lw1gxHZGRYbzAbW59pKGO1C2fe2T8SGsXtzLYXNC0JbjurneQxDnnRM6FHAy0F57IpJeWSsEq8Vpdm3NOJ1sPCBEnlOQOyRbEsv31ixSv+vi6c588r9vXBaby8YrZTG1aLlftWAcF3aUgqJ5aBFkVMJVlneFO1FhBzsMUyYVCzobiljC054wLqKU+h00LNQIQk5cml2wdBgCTCEyLFHrqoAchEqBmzH9JRdCFBgWd6KipxLyJopvpiRUJ0cN+JBQWl1wXaoTeh3azl77R0M8s6pptj+t6dpJsdkc5jMPPiBQqRrLfeGLYc9tkX1fux423DQ14/MN5BB9Ck7BpbL1+qU6g8wUobZ8MJwNyb9MYBxIxGKVQZ2crbxBMo9/58Fo4E1L3XOXB1MK8/nO60YumNYvlEGUlxQkBVnFQapS95Vu/e+semGo8b+seS3nZbGREJzXPK0/w6H7xIiahTIb7L3gC+o2fR/Bi/8Os9GyPs3QvhuUZYI3x1ejQFgn1NsCb4fILNwA96H3+YUaAJAB1ooDXQl2QVbh/o+RDoYAJAt3m6JloT/ddEH/7N/VeibU20JvqStNm0+p/f3klNIeuwxy+3NdIa6bNflE8i0RhfMmiGNcOnGbaHqcYUM43x5c+K5Hl1D+tYL7y8m8wbEBGi2Vw2rJV/u603N8+Oe6NAmEEwkB55Y+l92zUteyz94clzgfZQ7a6S67behTx6/AU=</diagram><diagram id="SK1VvSCf6-f5suE94Ksw" name="AuthActivity">5ZfRbpswFIafhstIAQNtL1OarlI1qUq6RdrNZLADnowPs00ge/qZYCA0ldZOSiqVK+z/2Mec/zuWwEFRXn+RuMi+AqHc8eakdtCd43luEMzNo1H2rXJ9E7RCKhmxiwZhzf5QK9p9ackIVaOFGoBrVozFBISgiR5pWEqoxsu2wMenFjilJ8I6wfxU3TCiM1uFdzXoD5SlWXeyG960kRx3i20lKsMEqiMJLR0USQDdjvI6orwxr/Pl8ennZvUQzVZ3uwXDz8pfPaNZm+z+PVv6EiQV+r9Tb/ax+q59lCz5D/5rN4sf0z71DvPS+mVr1fvOQAmlILRJMnfQbZUxTdcFTppoZVrGaJnOuZm5ZrhlnEfAQZq5AEEbCYS2beEFZo45S4WZcLo1xdzaF6BS0/oFsX+U6/YMTPNSyKmWe7PP9qlvqVXH0K2WHQFHXaNi22hpn2ow0wysn+/w1jvxdlHqzNTEEqwZiKk5HZ7LaPRKE4dcW0dGHoe/S+gCM3XwamEWuH5RD0EzSu3zkCXuhAUhkip12NOGzPvGL5cbrT23kz8HZnf+Rs7+uTj7l+L8BFJPFPJbL/PZIAcXgyxBQwK83aQob74+Jkj8+qOJh5ci/k1RKXBOp3m1++/YDwN9dbGrjZWqQJIWNM4bJiJWxRjyZMCH5wNvpsMP0CF29BuJln8B</diagram></mxfile>

View File

@@ -0,0 +1,208 @@
//! ## AuthActivity
//!
//! `auth_activity` is the module which implements the authentication activity
/*
*
* Copyright (C) 2020 Christian Visintin - christian.visintin1997@gmail.com
*
* This file is part of "TermSCP"
*
* TermSCP is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* TermSCP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with TermSCP. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Dependencies
extern crate crossterm;
extern crate tui;
// locals
use super::{Activity, Context};
// Includes
use crossterm::event::Event as InputEvent;
use crossterm::event::{KeyCode, KeyEvent};
use tui::layout;
use tui::style;
use tui::widgets;
/// ### InputField
///
/// InputField describes the current input field to edit
#[derive(std::cmp::PartialEq)]
enum InputField {
Address,
Port,
Protocol,
Username,
Password,
}
/// ### ScpProtocol
///
/// ScpProtocol describes the communication protocol selected by the user to communicate with the remote
pub enum ScpProtocol {
Sftp,
Ftp,
}
/// ### AuthActivity
///
/// AuthActivity is the data holder for the authentication activity
pub struct AuthActivity {
pub address: String,
pub port: String,
pub protocol: ScpProtocol,
pub username: String,
pub password: String,
pub form_submit: bool, // becomes true after user has submitted fields
pub esc_called: bool, // Becomes true if user has pressed esc
selected_field: InputField,
}
impl AuthActivity {
/// ### new
///
/// Instantiates a new AuthActivity
pub fn new() -> AuthActivity {
AuthActivity {
address: String::new(),
port: String::from("22"),
protocol: ScpProtocol::Sftp,
username: String::new(),
password: String::new(),
form_submit: false,
esc_called: false,
selected_field: InputField::Address,
}
}
}
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
fn on_create(&mut self, context: &mut Context) {
// Mhm, nothing to do here I guess...
}
/// ### 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: &mut Context) {
// Start catching Input Events
let mut popup: Option<String> = None;
if let Ok(input_events) = context.input_hnd.fetch_events() {
// Iterate over input events
for event in input_events.iter() {
match event {
InputEvent::Key(key) => {
match key.code {
KeyCode::Esc => {
self.esc_called = true;
break
},
KeyCode::Enter => {
// TODO: handle submit (check form)
},
KeyCode::Backspace => {
// Pop last char
match self.selected_field {
InputField::Address => {
let _ = self.address.pop();
},
InputField::Password => {
let _ = self.password.pop();
},
InputField::Username => {
let _ = self.username.pop();
},
InputField::Port => {
let _ = self.port.pop();
},
_ => { /* Nothing to do */ }
};
},
KeyCode::Up => {
// Move item up
self.selected_field = match self.selected_field {
InputField::Address => InputField::Address, // End of list
InputField::Port => InputField::Address,
InputField::Protocol => InputField::Port,
InputField::Username => InputField::Protocol,
InputField::Password => InputField::Username,
}
},
KeyCode::Down => {
// Move item down
self.selected_field = match self.selected_field {
InputField::Address => InputField::Port,
InputField::Port => InputField::Protocol,
InputField::Protocol => InputField::Username,
InputField::Username => InputField::Password,
InputField::Password => InputField::Password, // End of list
}
},
KeyCode::Char(ch) => {
match self.selected_field {
InputField::Address => self.address.push(ch),
InputField::Password => self.password.push(ch),
InputField::Username => self.username.push(ch),
InputField::Port => {
// Value must be numeric
if ch.is_numeric() {
self.port.push(ch);
}
},
_ => { /* Nothing to do */ }
}
},
KeyCode::Left => {
// If current field is Protocol handle event... (move element left)
if self.selected_field == InputField::Protocol {
self.protocol = match self.protocol {
ScpProtocol::Sftp => ScpProtocol::Sftp,
ScpProtocol::Ftp => ScpProtocol::Sftp, // End of list
}
}
},
KeyCode::Right => {
// If current field is Protocol handle event... ( move element right )
if self.selected_field == InputField::Protocol {
self.protocol = match self.protocol {
ScpProtocol::Sftp => ScpProtocol::Ftp,
ScpProtocol::Ftp => ScpProtocol::Ftp, // End of list
}
}
},
_ => { /* Nothing to do */ }
}
}
_ => { /* Nothing to do */ }
}
}
}
// TODO: draw interface
}
/// ### 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.
fn on_destroy(&mut self, context: &mut Context) {
// Mhm, nothing to do here I guess...
}
}

View File

@@ -24,9 +24,11 @@
* *
*/ */
// Locals
use super::context::Context; use super::context::Context;
// Activities // Activities
pub mod auth_activity;
// Activity trait // Activity trait

View File

@@ -42,10 +42,10 @@ impl InputHandler {
InputHandler {} InputHandler {}
} }
/// ### fetch_messages /// ### fetch_events
/// ///
/// Check if new events have been received from handler /// Check if new events have been received from handler
pub(crate) fn fetch_messages(&self) -> Result<Vec<Event>, ()> { pub(crate) fn fetch_events(&self) -> Result<Vec<Event>, ()> {
let mut inbox: Vec<Event> = Vec::new(); let mut inbox: Vec<Event> = Vec::new();
loop { loop {
if let Ok(available) = poll(Duration::from_millis(10)) { if let Ok(available) = poll(Duration::from_millis(10)) {