Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_tui/src/lib_tui/input.rs

3.4 KiB, 11 runs

created by r1870400018:1193, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use oxedyne_fe2o3_core::prelude::*;
2use oxedyne_fe2o3_hash::kdf::KeyDerivationScheme;
3use oxedyne_fe2o3_iop_hash::kdf::KeyDeriver;
4
5use std::io::{
6 self,
7 Write,
8};
9
10use crossterm::{
11 cursor,
12 event::{
13 self,
14 Event,
15 KeyCode,
16 },
17 execute,
18 terminal::{
19 self,
20 ClearType,
21 },
22};
23use secrecy::{
24 ExposeSecret,
25 Secret,
26};
27
28
29pub struct UserInput;
30
31impl UserInput {
32
33 pub fn ask(prompt: &str) -> Outcome<String> {
34 print!("{}", prompt);
35 res!(std::io::stdout().flush());
36 let mut choice = String::new();
37 res!(std::io::stdin().read_line(&mut choice));
38 Ok(choice)
39 }
40
41 pub fn show_and_clear(sec: Secret<String>) -> Outcome<()> {
42 let sec = sec.expose_secret();
43 print!("{}", sec);
44 res!(std::io::stdout().flush());
45 res!(terminal::enable_raw_mode());
46 // Wait for any key press event.
47 if let Event::Key(_) = res!(event::read()) {
48 res!(terminal::disable_raw_mode());
49 res!(execute!(
50 io::stdout(),
51 cursor::MoveToColumn(0), // Move to the start of the line.
52 terminal::Clear(ClearType::CurrentLine), // Clear the current line.
53 ));
54 res!(std::io::stdout().flush());
55 }
56 Ok(())
57 }
58
59 pub fn create_pass(
60 max_attempts: usize,
61 )
62 -> Outcome<Secret<String>>
63 {
64 let mut count: usize = 0;
65 let pass = loop {
66 let pass1 = res!(Self::ask_for_secret(Some("Enter a passphrase: ")));
67 let pass2 = res!(Self::ask_for_secret(Some("Re-enter the passphrase: ")));
68 if pass1.expose_secret() != pass2.expose_secret() {
69 println!(" The passphrases do not match, try again.");
70 } else {
71 break pass1;
72 }
73 count += 1;
74 if count > max_attempts {
75 return Err(err!(
76 "Number of failed attempts to repeat passphrase exceeded limit of {}.",
77 max_attempts;
78 Input, Invalid, Excessive, String));
79 }
80 };
81 Ok(pass)
82 }
83
84 pub fn ask_for_secret(prompt_opt: Option<&str>) -> Outcome<Secret<String>> {
85
86 if let Some(prompt) = prompt_opt {
87 print!("{}", prompt);
88 } else {
89 print!("Enter app wallet passphrase: ");
90 }
91 res!(std::io::stdout().flush());
92 res!(terminal::enable_raw_mode());
93
94 let mut pass = String::new();
95 loop {
96 if let Event::Key(key_event) = res!(event::read()) {
97 match key_event.code {
98 KeyCode::Char(c) => {
99 pass.push(c);
100 }
101 KeyCode::Enter => {
102 break;
103 }
104 KeyCode::Backspace => {
105 pass.pop();
106 }
107 _ => {}
108 }
109 }
110 }
111
112 // Disable raw mode and print a newline.
113 res!(terminal::disable_raw_mode());
114 println!();
115
116 Ok(Secret::new(pass))
117 }
118
119 pub fn derive_key(
120 kdf: &mut KeyDerivationScheme,
121 pass: Secret<String>,
122 )
123 -> Outcome<Vec<u8>>
124 {
125 let pass = pass.expose_secret().as_bytes();
126 res!(kdf.derive(pass));
127 Ok(res!(kdf.get_hash()).to_vec())
128 }
129}