Skip to content

Commit c7cd7f9

Browse files
authored
Merge pull request #172 from replydev/fix/refactors
Fix/refactors
2 parents ff4dc3d + bfb62f9 commit c7cd7f9

File tree

7 files changed

+90
-71
lines changed

7 files changed

+90
-71
lines changed

src/argument_functions.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub fn import(matches: &ArgMatches, database: &mut OTPDatabase) -> Result<String
1717
} else if matches.get_flag("aegis") {
1818
importers::aegis::import(path)
1919
} else if matches.get_flag("aegis-encrypted") {
20-
let mut password = utils::prompt_for_passwords("Insert your Aegis password: ", 0, false);
20+
let mut password = utils::password("Insert your Aegis password: ", 0);
2121
let result = importers::aegis_encrypted::import(path, password.as_str());
2222
password.zeroize();
2323
result
@@ -94,7 +94,7 @@ fn get_from_args(matches: &ArgMatches) -> Result<OTPElement, String> {
9494

9595
pub fn edit(matches: &ArgMatches, database: &mut OTPDatabase) -> Result<String, String> {
9696
let mut secret = match matches.get_flag("change-secret") {
97-
true => Some(utils::prompt_for_passwords("Insert the secret: ", 0, false)),
97+
true => Some(rpassword::prompt_password("Insert the secret: ").unwrap()),
9898
false => None,
9999
};
100100

@@ -150,7 +150,7 @@ pub fn export(matches: &ArgMatches, database: &mut OTPDatabase) -> Result<String
150150
}
151151

152152
pub fn change_password(database: &mut OTPDatabase) -> Result<String, String> {
153-
let mut new_password = utils::prompt_for_passwords("New password: ", 8, true);
153+
let mut new_password = utils::verified_password("New password: ", 8);
154154
let r = match database.save_with_pw(&new_password) {
155155
Ok(()) => Ok(String::from("Password changed")),
156156
Err(e) => Err(format!("An error has occurred: {}", e)),

src/interface/app.rs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,14 @@ pub struct App {
3636
pub(crate) current_page: Page,
3737
pub(crate) search_query: String,
3838
pub(crate) focus: Focus,
39-
pub(crate) popup_text: String,
40-
pub(crate) popup_action: PopupAction,
41-
pub(crate) popup_percent_x: u16,
42-
pub(crate) popup_percent_y: u16,
39+
pub(crate) popup: Popup,
40+
}
41+
42+
pub struct Popup {
43+
pub(crate) text: String,
44+
pub(crate) action: PopupAction,
45+
pub(crate) percent_x: u16,
46+
pub(crate) percent_y: u16,
4347
}
4448

4549
impl App {
@@ -59,10 +63,12 @@ impl App {
5963
current_page: Main,
6064
search_query: String::from(""),
6165
focus: Focus::MainPage,
62-
popup_text: String::from(""),
63-
popup_action: PopupAction::EditOtp,
64-
popup_percent_x: 60,
65-
popup_percent_y: 20,
66+
popup: Popup {
67+
text: String::from(""),
68+
action: PopupAction::EditOtp,
69+
percent_x: 60,
70+
percent_y: 20,
71+
},
6672
}
6773
}
6874

@@ -178,19 +184,23 @@ impl App {
178184
self.render_table_box(frame, rects[1]);
179185
frame.render_widget(progress_bar, rects[2]);
180186
if self.focus == Focus::Popup {
181-
let block = Block::default().title("Alert").borders(Borders::ALL);
182-
let paragraph = Paragraph::new(&*self.popup_text)
183-
.block(block)
184-
.alignment(Alignment::Center)
185-
.wrap(Wrap { trim: true });
186-
let area = centered_rect(self.popup_percent_x, self.popup_percent_y, frame.size());
187-
frame.render_widget(Clear, area); //this clears out the background
188-
frame.render_widget(paragraph, area);
187+
self.render_alert(frame);
189188
}
190189
}
191190

191+
fn render_alert<B: Backend>(&mut self, frame: &mut Frame<'_, B>) {
192+
let block = Block::default().title("Alert").borders(Borders::ALL);
193+
let paragraph = Paragraph::new(&*self.popup.text)
194+
.block(block)
195+
.alignment(Alignment::Center)
196+
.wrap(Wrap { trim: true });
197+
let area = centered_rect(self.popup.percent_x, self.popup.percent_y, frame.size());
198+
frame.render_widget(Clear, area);
199+
//this clears out the background
200+
frame.render_widget(paragraph, area);
201+
}
202+
192203
fn render_table_box<B: Backend>(&mut self, frame: &mut Frame<'_, B>, area: Rect) {
193-
// TODO If terminal is too little do not show info box
194204
let constraints = if self.is_large_application(frame) {
195205
vec![Constraint::Percentage(80), Constraint::Percentage(20)]
196206
} else {

src/interface/handler.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::interface::enums::Page::*;
55
use crate::otp::otp_type::OTPType;
66
use crate::utils::{copy_string_to_clipboard, CopyType};
77

8+
use super::app::Popup;
89
use super::enums::Page;
910
use super::enums::{Focus, PopupAction};
1011

@@ -19,12 +20,12 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
1920
}
2021

2122
fn popup_handler(key_event: KeyEvent, app: &mut App) {
22-
match app.popup_action {
23+
match app.popup.action {
2324
PopupAction::EditOtp => todo!(),
2425
PopupAction::DeleteOtp => match key_event.code {
2526
KeyCode::Char('y') | KeyCode::Char('Y') => {
2627
if let Err(e) = delete_selected_code(app) {
27-
app.popup_text = e;
28+
app.popup.text = e;
2829
return;
2930
}
3031
app.focus = Focus::MainPage;
@@ -108,10 +109,12 @@ fn main_handler(key_event: KeyEvent, app: &mut App) {
108109
} else if app.table.state.selected().is_some() {
109110
// Ask the user if he wants to delete the OTP Code
110111
show_popup(
111-
String::from("Do you want to delete the selected OTP Code? [Y/N]"),
112-
60,
113-
20,
114-
PopupAction::DeleteOtp,
112+
Popup {
113+
text: String::from("Do you want to delete the selected OTP Code? [Y/N]"),
114+
percent_x: 60,
115+
percent_y: 20,
116+
action: PopupAction::DeleteOtp,
117+
},
115118
app,
116119
)
117120
}
@@ -161,7 +164,15 @@ fn main_handler(key_event: KeyEvent, app: &mut App) {
161164
q, CTRL-D, Esc -> Exit the application
162165
",
163166
);
164-
show_popup(info_text, 40, 50, PopupAction::GeneralInfo, app);
167+
show_popup(
168+
Popup {
169+
text: info_text,
170+
percent_x: 40,
171+
percent_y: 50,
172+
action: PopupAction::GeneralInfo,
173+
},
174+
app,
175+
);
165176
}
166177

167178
KeyCode::Char('f') | KeyCode::Char('F') => {
@@ -304,21 +315,20 @@ fn search_and_select(app: &mut App) {
304315
// TODO Handle if no search results
305316
}
306317

307-
fn show_popup(text: String, percent_x: u16, percent_y: u16, action: PopupAction, app: &mut App) {
318+
fn show_popup(popup: Popup, app: &mut App) {
308319
app.focus = Focus::Popup;
309-
app.popup_percent_x = percent_x;
310-
app.popup_percent_y = percent_y;
311-
app.popup_text = text;
312-
app.popup_action = action;
320+
app.popup = popup;
313321
}
314322

315323
fn handle_exit(app: &mut App) {
316324
if app.database.is_modified() {
317325
show_popup(
318-
String::from("Do you want to save your chages? [Y/N]"),
319-
60,
320-
20,
321-
PopupAction::SaveBeforeQuit,
326+
Popup {
327+
text: String::from("Do you want to save your chages? [Y/N]"),
328+
percent_x: 60,
329+
percent_y: 20,
330+
action: PopupAction::SaveBeforeQuit,
331+
},
322332
app,
323333
)
324334
} else {

src/main.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ mod reading;
2121
mod utils;
2222

2323
fn init() -> Result<ReadResult, String> {
24-
match utils::create_db_if_needed() {
25-
Ok(needs_creation) => {
26-
if needs_creation {
27-
let mut pw = utils::prompt_for_passwords("Choose a password: ", 8, true);
24+
match utils::init_app() {
25+
Ok(first_run) => {
26+
if first_run {
27+
// Let's initialize the database file
28+
let mut pw = utils::verified_password("Choose a password: ", 8);
2829
let mut database = OTPDatabase {
2930
version: CURRENT_DATABASE_VERSION,
3031
elements: vec![],

src/otp/algorithms/hotp_maker.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ use sha2::{Sha256, Sha512};
1515
use crate::otp::otp_algorithm::OTPAlgorithm;
1616

1717
pub fn hotp(secret: &str, algorithm: OTPAlgorithm, counter: u64) -> Result<u32, String> {
18-
match algorithm.to_string().to_uppercase().as_str() {
19-
"SHA256" => generate_hotp::<Sha256>(secret, counter),
20-
"SHA512" => generate_hotp::<Sha512>(secret, counter),
18+
match algorithm {
19+
OTPAlgorithm::Sha256 => generate_hotp::<Sha256>(secret, counter),
20+
OTPAlgorithm::Sha512 => generate_hotp::<Sha512>(secret, counter),
2121
_ => generate_hotp::<Sha1>(secret, counter),
2222
}
2323
}

src/reading.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use zeroize::Zeroize;
88
pub type ReadResult = (OTPDatabase, Vec<u8>, Vec<u8>);
99

1010
pub fn get_elements() -> Result<ReadResult, String> {
11-
let mut pw = utils::prompt_for_passwords("Password: ", 8, false);
11+
let mut pw = utils::password("Password: ", 8);
1212
let (elements, key, salt) = match read_from_file(&pw) {
1313
Ok((result, key, salt)) => (result, key, salt),
1414
Err(e) => return Err(format!("Cannot decrypt existing database: {}", e)),

src/utils.rs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use copypasta_ext::x11_fork::ClipboardContext;
44
use crossterm::style::Print;
55
#[cfg(not(debug_assertions))]
66
use dirs::home_dir;
7-
use std::fs::File;
87
use std::path::PathBuf;
98
use std::time::{SystemTime, UNIX_EPOCH};
109
use std::{env, io};
@@ -46,24 +45,19 @@ pub fn get_default_db_path() -> PathBuf {
4645
.join(".cotp/db.cotp")
4746
}
4847

49-
pub fn create_db_if_needed() -> Result<bool, ()> {
48+
pub fn init_app() -> Result<bool, ()> {
5049
let db_path = get_db_path();
5150
let db_dir = db_path.parent().unwrap();
5251
if !db_dir.exists() {
53-
if let Err(_e) = std::fs::create_dir(db_dir) {
52+
if let Err(_e) = std::fs::create_dir_all(db_dir) {
5453
return Err(());
5554
}
55+
return Ok(true);
5656
}
57-
if !db_path.exists() {
58-
return match File::create(db_path) {
59-
Ok(_f) => Ok(true),
60-
Err(_e) => Err(()),
61-
};
62-
}
63-
Ok(false)
57+
Ok(!db_path.exists())
6458
}
6559

66-
pub fn delete_db() -> std::io::Result<()> {
60+
pub fn delete_db() -> io::Result<()> {
6761
std::fs::remove_file(get_db_path())
6862
}
6963

@@ -78,26 +72,30 @@ pub fn percentage() -> u16 {
7872
(millis_before_next_step() * 100 / 30000) as u16
7973
}
8074

81-
pub fn prompt_for_passwords(message: &str, minimum_password_length: usize, verify: bool) -> String {
82-
let mut password;
75+
pub fn password(message: &str, minimum_length: usize) -> String {
8376
loop {
84-
password = rpassword::prompt_password(message).unwrap();
85-
if verify {
86-
let verify_password = rpassword::prompt_password("Retype the same password: ").unwrap();
87-
if password != verify_password {
88-
println!("Passwords do not match");
89-
continue;
90-
}
77+
let password = rpassword::prompt_password(message).unwrap();
78+
if password.chars().count() < minimum_length {
79+
println!(
80+
"Please insert a password with at least {} digits.",
81+
minimum_length
82+
);
83+
continue;
9184
}
92-
if password.chars().count() >= minimum_password_length {
93-
break;
85+
return password;
86+
}
87+
}
88+
89+
pub fn verified_password(message: &str, minimum_length: usize) -> String {
90+
loop {
91+
let password = password(message, minimum_length);
92+
let verify_password = rpassword::prompt_password("Retype the same password: ").unwrap();
93+
if password != verify_password {
94+
println!("Passwords do not match");
95+
continue;
9496
}
95-
println!(
96-
"Please insert a password with at least {} digits.",
97-
minimum_password_length
98-
);
97+
return password;
9998
}
100-
password
10199
}
102100

103101
fn in_ssh_shell() -> bool {

0 commit comments

Comments
 (0)