login: Simplify whole async decrypting process
This commit is contained in:
parent
c82ba73eba
commit
84f57b4493
|
@ -17,6 +17,9 @@ fuzzy-matcher = "0.3.7"
|
||||||
serde_json = "1.0.59"
|
serde_json = "1.0.59"
|
||||||
unicase = "2.6.0"
|
unicase = "2.6.0"
|
||||||
|
|
||||||
|
[dependencies.bitwarden]
|
||||||
|
path = "bitwarden"
|
||||||
|
|
||||||
[dependencies.cursive]
|
[dependencies.cursive]
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
@ -28,6 +31,3 @@ git = "https://github.com/BonsaiDen/cursive_table_view.git"
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "1.0.117"
|
version = "1.0.117"
|
||||||
features = ["derive"]
|
features = ["derive"]
|
||||||
|
|
||||||
[dependencies.bitwarden]
|
|
||||||
path = "bitwarden"
|
|
||||||
|
|
|
@ -29,4 +29,3 @@ features = ["derive"]
|
||||||
[dependencies.uuid]
|
[dependencies.uuid]
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
features = ["v4", "serde"]
|
features = ["v4", "serde"]
|
||||||
|
|
||||||
|
|
89
src/login.rs
89
src/login.rs
|
@ -1,6 +1,5 @@
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
use std::sync::mpsc;
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use cursive::direction::Orientation;
|
use cursive::direction::Orientation;
|
||||||
|
@ -14,16 +13,6 @@ use bitwarden::{self, ApiError, AuthData};
|
||||||
|
|
||||||
use crate::vault::{self, VaultData};
|
use crate::vault::{self, VaultData};
|
||||||
|
|
||||||
enum LoginProgress {
|
|
||||||
Decrypting,
|
|
||||||
Syncing,
|
|
||||||
Finished(VaultData),
|
|
||||||
Error(Option<VaultData>, ApiError),
|
|
||||||
}
|
|
||||||
|
|
||||||
type LoginProgressSink = mpsc::Sender<LoginProgress>;
|
|
||||||
type LoginProgressRecv = mpsc::Receiver<LoginProgress>;
|
|
||||||
|
|
||||||
pub fn create(siv: &mut Cursive) {
|
pub fn create(siv: &mut Cursive) {
|
||||||
let email_edit = EditView::new().with_name("email");
|
let email_edit = EditView::new().with_name("email");
|
||||||
let email_view = OnEventView::new(email_edit).on_event(Event::CtrlChar('u'), |siv| {
|
let email_view = OnEventView::new(email_edit).on_event(Event::CtrlChar('u'), |siv| {
|
||||||
|
@ -66,89 +55,65 @@ fn on_login(siv: &mut Cursive) {
|
||||||
siv.add_layer(progress_dialog);
|
siv.add_layer(progress_dialog);
|
||||||
|
|
||||||
let vault_data = siv.take_user_data();
|
let vault_data = siv.take_user_data();
|
||||||
let (tx, rx) = mpsc::channel();
|
let sink = siv.cb_sink().clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
if let Some(data) = vault_data {
|
if let Some(data) = vault_data {
|
||||||
decrypt_cached(tx, data, &email, &password);
|
decrypt_cached(sink.clone(), progress_text, data, &email, &password);
|
||||||
} else {
|
} else {
|
||||||
sync_and_decrypt(tx, &email, &password);
|
sync_and_decrypt(sink.clone(), progress_text, &email, &password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sink.send(Box::new(|siv| {
|
||||||
|
siv.set_autorefresh(false);
|
||||||
|
})).unwrap();
|
||||||
});
|
});
|
||||||
|
|
||||||
let cb_sink = siv.cb_sink().clone();
|
|
||||||
thread::spawn(move || {
|
|
||||||
process_login(cb_sink, rx, progress_text);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrypt_cached(
|
fn decrypt_cached(
|
||||||
sink: LoginProgressSink,
|
sink: CursiveSink,
|
||||||
|
progress: TextContent,
|
||||||
mut vault: VaultData,
|
mut vault: VaultData,
|
||||||
email: &str,
|
email: &str,
|
||||||
master_password: &str
|
master_password: &str
|
||||||
) {
|
) {
|
||||||
sink.send(LoginProgress::Decrypting).unwrap();
|
progress.set_content("decrypting ...");
|
||||||
vault.auth.cipher = CipherSuite::from(&email, master_password, vault.auth.kdf_iterations);
|
vault.auth.cipher = CipherSuite::from(&email, master_password, vault.auth.kdf_iterations);
|
||||||
|
|
||||||
if vault.auth.cipher.set_decrypt_key(&vault.sync.profile.key).is_err() {
|
if vault.auth.cipher.set_decrypt_key(&vault.sync.profile.key).is_err() {
|
||||||
sink.send(
|
handle_login_error(sink, Some(vault), ApiError::LoginFailed);
|
||||||
LoginProgress::Error(Some(vault), ApiError::LoginFailed)
|
|
||||||
).unwrap();
|
|
||||||
} else {
|
} else {
|
||||||
vault::decrypt(&mut vault);
|
vault::decrypt(&mut vault);
|
||||||
sink.send(LoginProgress::Finished(vault)).unwrap();
|
|
||||||
|
sink.send(Box::new(|siv| {
|
||||||
|
siv.set_user_data(vault);
|
||||||
|
vault::create(siv);
|
||||||
|
})).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sync_and_decrypt(sink: LoginProgressSink, email: &str, master_password: &str) {
|
fn sync_and_decrypt(sink: CursiveSink, progress: TextContent, email: &str, master_password: &str) {
|
||||||
match bitwarden::authenticate(&email, &master_password) {
|
match bitwarden::authenticate(&email, &master_password) {
|
||||||
Ok(auth) => {
|
Ok(auth) => {
|
||||||
sink.send(LoginProgress::Syncing).unwrap();
|
progress.set_content("syncing ...");
|
||||||
let vault = sync_vault_data(auth).unwrap();
|
let vault = sync_vault_data(auth).unwrap();
|
||||||
|
|
||||||
decrypt_cached(sink, vault, email, master_password);
|
decrypt_cached(sink, progress, vault, email, master_password);
|
||||||
},
|
},
|
||||||
Err(err) => sink.send(LoginProgress::Error(None, err)).unwrap(),
|
Err(err) => handle_login_error(sink, None, err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_login(sink: CursiveSink, recv: LoginProgressRecv, progress_text: TextContent) {
|
fn handle_login_error(sink: CursiveSink, vault: Option<VaultData>, error: ApiError) {
|
||||||
for progress in recv.iter() {
|
sink.send(Box::new(move |siv| {
|
||||||
match progress {
|
siv.pop_layer();
|
||||||
LoginProgress::Decrypting => {
|
siv.find_name::<EditView>("master_password").unwrap().set_content("")(siv);
|
||||||
progress_text.set_content("decrypting ...");
|
|
||||||
},
|
|
||||||
|
|
||||||
LoginProgress::Syncing => {
|
if let Some(vault) = vault {
|
||||||
progress_text.set_content("syncing ...");
|
siv.set_user_data(vault);
|
||||||
},
|
|
||||||
|
|
||||||
LoginProgress::Finished(vault) => {
|
|
||||||
sink.send(Box::new(|siv| {
|
|
||||||
siv.set_user_data(vault);
|
|
||||||
vault::create(siv);
|
|
||||||
})).unwrap();
|
|
||||||
break;
|
|
||||||
},
|
|
||||||
|
|
||||||
LoginProgress::Error(vault, err) => {
|
|
||||||
sink.send(Box::new(move |siv| {
|
|
||||||
siv.pop_layer();
|
|
||||||
siv.find_name::<EditView>("master_password").unwrap().set_content("")(siv);
|
|
||||||
|
|
||||||
if let Some(vault) = vault {
|
|
||||||
siv.set_user_data(vault);
|
|
||||||
}
|
|
||||||
|
|
||||||
siv.add_layer(Dialog::info(err.to_string()));
|
|
||||||
})).unwrap();
|
|
||||||
break;
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sink.send(Box::new(|siv| {
|
siv.add_layer(Dialog::info(error.to_string()));
|
||||||
siv.set_autorefresh(false);
|
|
||||||
})).unwrap();
|
})).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue